Zum Hauptinhalt springen
Version: 1.67.x (Q1 26)

Installationsanleitung

Diese Anleitung enthält umfassende Anweisungen zur Installation von Codesphere Private Cloud. Codesphere wird hauptsächlich als Helm-Chart bereitgestellt und stützt sich auf zwei zentrale externe Komponenten: PostgreSQL für die Datenbank und Ceph für hochverfügbaren verteilten Speicher. Obwohl diese Teil des Helm-Deployments sein könnten, werden sie zur Erhöhung von Stabilität und Robustheit als externe Komponenten behandelt.

Dieses Dokument beschreibt zwei unterschiedliche Installationsmethoden:

  1. Multi-Node-Installer: Diese Methode nutzt ein Skript, das sich per SSH von einer zentralen Setup-Maschine aus mit verschiedenen Hosts verbindet und die Komponenten nacheinander installiert. Sie ist dafür ausgelegt, ein komplettes Codesphere-Rechenzentrum von Grund auf (Bare Metal, VMs) bereitzustellen oder mit einigen bereits vorhandenen Komponenten zu integrieren.
  2. Single-Node-Installer: Dieses Skript installiert jeweils eine bestimmte Komponente auf einem festgelegten Host. Die zu installierende Komponente muss im Befehl explizit angegeben werden.

Beide Installationsmethoden basieren auf einer globalen Konfigurationsdatei config.yaml und erfordern SSH-Zugriff auf alle Ziel-Hosts von der Maschine aus, auf der die Installationsskripte ausgeführt werden.


Die Installer verstehen

Warum diese Installer?

Der Kern von Codesphere wird mittels eines Helm-Charts bereitgestellt. Für kritische Infrastrukturkomponenten wie PostgreSQL und Ceph (für verteilten, hochverfügbaren Speicher) empfehlen wir jedoch, diese als robuste, externe Dienste einzurichten, statt sie in das Helm-Chart einzubetten. Dieser Ansatz sorgt für eine stabilere und belastbarere Umgebung.

Diese Installer sind modulare Werkzeuge und ermöglichen es, entweder:

  • ein komplettes Codesphere-Rechenzentrum auf neuer Hardware (Bare Metal oder VMs) bereitzustellen, oder
  • bestimmte, bereits vorhandene Komponenten zu nutzen und zu integrieren, sofern verfügbar.

Zentrale Installer-Komponenten

Der Installationsprozess umfasst mehrere zentrale Komponenten:

KomponentennameBeschreibung
SecretsVerwaltet sensible Daten mittels Age- und Sops-Schlüsseldateien.
DockerContainer-Runtime für die Bereitstellung der Codesphere-Dienste.
PostgreSQLDie primäre Datenbank für Codesphere.
CephVerteilte Speicherlösung für Hochverfügbarkeit.
KubernetesContainer-Orchestrierungsplattform.
SetUpClusterGrundlegende Kubernetes-Ressourcen für Codesphere.
Monitoring(implizit) Komponenten zur Überwachung des Clusters.
CodesphereDas Haupt-Deployment der Codesphere-Anwendung.

Globale Voraussetzungen & Einrichtung

Diese Voraussetzungen gelten sowohl für die Multi-Node- als auch für die Single-Node-Installationsmethode.

Unterstütztes Betriebssystem

  • Ubuntu 22.04 LTS (Server Edition) ist das empfohlene und unterstützte Betriebssystem für alle Nodes.

Hardwareanforderungen

  • PostgreSQL-Nodes (falls Installation gemäß dieser Anleitung – 2 Server für HA empfohlen):

    • Mindestens 2 CPU-Kerne pro Server
    • Mindestens 4 GB RAM pro Server
    • Mindestens 200 GB unter / (inklusive /etc/codesphere)
  • Ceph-Nodes (mindestens 3 Server für HA empfohlen):

    • Mindestens 2 CPU-Kerne pro Server
    • Mindestens 8 GB RAM pro Server
    • 1 Festplatte mit mindestens 200 GB für Ceph-Metadaten (BlueStore DB/WAL). Dieser Speicher sollte schnell sein (z. B. SSD/NVMe) und mindestens 4 % der gesamten Blockspeicherkapazität ausmachen. Muss vollständig leer sein (kein Dateisystem).
    • 1 oder mehr Festplatten mit jeweils mindestens 300 GB für Ceph-Blockspeicher (OSDs). Müssen vollständig leer sein (kein Dateisystem).
    • 1 Root-Festplatte mit mindestens 200 GB für das Betriebssystem.
  • Kubernetes-Nodes:

    • Mindestens 1 Control-Plane-Node.
    • Mindestens 2 Worker-Nodes.
    • Jeder Kubernetes-Server:
      • Mindestens 200 GB unter / (inklusive /etc/codesphere)
      • Zusätzlich 200 GB unter /var/lib/docker (oder /var/lib/k0s, falls k0s containerd direkt verwaltet; siehe k0s-Speicherdokumentation).
    • Mindestens 8 CPU-Threads auf jedem Node (wie von Kubernetes erkannt).
    • Mindestens 16 GB Gesamtspeicher über alle Worker-Nodes zusammen.
    • Mindestens 8 GB Speicher pro Control-Plane-Node.

Erforderliche Softwarepakete

Stelle sicher, dass folgende Software installiert ist:

  • Auf der Installer-Maschine (nur Multi-Node, bzw. deine Verwaltungsmaschine für Single-Node):

    • OpenSSH-Client
    • scp (Secure Copy Protocol-Client)
    • Node.js Version 22 (ein node-Binary wird auch mit dem Installer geliefert)
  • Auf allen Ziel-Nodes (Ceph, Kubernetes, PostgreSQL):

    • iptables
    • Ein Texteditor wie vi oder nano
    • curl

SSH-Zugriff

  • Die Maschine, auf der die Installationsskripte ausgeführt werden, muss SSH-Zugriff auf alle Ziel-Maschinen haben (PostgreSQL-, Ceph-, Kubernetes-Nodes).
  • Die SSH-Konfiguration muss SSH-Sitzungen von bis zu 3 Stunden erlauben, z. B. durch Setzen eines geeigneten ServerAliveInterval (siehe unten).
  • Der Installer erwartet, dass ein einfaches ssh <IP-ADRESSE> funktioniert, d. h. es darf kein Passwort erforderlich sein und kein Benutzer angegeben werden müssen.
  • Um ein passwortloses Login zu ermöglichen, konfiguriere ein Schlüsselpaar für die SSH-Nutzung (ersetze id_ed25519_csinstall durch den gewünschten Schlüsselnamen):
    ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_csinstall -C "some identifier"
    # Verwende ssh-copy-id oder kopiere den öffentlichen Schlüssel (*.pub) auf /root/.ssh/authorized_keys auf allen VMs
    ssh-copy-id -i ~/.ssh/id_ed25519_csinstall root@host
  • Der Benutzer auf den Remote-Maschinen MUSS derzeit root sein.
  • Den SSH-Zugriff für verschiedene Hosts kann über deine SSH-Konfigurationsdatei (z. B. ~/.ssh/config) konfiguriert werden. Beispiel:
    Host 10.10.123.1
    HostName 10.10.123.1
    User root
    IdentityFile ~/.ssh/id_ed25519_csinstall
    # Optional
    ServerAliveInterval 30


    # Für alle weiteren Maschinen wiederholen

    Weitere Details findest du in der ssh_config-Man-Page.
  • SSH-Konnektivität testen: Prüfe vor Beginn der Installation, ob eine SSH-Verbindung zu jedem Node möglich ist, indem du einfach ssh <IP-ADRESSE> ausführst, ohne Benutzer, Port oder Schlüsseldatei anzugeben. Bei der ersten Verbindung erscheint möglicherweise:
    Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
    Warning: Permanently added 'hostname,ip_address' (ED25519) to the list of known hosts.
    Bestätige yes für jeden neuen Host.

Abhängigkeiten herunterladen

  1. Beziehe das Codesphere-Installer-Archiv (installer.tar.gz) von Codesphere. Dies kann über eine direkte Download-URL oder ein physisches Speichermedium erfolgen.
  2. Für Multi-Node: Lege das Archiv auf dem Server ab, von dem aus die Installation durchgeführt wird.
  3. Für Single-Node: Dieses Archiv muss auf jedem an der Installation beteiligten Host hochgeladen und extrahiert werden.
  4. Extrahiere das Installer-Archiv in ein Verzeichnis (z. B. /etc/codesphere). Du kannst auch das Abhängigkeiten-Archiv deps.tar.gz extrahieren, das später nützlich sein kann.
    mkdir /etc/codesphere
    tar -xvzf ./installer.tar.gz -C /etc/codesphere
    mkdir /etc/codesphere/deps
    tar -xvzf ./etc/codesphere/deps.tar.gz -C /etc/codesphere/deps

inotify-Watcher-Limits konfigurieren

Erhöhe auf allen Kubernetes-Nodes die inotify-Limits, um Probleme mit der Dateiüberwachung zu vermeiden. Erstelle oder bearbeite /etc/sysctl.d/11-inotify.conf mit folgendem Inhalt:

fs.inotify.max_queued_events=16384
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=524288

Wende die Änderungen an:

sudo sysctl -p /etc/sysctl.d/11-inotify.conf

Hinweis: Größere Server benötigen möglicherweise proportional höhere Limits.

Konfigurationsdateien und Secrets-Verwaltung

Beide Installationsmethoden basieren auf zwei Hauptdateien:

  • config.yaml: Enthält die Hauptkonfiguration für deine Codesphere-Umgebung.
  • prod.vault.yaml: Speichert sensible Informationen, verschlüsselt mit SOPS und Age.

Zertifikate und Schlüssel generieren

Allgemeiner Hinweis: Füge keine Passphrasen zu neu erstellten Schlüsseln hinzu.

Ceph-SSH-Schlüssel

Dieser Schlüssel ermöglicht es cephadm, Ceph-Nodes zu bootstrappen und zu verwalten. Generiere ihn auf deiner Setup-Maschine:

# Dies erstellt ceph_id_rsa (privater Schlüssel) und ceph_id_rsa.pub (öffentlicher Schlüssel)
ssh-keygen -t rsa -b 4096 -C "ceph" -f ./ceph_id_rsa

Cluster Ingress CA

Codesphere unterstützt mehrere Optionen zur Ausstellung und Verwaltung der Cluster Ingress CA, die Zertifikate für den gesamten Ingress-Verkehr innerhalb des Clusters signiert. Die Maschinen der Benutzer, die auf Codesphere zugreifen, müssen dieser CA vertrauen. Möglich sind:

  • Eine neue selbstsignierte CA generieren (Standard, einfach für den Schnellstart)
  • Die vorhandene CA oder Zwischen-CA deiner Organisation verwenden (empfohlen für den Produktivbetrieb)
  • Integration mit einer externen Zertifizierungsstelle (z. B. HashiCorp Vault, AWS PCA, Let's Encrypt) für automatisiertes Zertifikatsmanagement

Eine Zusammenfassung findest du in der folgenden Tabelle:

OptionBeschreibung
Selbstsigniert (Standard)Generiert eine neue selbstsignierte CA lokal.
Organisations-CANutzt die vorhandene CA oder Zwischen-CA deiner Organisation zum Signieren von Ingress-Zertifikaten.
Externer AusstellerIntegration mit einer externen Zertifizierungsstelle (z. B. Vault, AWS PCA, Let's Encrypt).

Konfigurationsdetails und Beispiele findest du unter Optionen für die Cluster Ingress CA.

(Optional): Eine neue CA generieren Ersetze MyOrg, DE, KA durch die Angaben deiner Organisation.

# CA-Schlüssel generieren
openssl genrsa -out ca.key 2048
openssl rsa -in ca.key -outform PEM -pubout -out ca-pub.pem

# CA-Zertifikat generieren
openssl req -x509 -new -nodes -key ca.key -sha256 -days 1068 \
-outform PEM -out ca.pem \
-subj '/CN=MyOrg Root CA/C=DE/L=KA/O=MyOrg'

Einen neuen Serverschlüssel für Ingress mit deiner CA signieren Ersetze <hostname> durch den primären Hostnamen für deinen Codesphere-Zugriff und MyOrg durch den Namen deiner Organisation.

# Certificate Signing Request (CSR) und neuen Schlüssel für Ingress erstellen
openssl req -new -nodes -out ingress.csr -newkey rsa:4096 -keyout ingress.key \
-subj '/CN=<hostname>/O=MyOrg'

# CSR mit deiner vorhandenen CA signieren
openssl x509 -req -in ingress.csr -CA existing_ca.pem -CAkey existing_ca.key -CAcreateserial \
-outform PEM -out ingress.pem \
-days 730 -sha256

(Wenn du im vorherigen Schritt eine neue CA generiert hast, ist existing_ca.pem gleich ca.pem und existing_ca.key gleich ca.key)

PostgreSQL-Zertifikate (falls PostgreSQL installiert wird)

Falls du PostgreSQL mit den bereitgestellten Skripten installieren möchtest, musst du dafür Zertifikate generieren. Dabei kommt ebenfalls eine CA zum Einsatz. Du kannst dieselbe CA verwenden, die für Ingress generiert wurde, oder eine dedizierte.

CA generieren (falls für Ingress noch nicht erfolgt): Folge den Schritten zur "Generierung einer neuen CA" in Abschnitt 3.1.2, falls du eine separate CA für PostgreSQL benötigst. Wir nehmen an, dass pg_ca.key und pg_ca.pem verwendet werden.

Primäres PostgreSQL-Server-Zertifikat generieren: Ersetze <primary_pg_hostname> und <primary_pg_ip_address>. Wenn dein PostgreSQL-Server nicht über einen Hostnamen erreichbar ist, kannst du für das CN-Feld auch jeden anderen beschreibenden Namen verwenden.

# CSR für den Primary erstellen
openssl req -new -nodes -out pg_primary.csr -newkey rsa:4096 -keyout pg_primary.key \
-subj '/CN=<primary_pg_hostname>/O=MyOrg'

# Extensions-Datei erstellen (primary.v3.ext)
cat > pg_primary.v3.ext << EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
IP.1 = <primary_pg_ip_address> # z. B. 10.50.0.1
EOF

# Primary-Zertifikat signieren
openssl x509 -req -in pg_primary.csr -CA pg_ca.pem -CAkey pg_ca.key -CAcreateserial \
-outform PEM -out pg_primary.pem \
-days 730 -sha256 -extfile pg_primary.v3.ext

Replica-PostgreSQL-Server-Zertifikat generieren: Ersetze <replica_pg_hostname> und <replica_pg_ip_address>.

# CSR für die Replica erstellen
openssl req -new -nodes -out pg_replica.csr -newkey rsa:4096 -keyout pg_replica.key \
-subj '/CN=<replica_pg_hostname>/O=MyOrg'

# Extensions-Datei erstellen (replica.v3.ext)
cat > pg_replica.v3.ext << EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
IP.1 = <replica_pg_ip_address> # z. B. 10.50.0.2
EOF

# Replica-Zertifikat signieren
openssl x509 -req -in pg_replica.csr -CA pg_ca.pem -CAkey pg_ca.key -CAcreateserial \
-outform PEM -out pg_replica.pem \
-days 730 -sha256 -extfile pg_replica.v3.ext

Starke Passwörter für PostgreSQL-Benutzer generieren

Codesphere verwendet mehrere unterschiedliche PostgreSQL-Benutzer für den Zugriff auf die Datenbank. Die Benutzer werden vom Installer automatisch in der DB angelegt, allerdings müssen die Passwörter für jeden Benutzer in der Secrets-Datei angegeben werden. Die Passwörter werden mit den Codesphere-Diensten geteilt, es gibt in der Regel keine direkte Interaktion mit ihnen. Verwende eine beliebige Methode, um starke Passwörter zu generieren, z. B.

openssl rand -base64 16

Domain-Auth-Schlüssel generieren

Codesphere verfügt über eine Domain-Validierung zur Überprüfung neuer benutzerdefinierter Domains. Dazu werden Secrets aus einem privaten/öffentlichen Schlüsselpaar erzeugt. Diese müssen in der prod.vault.yaml angegeben werden. Verwende zur Generierung folgende Befehle:

openssl ecparam -name prime256v1 -genkey -noout -out domain_auth_key.pem
openssl ec -in domain_auth_key.pem -pubout -out domain_auth_public.pem

Secrets-Datei erstellen (prod.vault.yaml)

In dieser Datei werden alle deine Secrets gespeichert. Erstelle sie unter einem Pfad wie /home/<myuser>/secrets/prod.vault.yaml. <myuser> kann ein dedizierter Benutzer oder root sein.

warnung

Bitte entferne alle Kommentare aus der prod.vault.yaml, bevor du sie verschlüsselst (siehe Abschnitt 3.4).

warnung

Die -----BEGIN PRIVATE KEY------Ausschnitte sind lediglich Platzhalter. Ersetze sie durch den Inhalt/das Format deiner generierten Dateien. Siehe OpenSSH- vs. OpenSSL-Format für weiteren Hintergrund.

# /home/<myuser>/secrets/prod.vault.yaml
secrets:
# --- Allgemeine Secrets ---
- name: cephSshPrivateKey
file:
# Inhalt von 'ceph_id_rsa', generiert in Abschnitt 3.1.1
name: id_rsa
content: |
-----BEGIN OPENSSH PRIVATE KEY----- # Oder passender Typ für deinen Schlüssel
...
-----BEGIN OPENSSH PRIVATE KEY-----
- name: selfSignedCaKeyPem # Oder deine vorhandene CA-Schlüsseldatei, falls für Ingress verwendet
file:
name: key.pem
# Inhalt von 'ca.key' (oder deinem vorhandenen CA-Schlüssel) aus Abschnitt 3.1.2
content: |
-----BEGIN PRIVATE KEY----- # Oder passender Typ für deinen Schlüssel
...
-----END PRIVATE KEY-----
- name: domainAuthPrivateKey
file:
name: key.pem
# Inhalt von 'domain_auth_key.pem' aus Abschnitt 3.1.4
content: |
-----BEGIN EC PRIVATE KEY-----
...
-----END EC PRIVATE KEY-----
- name: domainAuthPublicKey
file:
name: key.pem
# Inhalt von 'domain_auth_public.pem' aus Abschnitt 3.1.4
content: |
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----

# (Optional) Wenn dein Managed-Service-Backend so eingerichtet wurde, dass es
# Anfragen mittels eines API_KEY authentifiziert, muss dieser API_KEY hier gesetzt werden
#- name: managedServiceSecrets
# fields:
# # JSON-Array von Objekten
# password: |-
# [
# {
# "name": "postgres", # Anbietername
# "version": "v1" # Anbieterversion
# "api": {
# "secret": "MY-API-KEY-123123"
# }
# }
# ]

# --- Anmeldedaten für externe Registry (falls verwendet) ---
# Optional bei Nutzung einer von Codesphere verwalteten K8s, erforderlich bei externer K8s
- name: registryUsername
fields:
password: 'YOUR_REGISTRY_USERNAME'
- name: registryPassword
fields:
password: 'YOUR_REGISTRY_PASSWORD'

# --- Optional: Falls PostgreSQL installiert wird ---
- name: postgresPassword
fields:
# Generiere ein starkes primäres Admin-Passwort (z. B. 25 Zeichen)
password: 'YOUR_POSTGRES_ADMIN_PASSWORD'
- name: postgresReplicaPassword
fields:
# Generiere ein starkes Replica-Passwort
password: 'YOUR_POSTGRES_REPLICA_PASSWORD'
- name: postgresPrimaryServerKeyPem
file:
name: primary.key # Interner Name, muss nicht mit dem Dateinamen übereinstimmen
# Inhalt von 'pg_primary.key' aus Abschnitt 3.1.3
content: |
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
- name: postgresReplicaServerKeyPem
file:
name: replica.key # Interner Name
# Inhalt von 'replica.key' aus Abschnitt 3.1.3
content: |
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----

# --- Optional: Bei Nutzung externer Kubernetes (siehe config.yaml) ---
- name: kubeConfig
file:
name: kubeConfig # Interner Name
content: |
apiVersion: v1
kind: Config
clusters:
- cluster:
certificate-authority-data: ...
server: https://<your-k8s-api-server>
name: external-cluster
contexts:
- context:
cluster: external-cluster
user: external-admin
name: external-context
current-context: external-context
users:
- name: external-admin
user:
client-certificate-data: ...
client-key-data: ...
# ... (Rest deiner Admin-Kubeconfig)
# Postgres-Codesphere-Benutzer & Passwörter
# Benutzernamen unverändert lassen, inklusive *_blue
- name: postgresUserAuth
fields:
password: auth_blue
- name: postgresUserDeployment
fields:
password: deployment_blue
- name: postgresUserIde
fields:
password: ide_blue
- name: postgresUserMarketplace
fields:
password: marketplace_blue
- name: postgresUserPayment
fields:
password: payment_blue
- name: postgresUserPublicApi
fields:
password: public_api_blue
- name: postgresUserTeam
fields:
password: team_blue
- name: postgresUserWorkspace
fields:
password: workspace_blue
- name: postgresPasswordAuth
fields:
password:
- name: postgresPasswordDeployment
fields:
password:
- name: postgresPasswordIde
fields:
password:
- name: postgresPasswordMarketplace
fields:
password:
- name: postgresPasswordPayment
fields:
password:
- name: postgresPasswordPublicApi
fields:
password:
- name: postgresPasswordTeam
fields:
password:
- name: postgresPasswordWorkspace
fields:
password:

# --- Optional: OAuth-Anmeldedaten für Git-Provider (in config.yaml aktivieren) ---
# GitHub
- name: githubAppsClientId
fields:
password: 'YOUR_GITHUB_APP_CLIENT_ID'
- name: githubAppsClientSecret
fields:
password: 'YOUR_GITHUB_APP_CLIENT_SECRET'
# GitLab
- name: gitlabAppClientId
fields:
password: 'YOUR_GITLAB_APP_CLIENT_ID'
- name: gitlabAppClientSecret
fields:
password: 'YOUR_GITLAB_APP_CLIENT_SECRET'
# Bitbucket
- name: bitbucketAppsClientId
fields:
password: 'YOUR_BITBUCKET_APP_CLIENT_ID'
- name: bitbucketAppsClientSecret
fields:
password: 'YOUR_BITBUCKET_APP_CLIENT_SECRET'
# Azure DevOps
- name: azureDevOpsAppClientId
fields:
password: 'YOUR_AZUREDEVOPS_APP_CLIENT_ID'
- name: azureDevOpsAppClientSecret
fields:
password: 'YOUR_AZUREDEVOPS_APP_CLIENT_SECRET'

Fülle die ...-Platzhalter mit deinem tatsächlichen Schlüssel-/Zertifikatsinhalt aus und vergib starke Passwörter.

Konfigurationsdatei erstellen (config.yaml)

Diese Datei definiert die Struktur und die Einstellungen deiner Codesphere-Installation. Erstelle sie unter einem Pfad wie /home/<myuser>/secrets/config.yaml.

# /home/<myuser>/secrets/config.yaml
dataCenter:
id: 1
name: main
city: Karlsruhe # Stadt deines Rechenzentrums
countryCode: DE # Ländercode deines Rechenzentrums
secrets:
baseDir: /home/<myuser>/secrets/ # Pfad zu deinem Secrets-Verzeichnis (wo prod.vault.yaml liegt)

# Falls eine externe Container-Registry verwendet wird
# Optional bei Nutzung einer von Codesphere verwalteten K8s, erforderlich bei externer K8s
registry:
server: "my-registry.example.com"
replaceImagesInBom: true # Optional, sollte auf true gesetzt werden, wenn eine externe Registry verwendet wird
loadContainerImages: true # Optional, auf true setzen, falls Images aus dem Installer-Bundle geladen werden sollen


# --- PostgreSQL-Konfiguration ---
# Wähle eine Option: "Neue PostgreSQL-Installation" ODER "Externe PostgreSQL verwenden"
postgres:
# Option 1: Neue PostgreSQL-Installation (siehe Secrets-Datei für Passwörter & Schlüssel)
# CA-Zertifikat für PostgreSQL (pg_ca.pem aus Abschnitt 3.1.3)
caCertPem: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
primary:
sslConfig:
# Zertifikat des primären PostgreSQL-Servers (pg_primary.pem aus Abschnitt 3.1.3)
serverCertPem: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
ip: 10.50.0.2 # Reale IP des primären PostgreSQL-Servers
hostname: pg-primary-node # Hostname des primären PostgreSQL-Nodes
replica:
ip: 10.50.0.3 # Reale IP des Replica-PostgreSQL-Servers
name: replica1 # kann beliebig sein, PostgreSQL erlaubt jedoch nur [a-z0-9_]
sslConfig:
# Zertifikat des Replica-PostgreSQL-Servers (pg_replica.pem aus Abschnitt 3.1.3)
serverCertPem: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
# Ende von Option 1

# Option 2: Externe PostgreSQL verwenden
# caCertPem: | # CA-Zertifikat deines externen PostgreSQL-Servers (falls SSL verwendet wird)
# -----BEGIN CERTIFICATE-----
# ...
# -----END CERTIFICATE-----
# serverAddress: "your-external-postgres-host:5432"
# # Stelle sicher, dass 'postgresPassword' in der prod.vault.yaml für den externen DB-Benutzer gesetzt ist
# Ende von Option 2

# --- Ceph-Konfiguration ---
ceph:
csiKubeletDir: /var/lib/k0s/kubelet # Optional, setzen, falls nicht k0s verwendet wird
cephAdmSshKey:
# Öffentlicher Schlüsselteil von 'ceph_id_rsa.pub', generiert in Abschnitt 3.1.1
publicKey: >-
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC... ceph
nodesSubnet: 10.50.0.0/25 # Subnetz, in dem sich die Ceph-Nodes befinden
hosts:
# Der tatsächliche Hostname der VM (mit 'hostname' bestätigen).
# Hostnamen müssen nicht auflösbar sein (DNS), werden aber von Ceph geprüft
- hostname: ceph-node-0
ipAddress: 10.50.0.2 # Durch die reale IP eines Ceph-Nodes ersetzen
isMaster: true # Nur ein Master erlaubt
- hostname: ceph-node-1
ipAddress: 10.50.0.3 # Durch die reale IP eines weiteren Ceph-Nodes ersetzen
isMaster: false
- hostname: ceph-node-2
ipAddress: 10.50.0.4 # Durch die reale IP eines weiteren Ceph-Nodes ersetzen
isMaster: false
# OSD-Konfiguration (Object Storage Daemon). An deine Hardware anpassen.
# 'dataDevices' darf nicht leer sein. Siehe Ceph-Dokumentation für die 'size'- und 'limit'-Syntax.
osds:
- specId: default
placement:
host_pattern: '*' # Auf alle oben definierten Hosts anwenden
dataDevices: # Geräte zur Datenspeicherung
# Beispiel: alle verfügbaren Geräte, oder nach Größe, Modell etc. angeben
# all: true
size: '300G:' # Festplatten mit 300 GB oder größer
limit: 2 # Bis zu 2 solcher Festplatten pro Host für Daten verwenden
dbDevices: # Geräte für interne BlueStore-Metadaten (DB/WAL)
size: '100G:200G' # Festplatten zwischen 100 GB und 200 GB
limit: 1 # 1 solche Festplatte pro Host für Metadaten-DB verwenden

# --- Kubernetes-Konfiguration ---
# Wähle eine Option: "Neue Kubernetes-Installation" ODER "Externe Kubernetes verwenden"
# kubernetes.managedByCodesphere sollte entsprechend gesetzt werden
kubernetes:
# Option 1: Neue Kubernetes-Installation (mit k0s)
managedByCodesphere: true
apiServerHost: 10.50.0.2 # Externe Adresse für die K8s-API (LB, DNS oder Control-Plane-IP)
controlPlanes:
- ipAddress: 10.50.0.2 # Reale IP des K8s-Control-Plane-Servers
workers:
- ipAddress: 10.50.0.2 # Kann sowohl Control-Plane als auch Worker sein
- ipAddress: 10.50.0.3 # Reale IP eines K8s-Worker-Servers
- ipAddress: 10.50.0.4 # Reale IP eines weiteren K8s-Worker-Servers
# Ende von Option 1

# Option 2: Externe Kubernetes verwenden
managedByCodesphere: false
podCidr: "100.96.0.0/11" # Pod-Netzwerk-CIDR deines externen Clusters
serviceCidr: "100.64.0.0/13" # Service-Netzwerk-CIDR deines externen Clusters
# Stelle sicher, dass 'kubeConfig' in der prod.vault.yaml für den externen Cluster gesetzt ist
# Ende von Option 2

# --- Clusterweite Einstellungen (gilt für installierte und externe K8s) ---
cluster:
certificates: # CA für von Codesphere-Benutzern aufgerufene Dienste
ca:
algorithm: RSA
keySizeBits: 2048
# Inhalt von 'ca.pem' (oder deinem Ingress-CA-Zertifikat) aus Abschnitt 3.1.2
certPem: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
monitoring:
prometheus:
# optional, aktivieren, wenn externes Monitoring durch Codesphere SRE vereinbart wurde
remoteWrite:
enabled: false
clusterName: my-cluster-name
gateway: # Für interne Codesphere-Dienste
serviceType: "LoadBalancer" # oder "ExternalIP"
# annotations: # Optional: für cloud-anbieterspezifische LB-Konfiguration
# Beispiel Azure:
# service.beta.kubernetes.io/azure-load-balancer-ipv4: <IP>
# service.beta.kubernetes.io/azure-load-balancer-resource-group: <rg>
ipAddresses: # Erforderlich, falls serviceType "ExternalIP" ist
- 10.51.0.2 # Beispiel-IP
- 10.51.0.3 # Beispiel-IP
publicGateway: # Für Benutzer-Workspaces
serviceType: "LoadBalancer" # oder "ExternalIP"
# annotations: {}
ipAddresses: # Erforderlich, falls serviceType "ExternalIP" ist
- 10.52.0.2 # Beispiel-IP
- 10.52.0.3 # Beispiel-IP
metallb:
# Dies ist der zentrale Schalter zum Aktivieren oder Deaktivieren der MetalLB-Integration.
# Auf 'true' setzen, damit MetalLB installiert und konfiguriert wird.
enabled: true

# Definiert eine Liste von IP-Adresspools, die MetalLB verwenden kann. Einem Service
# wird eine IP aus einem Pool zugewiesen, der entweder per L2 oder BGP angekündigt wird.
pools:
- # Ein eindeutiger Name zur Identifikation dieses IP-Adresspools.
# Dieser Name wird in den l2- oder bgp-Advertisement-Abschnitten referenziert.
name: "default-pool"
# Eine Liste von IP-Adressen, die MetalLB verwalten kann.
# Diese Bereiche legen fest, welche IPs für deine LoadBalancer-Services verfügbar sind.
ipAddresses:
- "10.10.10.100-10.10.10.200" # Ein IP-Bereich für allgemeine Services.
- "192.168.5.0/24" # Ein CIDR-Block für eine andere Gruppe von Services.

- # Es können mehrere Pools für unterschiedliche Zwecke definiert werden.
name: "special-services-pool"
ipAddresses:
- "172.17.15.1-172.17.15.10" # Ein kleinerer, dedizierter Bereich für bestimmte Services.

# (Optional) Konfiguriert die Layer-2-Ankündigung. Im L2-Modus kündigt ein Node im Cluster
# die Service-IP im lokalen Netzwerk mittels ARP/NDP an.
l2:
- # Ein eindeutiger Name für diese L2-Advertisement-Konfiguration.
name: "default-l2-advertisement"
# Legt fest, welche IP-Adresspools von dieser L2-Konfiguration angekündigt werden sollen.
# Dies verknüpft den L2-Mechanismus mit den im Abschnitt 'pools' definierten IPs.
pools:
- "default-pool"
# (Optional) Beschränkt, welche Nodes die IPs für diese L2-Konfiguration ankündigen dürfen.
# Wenn dies nicht definiert ist, sind alle Nodes im Cluster berechtigt.
nodeSelectors:
- matchLabels:
# Dieser Selektor stellt sicher, dass nur Nodes mit dem Label 'role' auf 'frontend'
# IPs aus dem 'default-pool' per L2 ankündigen.
'role': 'frontend'

# (Optional) Konfiguriert die BGP-Ankündigung (Border Gateway Protocol). Im BGP-Modus
# peeren Nodes mit deinen Netzwerk-Routern, um Routen für die Service-IPs anzukündigen.
bgp:
- # Ein eindeutiger Name für diese BGP-Advertisement-Konfiguration.
name: "main-bgp-advertisement"
# Legt fest, welche IP-Adresspools von dieser BGP-Konfiguration angekündigt werden sollen.
# Hier wird ein anderer Pool per BGP angekündigt.
pools:
- "special-services-pool"
# Details zur BGP-Peering-Konfiguration.
config:
# Die Autonomous System Number (ASN) deines Kubernetes-Clusters.
myASN: 65001
# Die Autonomous System Number (ASN) des externen BGP-Peers (dein Router).
peerASN: 65100
# Die IP-Adresse des BGP-Peers, mit dem verbunden werden soll.
peerAddress: "192.168.1.1"
# (Optional) Der Name eines BFD-Profils für schnelle Fehlererkennung.
# Dies würde separat in der nativen Konfiguration von MetalLB eingerichtet.
bfdProfile: "fast-detection"
# (Optional) Beschränkt, welche Nodes diese BGP-Peering-Sitzung aufbauen dürfen.
# Nützlich, wenn nur Border-Nodes mit dem Peering-Router verbunden sind.
nodeSelectors:
- matchLabels:
# Dieser Selektor stellt sicher, dass nur Nodes mit dem Label 'kubernetes.io/hostname'
# gesetzt auf 'edge-node-01' mit 192.168.1.1 peeren.
'kubernetes.io/hostname': 'edge-node-01'

# --- Konfiguration der Codesphere-Anwendung ---
codesphere:
domain: "codesphere.yourcompany.com" # Haupt-Domain für die Codesphere-UI/API
workspaceHostingBaseDomain: "ws.yourcompany.com" # Basis-Domain für Workspaces (*.ws.yourcompany.com sollte auf publicGateway-IPs zeigen)
# Eine primäre öffentliche IP für Workspaces (verwende eine der publicGateway-IPs). Wenn sie von einem LoadBalancer zugewiesen wird und noch nicht bekannt ist,
# leer lassen und später hinzufügen, sobald bekannt.
publicIp: "10.52.0.2"
customDomains:
cNameBaseDomain: "custom.yourcompany.com" # Für benutzerdefinierte Domain-CNAMEs
dnsServers: [] # z. B. ["1.1.1.1", "8.8.8.8"] IP-Adressen von DNS-Servern zur Auflösung benutzerdefinierter Domains
experiments: [] # Liste der zu aktivierenden experimentellen Codesphere-Funktionen
features: # Map der aktivierten/deaktivierten Codesphere-Funktionen. Siehe [Feature-Flags-Dokumentation](./feature-flags.mdx) für weitere Details.
# email-signup: true
# email-signin: true
# billing: false
extraCaPem: "" # Optional: PEM einer zusätzlichen benutzerdefinierten Root-CA, der Codesphere-Dienste/Workspaces vertrauen sollen
extraWorkspaceEnvVars: {} # z. B. { "HTTP_PROXY": "[http://proxy.example.com:8080](http://proxy.example.com:8080)" }
extraWorkspaceFiles: []
# - path: /etc/custom-certs/my-ca.crt
# content: |
# -----BEGIN CERTIFICATE-----
# ...
# -----END CERTIFICATE-----
# Optional: falls bestimmte MetalLB-Pools für die IP-Zuweisung zu Workspaces verfügbar sein sollen
# ipService:
# loadBalancerKind: metallb
# addressPools:
# - "internal-pool"
# Standard-Workspace-Images überschreiben. Kann nötig sein, wenn benutzerdefinierte Basis-Images verwendet werden
# workspaceImages:
# agent: optional
# bomRef:
# agentGpu: optional
# bomRef:
# server: optional
# bomRef:
# vpn: optional
# bomRef:
deployConfig:
images:
ubuntu-24.04:
name: 'Ubuntu 24.04'
supportedUntil: '2028-05-31'
flavors:
default:
# Für benutzerdefinierte Images den vollständigen Image-Namen inklusive Registry angeben
# Kein Tag hinzufügen, da der Tag von Codesphere verwaltet wird (siehe Anhang)
# image: 'registry.corp42.net/codesphere-custom-images/workspace-agent-24.04-mycorp'
image:
# Für Standard-Basis-Images: muss einem Workspace-Image in der Installer-BOM entsprechen.
# Im Zweifelsfall <deps.tar.gz>/bom.json prüfen
bomRef: 'workspace-agent-24.04'
pool:
1: 1 # Anzahl der vorzuhaltenden vorgewärmten Instanzen
oauth:
oidc:
enabled: false
type: oidc
name: ""
issuerUrl: ""
scopes: ['openid', 'email', 'profile'] # Für Azure AD muss 'https://graph.microsoft.com/User.Read' enthalten sein
plans: # Verfügbare Workspace- und Hosting-Pläne definieren
hostingPlans:
1: # ID muss eine Zahl sein
cpuTenth: 10 # 1 CPU-Kern (10 Zehntel)
gpuParts: 0 # GPU-Ressourcen
memoryMb: 2048 # 2 GB RAM
storageMb: 20480 # 20 GB persistenter Speicher
tempStorageMb: 1024 # Temporärer Speicher
workspacePlans:
1: # ID muss eine Zahl sein
name: "Standard Developer" # Anzeigename des Plans
hostingPlanId: 1 # Verweist auf eine ID aus hostingPlans
maxReplicas: 3 # Maximale gleichzeitige Replikate für einen Workspace
onDemand: true # On-Demand-Workspaces (Start/Stopp) erlauben
# Optional, die tatsächlich angeforderten Ressourcen liegen um diesen Faktor niedriger als im Plan
# definiert, um die Auslastung zu verbessern. Bei Standardwerten belassen, außer bei besonderem Bedarf.
# underprovisionFactors:
# cpu: 0.5
# memory: 0.75
gitProviders:
github:
enabled: false
url: "https://github.com"
api:
baseUrl: "https://api.github.com"
oauth:
issuer: "https://github.com"
authorizationEndpoint: "https://github.com/login/oauth/authorize"
tokenEndpoint: "https://github.com/login/oauth/access_token"
gitlab:
enabled: false
url: "https://gitlab.com" # Für selbst gehostete Instanzen: "https://your-gitlab.example.com"
api:
baseUrl: "https://gitlab.com" # Für selbst gehostete Instanzen nur die Basis-URL. "/api/v4" wird automatisch angehängt.
oauth:
issuer: "https://gitlab.com"
authorizationEndpoint: "https://gitlab.com/oauth/authorize"
tokenEndpoint: "https://gitlab.com/oauth/token"
bitbucket:
enabled: false # Bitbucket Server/Data Center
url: "https://bitbucket.org" # Die URL deiner Bitbucket-Instanz
api:
baseUrl: "https://api.bitbucket.org/2.0" # Für Server: passende API-Basis verwenden
oauth: # OAuth1 für Bitbucket Server, OAuth2 für Cloud
issuer: "https://bitbucket.org"
authorizationEndpoint: "https://bitbucket.org/site/oauth2/authorize"
tokenEndpoint: "https://bitbucket.org/site/oauth2/access_token"
azureDevOps:
enabled: false
url: "https://dev.azure.com"
api:
baseUrl: "https://dev.azure.com"
oauth:
issuer: "https://login.microsoftonline.com"
authorizationEndpoint: "https://login.microsoftonline.com/common/oauth2/v2.0/authorize"
tokenEndpoint: "https://login.microsoftonline.com/common/oauth2/v2.0/token"
clientAuthMethod: 'client_secret_post'
scope: 'openid offline_access https://app.vssps.visualstudio.com/vso.code_full'
managedServices:
# Konfiguriere Managed Service Provider in diesem Abschnitt.
# Detaillierte Konfigurationsoptionen siehe Anhang
# - name: postgres
# api: # ...

# (Optional) Wenn mehrere Cluster dieselbe Masterdaten-Datenbank verwenden,
# setze diesen Scope-Wert, um Reconciliation-Konflikte zu vermeiden.
# managedServiceScope: production-cluster-1

# Managed Services, die ein Landscape-basiertes Backend verwenden, nutzen diese Plan-ID
# Muss einem der Einträge in codesphere.plans entsprechen
managedServiceWorkspacePlanId: 1

managedServiceBackends:
# Wenn du Provider in codesphere.managedServices konfigurierst, musst du auch
# die entsprechenden Backends in diesem Abschnitt bereitstellen.
postgres: {
# Für die Standardkonfiguration leer lassen
}

Denke daran, die Platzhalterwerte durch deine tatsächliche Konfiguration zu ersetzen. Detaillierte Informationen zur Konfiguration von plans und gitProviders (einschließlich der Generierung von OAuth-Anmeldedaten) findest du in den entsprechenden Abschnitten am Ende dieser Anleitung bzw. im ursprünglichen Anhang.

SOPS Secret Manager initialisieren (dateibasiert)

Um zu vermeiden, dass Secrets remote im Klartext gespeichert werden, ist SOPS (Secrets OPerationS) in den Installationsworkflow integriert. Es nutzt Age als dateibasiertes Verschlüsselungswerkzeug.

Das Ziel, die Secrets-Datei (prod.vault.yaml) zu schützen, wird über folgenden Workflow erreicht:

  1. Stelle sicher, dass in prod.vault.yaml keine Kommentare vorhanden sind. Dies ist notwendig, da SOPS Kommentare nicht ignoriert und sie die Dateistruktur der verschlüsselten Version verändern würden.
  2. Verschlüssele prod.vault.yaml auf deiner lokalen Maschine
  3. Speichere nur die verschlüsselte Variante von prod.vault.yaml auf einer Remote-Maschine
  4. Temporär den Entschlüsselungsschlüssel auf die Remote-Maschine kopieren, wo erforderlich
  5. Alternativ: SSH-Portweiterleitung nutzen, um SOPS über HTTP Zugriff auf den Entschlüsselungsschlüssel zu geben (fortgeschritten, siehe 3.5)

Gehe wie folgt vor:

  1. Installiere SOPS und Age auf deiner lokalen Maschine, z. B. auf macOS:
    brew install sops age
  2. Generiere ein Age-Schlüsselpaar (privater + öffentlicher Schlüssel)
    age-keygen -o age_key.txt
    Dadurch wird age_key.txt erstellt, die sowohl den privaten als auch den öffentlichen Schlüssel enthält. Notiere den öffentlichen Schlüssel (beginnt mit age1...). Du benötigst ihn für die Verschlüsselung. Der private Schlüsselteil wird durch AGE-SECRET-KEY-1... gekennzeichnet. Bewahre diesen äußerst sicher auf.
  3. Verschlüssele die Secrets-Datei (prod.vault.yaml) lokal mit dem Age-Schlüsselpaar:
    # Den öffentlichen Schlüssel abrufen
    age-keygen -y age_key.txt
    sops --encrypt --age <age1....> --in-place /home/<myuser>/secrets/prod.vault.yaml
    Dieser Befehl überschreibt die unverschlüsselte prod.vault.yaml direkt.
  4. Initialisiere SOPS auf den Remote-Nodes (Multi-Node-Installer: nur auf dem Setup-Node erforderlich). Du kannst das Installer-Skript nutzen, um SOPS als Komponente zu installieren. Dafür muss deps.tar.gz zunächst extrahiert werden, falls noch nicht erfolgt. Führe dann Folgendes aus:
    # Falls noch nicht erfolgt
    tar -xvzf <INSTALLER-DIR>/deps.tar.gz -C <INSTALLER-DIR>/deps && cd <INSTALLER-DIR>/
    ./node ./install-components.js \
    --dependenciesDir=./deps \
    --config=/root/secrets/config.yaml \
    --component=sops

Um die verschlüsselte prod.vault.yaml-Datei später zu bearbeiten:

export SOPS_AGE_KEY_FILE=/path/to/your/age_key.txt # Auf die Datei mit deinem privaten Schlüssel verweisen
sops /home/<myuser>/secrets/prod.vault.yaml

Dadurch wird die entschlüsselte Datei in deinem Standardeditor geöffnet. Speichern und schließen, um sie erneut zu verschlüsseln.

warnung

Falls du nach dem ersten Durchlauf des Installers Änderungen an der prod.vault.yaml vornehmen musst, wende die Änderungen bitte direkt an der Datei auf der Setup-Maschine an. Grund: Die Installer-Schritte fügen zur Laufzeit eigene generierte Secrets hinzu, d. h. die Datei wird verändert.

Sicherheitsüberlegungen zum privaten Age-Schlüssel

  • Bewahre die age_key.txt (mit dem privaten Schlüssel) höchst sicher und privat auf. Speichere sie nicht dauerhaft auf einem Remote-Node.
  • Multi-Node-Installer: Das Flag --privKey=/path/to/your/age_key.txt wird verwendet, um dem Hauptinstallationsskript den Schlüssel bereitzustellen.
  • Single-Node-Installer / manuelle SOPS-Nutzung auf dem Server: Falls der Schlüssel unbedingt auf einem Server verwendet werden muss (z. B. während der Single-Node-Komponenteninstallation), übertrage ihn sicher und entferne ihn unmittelbar nach Gebrauch, oder nutze SSH-Portweiterleitung für temporären Zugriff, falls SOPS Remote-Schlüsseldateien über HTTP unterstützt (fortgeschritten).

Zum Entschlüsseln der Secrets-Datei verwende:

# export SOPS_AGE_KEY_FILE=/path/to/temporarily/copied/age_key.txt
sops --decrypt /home/<myuser>/secrets/prod.vault.yaml

HTTP-Zugriff auf den lokalen age_key via SSH-Portweiterleitung

  1. Auf deiner lokalen Maschine (auf der sich age_key.txt befindet):
cd /path/to/keypair_directory
python3 -m http.server 8000
  1. SSH von deiner lokalen Maschine zum Remote-Server, dabei den Port weiterleiten:
ssh -L 9000:localhost:8000 user@remote-host
  1. Auf dem Remote-Server:
export SOPS_AGE_KEY_FILE_URL=http://localhost:9000/age_key.txt
sops --decrypt /home/<myuser>/secrets/prod.vault.yaml

Diese HTTP-Methode dient dem temporären Zugriff und sollte mit Vorsicht verwendet werden. Wenn möglich, ist die direkte Übergabe des Schlüsseldateipfads vorzuziehen.


Anleitung zur Multi-Node-Installation

Dieser Installer nutzt SSH, um sich von einer zentralen Setup-Maschine aus mit den verschiedenen Hosts zu verbinden und die Komponenten nacheinander zu installieren.

Voraussetzungen (Zusammenfassung & Spezifika)

  • Alle globalen Voraussetzungen (Abschnitt 2) sind erfüllt.
  • Installer-Maschine: OpenSSH-Client, scp, Node.js v22 (mit dem Installer geliefert).
  • Ziel-Nodes: iptables, vi/nano, curl.
  • SSH-Zugriff: root-Zugriff von der Installer-Maschine auf alle Ziel-Nodes.
  • Abhängigkeiten: Das Skript private-cloud-installer.js und das Archiv deps.tar.gz liegen auf der Installer-Maschine.
  • Konfiguration: config.yaml und die verschlüsselte prod.vault.yaml sind vorbereitet (Abschnitt 3, siehe auch unten).
  • Privater Age-Schlüssel: Die Datei age_key.txt ist für die Installer-Maschine zugänglich.

Optionen zur Image-Verteilung

Der Multi-Node-Installer bietet zwei verschiedene Optionen zur Verteilung aller benötigten Container-Images auf alle Ziel-Nodes.

Bei Verwendung einer externen Container-Registry lädt der Installer alle Images aus dem Archiv deps.tar.gz und pusht sie von der Verwaltungsmaschine aus in die Registry. Dafür müssen registry.server in config.yaml sowie registryUsername und registryPassword in prod.vault.yaml korrekt befüllt sein. Die angegebene Registry muss von allen Nodes aus erreichbar sein.

Wenn keine Registry angegeben ist, werden die Images direkt aus deps.tar.gz auf dem Node geladen.

Synchronisation von Konfigurationsdateien und Secrets

Der Multi-Node-Installer stellt sicher, dass config.yaml, die verschlüsselte prod.vault.yaml und die zur Entschlüsselung benötigte age_key.txt mit allen Ziel-Nodes synchronisiert werden. Auf den Ziel-Nodes befinden sie sich in /etc/codesphere/. Der Multi-Node-Installer ändert vor dem Upload auf die Ziel-Nodes automatisch den Wert von secrets.baseDir in config.yaml.

Vorbereitende Schritte auf den Ziel-Nodes

Inotify-Watcher-Limits konfigurieren

Siehe Globale Einrichtung – Abschnitt 2.5. Stelle sicher, dass dies auf allen Kubernetes-Nodes erfolgt.

Festplatten für Ceph vorbereiten

Stelle sicher, dass die für Ceph-OSDs vorgesehenen Festplatten (Daten und Metadaten-DB) vollständig leer sind. Vorsicht: Dieser Befehl löscht Daten von der Festplatte sdx. Überprüfe den Festplattenbezeichner sorgfältig. Für jede Ceph-Daten-/DB-Festplatte auf jedem Ceph-Node:

sudo dd if=/dev/zero of=/dev/sdx bs=1M count=100 conv=fsync # sdx ist deine Zielfestplatte, z. B. sdb, sdc
sudo wipefs -a /dev/sdx

Nach dem Bereinigen der Festplatten kann ein Neustart erforderlich sein, damit die Änderungen vom Betriebssystem vollständig erkannt werden.

sudo reboot

Synchronisierte Uhren

Stelle sicher, dass die Zeit auf allen Servern synchronisiert ist. Verwende NTP (Network Time Protocol).

sudo apt update
sudo apt install chrony -y
sudo systemctl enable chrony --now
sudo chronyc sources

Überprüfe, dass alle Nodes mit einer zuverlässigen Zeitquelle synchronisiert sind.

Die Installation durchführen

Führe das Hauptinstallationsskript von deiner zentralen Setup-Maschine aus. Dieser Befehl installiert alle in deiner config.yaml definierten Komponenten.

node ./private-cloud-installer.js \
--archive=./deps.tar.gz \
--config=/home/<myuser>/secrets/config.yaml \
--privKey=/path/to/your/age_key.txt

Der Installer arbeitet die Komponenten in dieser Reihenfolge ab: Docker, Postgres (falls konfiguriert), Ceph, Kubernetes (k0s), SetUpCluster und schließlich Codesphere.

tipp

Du kannst --skipSteps=loadContainerImages --skipSteps=extract-dependencies hinzufügen, um Zeit zu sparen, falls du den Installer aufgrund eines Fehlers ein zweites Mal ausführst und diese beiden Schritte bereits abgeschlossen wurden (weitere Details unten).

Nach der Installation und Fehlerbehebung

Ceph-Spezifika

  • Bekanntes Problem: Manchmal initialisiert Ceph so, dass nur ein Monitor-Daemon vollständig gesund wird, was zu einer nicht-hochverfügbaren (aber funktionsfähigen) Monitor-Konfiguration führt. Der Installer versucht, mehrere zu konfigurieren.

  • Ceph-Fehlerbehebung: Falls Ceph Probleme aufweist, kannst du dich in den Ceph-Admin-Container auf dem Ceph-Master-Node einloggen:

# Auf dem Ceph-Master-Node (wie in deiner config.yaml definiert)
sudo ./ceph/files/cephadm --image quay.io/ceph/ceph:v18.2 --docker \
shell ceph status

Wenn der Status nach manuellen Prüfungen oder Korrekturen gesund wird, kannst du möglicherweise den Installer neu starten, oder er setzt seine Arbeit dort fort, wo er aufgehört hat (das Verhalten hängt von der Idempotenz des Installers für Ceph ab).

  • Debugging des Ceph-Managers (mgr):
# Auf einem Ceph-Node mit einem laufenden Manager
systemctl list-units | grep ceph.*mgr
# Beispiel: [email protected]
sudo systemctl restart <ceph-mgr-service-name>
sudo journalctl -u <ceph-mgr-service-name> -r # -r für umgekehrt chronologisch (neueste zuerst)
  • Debugging von Ceph-OSDs (osd): Liste laufende Docker-Container auf, um die OSDs zu sehen:
# Auf einem Ceph-OSD-Node
sudo docker ps | grep ceph-osd
  • Logs für einen bestimmten OSD-Container prüfen:
sudo docker logs <container_id_or_name_of_osd>

Bestimmte Installationsschritte überspringen

warnung

Mit Vorsicht verwenden! --skipStep ist ein "harter Sprung" und prüft nicht, ob ein bestimmter Schritt tatsächlich sicher übersprungen werden kann.

In bestimmten Fällen, z. B. beim Beheben eines Fehlers in der config.yaml oder beim Ändern eines Secrets, können einige zeitintensive Installationsschritte übersprungen werden. Eine Liste aller unterstützten überspringbaren Schritte erhältst du mit:

./node ./private-cloud-installer.js -h

Ein oder mehrere zu überspringende Schritte können über das --skipStep-Flag von prviate-cloud-installer.js gesetzt werden, zum Beispiel:

node ./private-cloud-installer.js \
--archive=./deps.tar.gz \
--config=/home/<myuser>/secrets/config.yaml \
--privKey=/path/to/your/age_key.txt \
--skipStep=copy-dependencies \
--skipStep=extract-dependencies

Anleitung zur Single-Node-Installation

Bei dieser Methode werden Installationsbefehle für jede Komponente manuell auf den jeweiligen Ziel-Hosts ausgeführt. Du musst die Abhängigkeiten- und Konfigurationsdateien auf jeden Host kopieren.

Voraussetzungen (Zusammenfassung & Spezifika)

  • Alle globalen Voraussetzungen (Abschnitt 2) sind erfüllt.
  • Auf jedem Ziel-Node: iptables, vi/nano, curl. Das Skript install-components.js (aus deps.tar.gz) wird verwendet.
  • SSH-Zugriff: Du verbindest dich per SSH mit jedem Node, um Befehle auszuführen. Die Befehle erfordern in der Regel root oder sudo.
  • Abhängigkeiten: deps.tar.gz muss auf jeden Host hochgeladen und extrahiert werden.
  • Konfiguration: config.yaml und die verschlüsselte prod.vault.yaml müssen auf jedem Host verfügbar sein, auf dem install-components.js ausgeführt wird.
  • Privater Age-Schlüssel: age_key.txt muss zugänglich sein, wenn Befehle ausgeführt werden, die die Entschlüsselung von Secrets erfordern (z. B. auf dem Control-Plane-Node für die meisten Schritte).

Umgebung auf jedem Host einrichten

  1. Abhängigkeiten hochladen und extrahieren: Für jeden Host (PostgreSQL-, Ceph-, Kubernetes-Nodes):
# Von deiner Verwaltungsmaschine
scp deps.tar.gz <user>@<host_ip>:./deps.tar.gz

# Per SSH mit dem Host verbinden
ssh <user>@<host_ip>
sudo mkdir /opt/codesphere_deps
sudo tar xf deps.tar.gz -C /opt/codesphere_deps
cd /opt/codesphere_deps
  1. (Stelle sicher, dass install-components.js unter ./installer/files/ innerhalb des extrahierten Verzeichnisses liegt)

  2. Konfigurationsdateien hochladen: Lade config.yaml und die verschlüsselte prod.vault.yaml (erstellt in Abschnitt 3) auf jeden Host hoch, typischerweise in ein Verzeichnis wie /home/<user>/secrets/ oder /root/secrets/. Stelle außerdem age_key.txt bei Bedarf sicher für die Entschlüsselung auf diesem Host bereit.

# Von deiner Verwaltungsmaschine
scp /path/to/config.yaml <user>@<host_ip>:/root/secrets/config.yaml
scp /path/to/prod.vault.yaml <user>@<host_ip>:/root/secrets/prod.vault.yaml
# Falls direkter Schlüsselzugriff auf dem Host benötigt wird (mit Vorsicht verwenden):
# scp /path/to/age_key.txt <user>@<host_ip>:/root/secrets/age_key.txt
  1. Passe Pfade in config.yaml (secrets.baseDir) entsprechend an, falls nicht /root/secrets verwendet wird.

  2. Inotify-Watcher-Limits konfigurieren: (Behandelt in der Globalen Einrichtung – Abschnitt 2.5. Stelle sicher, dass dies auf allen Kubernetes-Nodes erfolgt.)

Schrittweise Komponenteninstallation

Alle folgenden Befehle sollten grundsätzlich als root oder mit sudo ausgeführt werden. Navigiere zu dem Verzeichnis, in das du die Abhängigkeiten extrahiert hast (z. B. /opt/codesphere_deps). Der --privKey-Pfad sollte auf deine age_key.txt verweisen.

Container-Engine einrichten (Docker)

Führe dies auf jedem Host aus (Ceph, Kubernetes, jedem Node, der Container für Codesphere-Komponenten ausführt, falls nicht alles über K8s läuft). Das Dateisystem unter /var/lib/docker (oder Äquivalent für deine Container-Engine) sollte mindestens 100–200 GB frei haben.

sudo ./installer/files/node ./installer/files/install-components.js \
--dependenciesDir=. \
--config=/root/secrets/config.yaml \
--component=docker

# Benötigte Images in den lokalen Docker-Cache laden (hauptsächlich auf K8s-Nodes)
sudo ./installer/files/node ./installer/files/install-components.js \
--dependenciesDir=. \
--config=/root/secrets/config.yaml \
--privKey=/root/secrets/age_key.txt \
--component=loadContainerImages

Prüfen: sudo docker info und sudo docker image ls.

PostgreSQL installieren (falls keine externe Instanz verwendet wird)

A. Primären PostgreSQL-Node installieren: Verbinde dich per SSH mit dem vorgesehenen primären PostgreSQL-Server (gemäß deiner config.yaml).

sudo ./installer/files/node ./installer/files/install-components.js \
--dependenciesDir=. \
--config=/root/secrets/config.yaml \
--privKey=/root/secrets/age_key.txt \
--component=postgresPrimary

Prüfen: sudo systemctl status codesphere-postgres.service

B. Replica-PostgreSQL-Node(s) installieren: Verbinde dich per SSH mit dem/den vorgesehenen Replica-PostgreSQL-Server(n).

sudo ./installer/files/node ./installer/files/install-components.js \
--dependenciesDir=. \
--config=/root/secrets/config.yaml \
--privKey=/root/secrets/age_key.txt \
--component=postgresReplica

Prüfen: sudo systemctl status codesphere-postgres.service

Ceph installieren

A. Nodes vorbereiten (Bereinigung & Synchronisation):

  • Festplatten bereinigen: (Abschnitt 4.3.2) Stelle auf jedem Ceph-Node sicher, dass die für OSDs vorgesehenen Festplatten vollständig gelöscht sind.
  • Synchronisierte Uhren: (Abschnitt 4.3.3) Stelle sicher, dass die Zeit auf allen Ceph-Nodes synchronisiert ist.

B. Ceph installieren: Führe den Befehl zunächst auf allen Nicht-Master-Ceph-Nodes aus und anschließend auf dem Master-Ceph-Node (wie in config.yaml definiert).

sudo ./installer/files/node ./installer/files/install-components.js \
--dependenciesDir=. \
--config=/root/secrets/config.yaml \
--privKey=/root/secrets/age_key.txt \
--component=ceph

Fehlerbehebung: Siehe Abschnitt 4.5.1 für Ceph-Fehlerbehebungsbefehle.

Kubernetes installieren (k0s)

A. Control-Plane-Node(s) installieren: Verbinde dich per SSH mit dem/den vorgesehenen Kubernetes-Control-Plane-Node(s).

sudo ./installer/files/node ./installer/files/install-components.js \
--dependenciesDir=. \
--config=/root/secrets/config.yaml \
--privKey=/root/secrets/age_key.txt \
--component=kubernetes # Dies installiert die k0s-Control-Plane

Nachdem die erste Control-Plane läuft, beziehe ein Bootstrap-Token für Worker-Nodes:

sudo ./kubernetes/files/k0s token create --role=worker > /tmp/k0s_worker_token.txt

Kopiere diese Datei /tmp/k0s_worker_token.txt sicher auf alle geplanten Worker-Nodes.

B. Worker-Node(s) installieren: Verbinde dich per SSH mit jedem vorgesehenen Kubernetes-Worker-Node. Dieser Schritt ist nicht erforderlich, wenn ein Node sowohl Control-Plane als auch Worker ist (Single-Node-K8s-Setup oder kombinierte Rollen).

# Stelle sicher, dass /tmp/k0s_worker_token.txt auf dem Worker-Node vorhanden ist
export K0S_TOKEN_FILE=/tmp/k0s_worker_token.txt # k0s erwartet diese Umgebungsvariable
sudo ./installer/files/node ./installer/files/install-components.js \
--dependenciesDir=. \
--config=/root/secrets/config.yaml \
--privKey=/root/secrets/age_key.txt \
--component=kubernetes # Dies installiert den k0s-Worker

Warte, bis alle Worker-Nodes bereit sind. Überprüfe von einem Control-Plane-Node aus:

sudo ./kubernetes/files/k0s kubectl get nodes -o wide

Hinweis: Control-Plane-Nodes werden bei kubectl get nodes möglicherweise nicht als "Nodes" angezeigt, wenn sie nicht auch als Worker vorgesehen sind oder wenn es sich um reine Master-Nodes handelt.

Anfängliche Kubernetes-Ressourcen erstellen

Führe folgende Befehle auf einem Kubernetes-Control-Plane-Node aus:

  1. Codesphere-Namespace erstellen:
sudo ./kubernetes/files/k0s kubectl create ns codesphere
  1. Dummy-Fehlerseiten-Server erstellen (temporär): Dies ist ein Platzhalter, der von setUpCluster benötigt wird, falls bestimmte Dienste noch nicht laufen.

sudo ./kubernetes/files/k0s kubectl -n codesphere create svc clusterip error-page-server --tcp=8080:8080

Grundlegende Komponenten installieren (setUpCluster)

Führe dies auf einem Kubernetes-Control-Plane-Node aus:

sudo ./installer/files/node ./installer/files/install-components.js \
--dependenciesDir=. \
--config=/root/secrets/config.yaml \
--privKey=/root/secrets/age_key.txt \
--component=setUpCluster

Codesphere installieren

A. Docker-Images aktualisieren (optional – für Upgrades oder um die neuesten Images sicherzustellen): Falls du ein Update durchführst oder sicherstellen möchtest, dass die aktuellsten Images (gemäß deps.tar.gz) verwendet werden:

  1. Images in den Docker-Cache auf K8s-Nodes laden: Auf jedem Kubernetes-Node (Control-Plane und Worker) ausführen:
sudo ./installer/files/node ./installer/files/install-components.js \
--dependenciesDir=. \
--config=/root/secrets/config.yaml \
--privKey=/root/secrets/age_key.txt \
--component=loadContainerImages
  1. Neue Images für k0s verfügbar machen (falls k0s verwendet wird): Auf jedem Kubernetes-Node ausführen. Dadurch werden Nodes vorübergehend NotReady.

sudo ./installer/files/node ./installer/files/install-components.js \
--dependenciesDir=. \
--config=/root/secrets/config.yaml \
--privKey=/root/secrets/age_key.txt \
--component=reloadKubernetesImages
  1. Warte, bis alle Nodes wieder Ready sind (ca. 5 Minuten). Prüfen mit: sudo ./kubernetes/files/k0s kubectl get nodes -o wide

B. Abschließende Installation: Führe dies auf einem Kubernetes-Control-Plane-Node aus:

  1. Dummy-Fehlerseiten-Server löschen:
sudo ./kubernetes/files/k0s kubectl -n codesphere delete svc error-page-server
  1. Codesphere-Anwendung installieren:

sudo ./installer/files/node ./installer/files/install-components.js \
--dependenciesDir=. \
--config=/root/secrets/config.yaml \
--privKey=/root/secrets/age_key.txt \
--component=codesphere
  1. Deine Codesphere-Installation sollte nun abgeschlossen sein. Zugriff erfolgt über die in codesphere.domain in deiner config.yaml angegebene Domain.

Anhang

Konfiguration der Codesphere-Pläne

Pläne definieren die verfügbaren Ressourcen für Entwickler-Workspaces. Konfiguriere dies im Abschnitt codesphere.plans deiner config.yaml.

  • hostingPlans: Definiert die reinen Ressourcenzuteilungen. IDs müssen Zahlen sein.
    • cpuTenth: CPU-Kerne in Zehnteln (z. B. 10 = 1 Kern, 25 = 2,5 Kerne).
    • gpuParts: GPU-Zuteilung (abhängig von deinem GPU-Setup).
    • memoryMb: Arbeitsspeicher in Megabyte.
    • storageMb: Persistenter Speicher für den Workspace in Megabyte.
    • tempStorageMb: Temporärer Speicher in Megabyte.
    • pooledInstances: Anzahl vorgewärmter Instanzen dieses Plans, die bereitgehalten werden.
  • workspacePlans: Definiert vom Benutzer wählbare Pläne, die auf hostingPlans verweisen. IDs müssen Zahlen sein.
    • name: Anzeigename des Plans.
    • hostingPlanId: Verweist auf eine ID in hostingPlans.
    • maxReplicas: Maximale Anzahl gleichzeitiger Instanzen für einen einzelnen Workspace in diesem Plan.
    • onDemand: true, wenn Benutzer diese Workspaces starten/stoppen können, false für dauerhaft aktiv.

Beispiel: (Bereits im Hauptbeispiel der config.yaml enthalten)

codesphere:
# ... weitere Codesphere-Einstellungen ...
plans:
hostingPlans:
1:
cpuTenth: 10
gpuParts: 0
memoryMb: 2048
storageMb: 20480
tempStorageMb: 1024
2:
cpuTenth: 20
memoryMb: 4096
storageMb: 51200
tempStorageMb: 2048
workspacePlans:
1:
name: "Basic"
hostingPlanId: 1
maxReplicas: 1
onDemand: true
2:
name: "Pro"
hostingPlanId: 2
maxReplicas: 3
onDemand: true

Konfiguration des Git-Providers

Konfiguriere Git-Provider-Integrationen unter codesphere.gitProviders in config.yaml. Für jeden aktivierten Provider musst du außerdem entsprechende clientId und clientSecret in deine Secrets-Datei prod.vault.yaml eintragen (siehe Abschnitt 3.2).

Allgemeine Struktur für jeden Provider:

# providerName z. B. github, gitlab
# providerName:
# enabled: true # oder false
# url: "Basis-URL des Providers"
# api:
# baseUrl: "API-Basis-URL"
# oauth:
# issuer: "OAuth-Issuer-URL"
# authorizationEndpoint: "OAuth-Autorisierungs-URL"
# tokenEndpoint: "OAuth-Token-URL"
# # Weitere providerspezifische OAuth-Einstellungen wie scope, clientAuthMethod

Anmeldedaten generieren (Beispiele):

  • GitLab:

    1. Gehe zu deiner GitLab-Gruppe (oder den Benutzereinstellungen für eine benutzerbezogene App) > Einstellungen > Anwendungen.
    2. Erstelle eine neue Anwendung (z. B. "Codesphere Git Integration").
    3. Redirect-URI/Callback-URL: https://<codesphere.domain>/ide/auth/gitlab/callback (ersetze <codesphere.domain> durch deine Codesphere-Domain).
    4. Scopes: Wähle api, read_repository, write_repository. (Stelle sicher, dass openid, profile, email ebenfalls verfügbar/ausgewählt sind, falls Benutzerprofilinformationen benötigt werden.)
    5. Speichere die Anwendung. Du erhältst eine "Application ID" (gitlabAppClientId) und ein "Secret" (gitlabAppClientSecret).
  • GitHub:

    1. Gehe zu den Einstellungen deiner GitHub-Organisation > Entwicklereinstellungen > OAuth Apps > Neue OAuth App.
    2. Anwendungsname: z. B. "Codesphere"
    3. Homepage-URL: https://<codesphere.domain>
    4. Authorization-Callback-URL: https://<codesphere.domain>/ide/auth/github/callback
    5. Du erhältst eine "Client ID" (githubAppsClientId) und generierst ein "Client Secret" (githubAppsClientSecret).
  • Bitbucket (Server/Data Center – in der Regel Application Links für OAuth 1.0a oder OAuth 2.0, falls unterstützt):

    1. Admin-Einstellungen > System > Application Links.
    2. Erstelle einen neuen Link. Wähle "External Application", "Incoming".
    3. Redirect-URL: https://<codesphere.domain>/ide/auth/bitbucket/callback
    4. Berechtigungen: Repository Lese-/Schreibzugriff.
    5. Du erhältst einen "Consumer Key" (bitbucketAppsClientId) und ein "Consumer Secret" (bitbucketAppsClientSecret) oder Ähnliches, abhängig von der OAuth-Version.
  • Azure DevOps:

    1. Registriere eine Anwendung in Azure Active Directory.
    2. Redirect-URI: https://<codesphere.domain>/ide/auth/azureDevOps/callback (stelle sicher, dass sie als Web-Redirect-URI hinzugefügt wird).
    3. Notiere die "Application (client) ID" (azureDevOpsAppClientId).
    4. Gehe zu "Certificates & secrets" -> "New client secret", um azureDevOpsAppClientSecret zu generieren. Setze eine Erinnerung, dieses Secret regelmäßig zu erneuern, da es ein Ablaufdatum hat.
    5. API-Berechtigungen: Füge Berechtigungen für "Azure DevOps" -> user_impersonation hinzu und stelle sicher, dass vso.code_full im Scope in config.yaml enthalten ist.

Denke daran, diese Client-IDs und Secrets in deine prod.vault.yaml-Datei einzutragen und sie zu verschlüsseln. Beispielhafte Secret-Namen:

  • githubAppsClientId, githubAppsClientSecret
  • gitlabAppClientId, gitlabAppClientSecret
  • bitbucketAppsClientId, bitbucketAppsClientSecret
  • azureDevOpsAppClientId, azureDevOpsAppClientSecret

Konfiguration der Managed Services

Jeder im Bereich Managed Services angebotene Dienst wird als individueller Managed Service Provider im Array codesphere.managedServices in config.yaml konfiguriert. Die Konfiguration folgt einem bestimmten Schema.

Managed Service Provider können extern zu Codesphere sein, d. h. es wird eine externe API aufgerufen, es gibt aber auch integrierte Managed Services, bei denen der Provider innerhalb von Codesphere läuft. Im aktuellen Release gibt es 1 solchen Provider für PostgreSQL.

Der folgende Ausschnitt zeigt eine Beispielkonfiguration des Postgres-Managed-Service-Providers. Bei Verwendung dieses Providers stelle bitte sicher, auch das entsprechende Backend im Abschnitt managedServiceBackends zu aktivieren.

- name: postgres
version: v1
backend:
api:
endpoint: "http://ms-backend-postgres.postgres-operator:3000/api/v1/postgres"
author: Codesphere
category: Database
displayName: PostgreSQL
iconUrl: /ide/assets/managed-services/postgresql.svg
configSchema:
type: object
properties:
version:
type: string
description: Version der Postgres-DB. Enthält vorinstallierte, mit dieser Version kompatible Extensions. Extension-Versionen werden verwaltet und können nicht angepasst werden.
enum:
- '17.6'
- '16.10'
default: '17.6'
readOnly: false
userName:
type: string
default: app
pattern: '^(?!postgres$)'
databaseName:
type: string
default: app
required: []
additionalProperties: false
detailsSchema:
type: object
properties:
port:
type: integer
hostname:
type: string
dsn:
type: string
ready:
type: boolean
required:
- port
- hostname
- dsn
- ready
additionalProperties: false
secretsSchema:
type: object
properties:
userPassword:
type: string
format: password
superuserPassword:
type: string
format: password
required:
- userPassword
- superuserPassword
additionalProperties: false
description: >-
Open-Source-Datenbanksystem, ausgelegt für effizientes Datenmanagement und
Skalierbarkeit. Wird auf Codesphere mit dem CNPG-K8s-Operator bereitgestellt.
plans:
- id: 0
description: 0,5 vCPU / 500 MB Speicher
name: Small
parameters:
storage:
pricedAs: storage-mb
schema:
description: Speicher (MB)
type: integer
default: 10000
readOnly: false
cpu:
pricedAs: cpu-tenths
schema:
description: CPU-Zehntel
type: number
default: 5
readOnly: true
memory:
pricedAs: ram-mb
schema:
description: Speicher (MB)
type: integer
default: 500
readOnly: true
- id: 1
description: 1 vCPU / 1 GB Speicher
name: Medium
parameters:
storage:
pricedAs: storage-mb
schema:
description: Speicher (MB)
type: integer
default: 25000
readOnly: false
cpu:
pricedAs: cpu-tenths
schema:
description: CPU-Zehntel
type: number
default: 10
readOnly: true
memory:
pricedAs: ram-mb
schema:
description: Speicher (MB)
type: integer
default: 1000
readOnly: true
- id: 2
description: 1 vCPU / 2 GB Speicher
name: Medium High-Mem
parameters:
storage:
pricedAs: storage-mb
schema:
type: integer
default: 25000
readOnly: false
cpu:
pricedAs: cpu-tenths
schema:
type: number
default: 10
readOnly: true
memory:
pricedAs: ram-mb
schema:
type: integer
default: 2000
readOnly: true
- id: 3
description: 2 vCPU / 4 GB Speicher
name: Large
parameters:
storage:
pricedAs: storage-mb
schema:
type: integer
default: 50000
readOnly: false
cpu:
pricedAs: cpu-tenths
schema:
type: number
default: 20
readOnly: true
memory:
pricedAs: ram-mb
schema:
type: integer
default: 4000
readOnly: true
- id: 4
description: 4 vCPU / 8 GB Speicher
name: Extra Large
parameters:
storage:
pricedAs: storage-mb
schema:
type: integer
default: 150000
readOnly: false
cpu:
pricedAs: cpu-tenths
schema:
type: number
default: 40
readOnly: true
memory:
pricedAs: ram-mb
schema:
type: integer
default: 8000
readOnly: true

Benutzerdefinierte Workspace-Basis-Images erstellen

Das Standard-Basis-Image für Workspaces enthält bereits viele nützliche Tools und Bibliotheken. Du kannst jedoch auch eigene benutzerdefinierte Basis-Images erstellen. Ein Grund, Basis-Images anzupassen, sind Pakete, die nicht über Nix verfügbar sind, aber über apt installiert werden müssen.

Die Codesphere OMS CLI bietet eine praktische Möglichkeit, eigene benutzerdefinierte Basis-Images zu erstellen.

Voraussetzungen:

  1. Installiere auf deinem Host Docker und das Buildx-Plugin (falls noch nicht installiert):
    sudo apt install docker.io docker-buildx
  2. Installiere die OMS CLI wie unter https://github.com/codesphere-cloud/oms beschrieben
  3. Verwende den Befehl extend baseimage in der OMS CLI, siehe
    oms-cli beta extend baseimage -h
  4. Dieser Befehl extrahiert das Standard-Basis-Image aus dem Codesphere-Installer-Bundle, lädt es in deinen lokalen Docker-Image-Cache und generiert ein Dockerfile, das du erweitern kannst.
  5. Bestätige mit docker image ls, dass das Basis-Image (ghcr.io/codesphere-cloud/codesphere-monorepo/workspace-agent-VERSION) lokal verfügbar ist.
  6. Bearbeite das generierte Dockerfile, um deine benutzerdefinierten Abhängigkeiten hinzuzufügen.
  7. Als Best Practice solltest du das Dockerfile in ein Unterverzeichnis legen, z. B. ./docker. So wird sichergestellt, dass beim folgenden Docker-Build-Befehl nur die notwendigen Dateien an den Docker-Daemon gesendet werden.
  8. Ermittle den Basis-Image-Tag aus dem Dockerfile, z. B. codesphere-1-67-1-4dd9b346cc, und verwende denselben Tag für dein benutzerdefiniertes Image.
  9. Baue das benutzerdefinierte Image mit folgendem Befehl:
    docker buildx build -f ./docker/custom.Dockerfile -t workspace-agent-24.04-mycorp:<TAG_TO_USE> --load ./docker
  10. Tagge und pushe das Image mit demselben Tag wie das Originalimage in deine eigene Registry:
    docker tag workspace-agent-24.04-mycorp:<TAG_TO_USE> <YOUR_REGISTRY_URL>/workspace-agent-24.04-mycorp:<TAG_TO_USE>
    docker login <YOUR_REGISTRY_URL> # falls noch nicht eingeloggt
    docker push <YOUR_REGISTRY_URL>/workspace-agent-24.04-mycorp:<TAG_TO_USE>

warnung

Der Image-Name kann frei gewählt werden, überprüfe aber genau, dass der Tag deines benutzerdefinierten Images exakt dem Tag des Original-Basis-Images entspricht. Stimmen die Tags nicht überein, kann Codesphere dein benutzerdefiniertes Image beim Starten von Workspaces derzeit nicht finden.

Zugriff auf Cluster-Monitoring (Grafana)

Im Rahmen der regulären Codesphere-Installation wird automatisch eine Grafana-Instanz mit vordefinierten Dashboards im Cluster bereitgestellt. Die Anmeldedaten werden automatisch generiert. Die Grafana-UI kann über Port-Forwarding zu localhost erreicht werden.

Schritte für den Zugriff auf die Grafana-Instanz:

  1. Anmeldedaten abrufen:
    1. Benutzername: admin
    2. Passwort: kubectl get secret grafana -n monitoring -o jsonpath={.data.admin-password} | base64 -d
  2. Auf Grafana im lokalen Browser zugreifen:
    1. Port-Forward starten mit kubectl port-forward deployment/grafana 3000:3000 -n monitoring
    2. Im lokalen Browser localhost:3000 aufrufen
    3. Mit den Anmeldedaten aus dem vorherigen Schritt einloggen.
  3. Hinweis: Wenn kubectl-Zugriff nur z. B. über einen Jumphost besteht, kann SSH-Portweiterleitung genutzt werden, um zur lokalen Maschine durchzureichen: ssh -L 3000:localhost:3000 user@jumphost