Zum Hauptinhalt springen
Version: Weekly Build

Installationsanleitung

Diese Anleitung enthält umfassende Anweisungen zur Installation von Codesphere Private Cloud. Codesphere wird primär 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 besseren Stabilität und Robustheit als externe Komponenten behandelt.

Dieses Dokument beschreibt zwei unterschiedliche Installationsmethoden:

  1. Multi-Node Installer: Diese Methode nutzt ein Skript, das per SSH von einer zentralen Setup-Maschine aus eine Verbindung zu verschiedenen Hosts aufbaut und die Komponenten sequenziell installiert. Sie ist dafür ausgelegt, ein komplettes Codesphere-Rechenzentrum von Grund auf (Bare Metal, VMs) bereitzustellen oder mit 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 setzen eine globale Konfigurationsdatei config.yaml voraus 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 über ein Helm-Chart bereitgestellt. Für kritische Infrastruktur wie PostgreSQL und Ceph (für verteilten, hochverfügbaren Speicher) empfehlen wir jedoch, diese als robuste, externe Dienste einzurichten, anstatt sie in das Helm-Chart einzubetten. Dieser Ansatz sorgt für eine stabilere und widerstandsfähigere Umgebung.

Diese Installer sind modulare Werkzeuge, die es ermöglichen:

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

Zentrale Installer-Komponenten

Der Installationsprozess umfasst mehrere zentrale Komponenten:

KomponentennameBeschreibung
SecretsVerwaltet vertrauliche Daten mittels Age- und Sops-Schlüsseldateien.
DockerContainer-Runtime zur 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 eigentliche 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 / (einschließlich /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 Block-Speicherkapazität ausmachen. Muss vollständig leer sein (kein Dateisystem).
    • 1 oder mehrere Festplatten mit jeweils mindestens 300 GB für Ceph-Block-Speicher (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 / (einschließlich /etc/codesphere)
      • Zusätzlich 200 GB unter /var/lib/docker (bzw. /var/lib/k0s, wenn 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 für jeden Control-Plane-Node.

Erforderliche Software-Pakete

Stelle sicher, dass folgende Software installiert ist:

  • Auf der Installer-Maschine (nur Multi-Node, oder deiner Management-Maschine für Single-Node):

    • OpenSSH-Client
    • scp (Secure Copy Protocol Client)
    • Node.js Version 22 (eine node-Binärdatei 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, die die Installer-Skripte ausführt, muss SSH-Zugriff auf alle entfernten 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-ADDRESS> funktioniert, d. h. es darf kein Passwort erforderlich sein und kein Benutzer muss angegeben werden.
  • Um ein passwortloses Login zu ermöglichen, konfiguriere ein öffentliches Schlüsselpaar für SSH (ersetze id_ed25519_csinstall durch den gewünschten Schlüsselnamen):
    ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_csinstall -C "some identifier"
    # Nutze ssh-copy-id oder kopiere den öffentlichen Schlüssel (*.pub) auf /root/.ssh/authorized_keys aller VMs
    ssh-copy-id -i ~/.ssh/id_ed25519_csinstall root@host
  • Der Benutzer auf den entfernten Maschinen MUSS aktuell root sein.
  • Du kannst den SSH-Zugriff für verschiedene Hosts über deine SSH-Konfigurationsdatei einrichten (z. B. ~/.ssh/config). Beispiel:
    Host 10.10.123.1
    HostName 10.10.123.1
    User root
    IdentityFile ~/.ssh/id_ed25519_csinstall
    # Optional
    ServerAliveInterval 30


    # Für alle anderen Maschinen wiederholen
    Weitere Details findest du in der Man-Page zu ssh_config.
  • SSH-Konnektivität testen: Bevor du mit der Installation beginnst, überprüfe, ob du dich per SSH mit jedem Node verbinden kannst, indem du einfach ssh <IP-ADDRESS> ausführst, ohne Benutzer, Port oder Schlüsseldatei anzugeben. Bei der ersten Verbindung erscheint möglicherweise folgende Meldung:
    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 mit 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 Speichergerät erfolgen.
  2. Für Multi-Node: Platziere das Archiv auf dem Server, von dem aus du die Installation durchführst.
  3. Für Single-Node: Du musst dieses Archiv auf jedem an der Installation beteiligten Host hochladen und extrahieren.
  4. Entpacke das Installer-Archiv in ein Verzeichnis (z. B. /etc/codesphere). Du kannst auch das Abhängigkeitsarchiv deps.tar.gz entpacken, das später nützlich sein könnte.
    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 bei 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 stützen sich auf zwei Hauptdateien:

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

Zertifikate und Schlüssel generieren

Allgemeiner Hinweis: Verzichte darauf, neu erstellten Schlüsseln eine Passphrase hinzuzufügen.

Ceph-SSH-Schlüssel

Dieser Schlüssel ermöglicht 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 zum Ausstellen und Verwalten 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. Du kannst:

  • Eine neue selbstsignierte CA generieren (Standard, einfach für einen schnellen Einstieg)
  • Die bestehende CA oder Zwischen-CA deiner Organisation verwenden (empfohlen für die Produktion)
  • Eine externe Zertifizierungsstelle integrieren (z. B. HashiCorp Vault, AWS PCA, Let's Encrypt) für automatisiertes Zertifikatsmanagement

Die folgende Tabelle bietet eine Zusammenfassung:

OptionBeschreibung
Selbstsigniert (Standard)Generiere lokal eine neue selbstsignierte CA.
Organisations-CAVerwende die bestehende CA oder Zwischen-CA deiner Organisation, um Ingress-Zertifikate zu signieren.
Externer AusstellerIntegriere eine externe 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 Server-Schlü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.

# CSR (Certificate Signing Request) 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 bestehenden 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 vorhast, PostgreSQL mit den bereitgestellten Skripten zu installieren, musst du dafür Zertifikate generieren. Auch hierfür wird eine CA benötigt. Du kannst dieselbe CA verwenden, die für Ingress generiert wurde, oder eine dedizierte CA.

CA generieren (falls für Ingress noch nicht erfolgt): Folge den Schritten unter "Eine neue CA generieren" in Abschnitt 3.1.2, falls du eine separate CA für PostgreSQL benötigst. Angenommen, du verwendest pg_ca.key und pg_ca.pem.

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

# CSR für 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 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 nutzt 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 Custom Domains. Dafür werden Secrets aus einem privaten/öffentlichen Schlüsselpaar erstellt. Diese müssen in der prod.vault.yaml angegeben werden. Verwende zur Generierung diese 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)

Diese Datei speichert alle deine Secrets. 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 Ausschnitte -----BEGIN PRIVATE KEY----- sind nur als Platzhalter gedacht. Ersetze sie durch den Inhalt/das Format deiner generierten Dateien. Siehe OpenSSH- vs. OpenSSL-Format für Hintergrundinformationen.

# /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 bestehende CA-Key-Datei, falls für Ingress verwendet
file:
name: key.pem
# Inhalt von 'ca.key' (oder deiner bestehenden CA-Key-Datei) 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) Falls du dein Managed-Service-Backend so bereitgestellt hast, dass
# Requests via API_KEY authentifiziert werden, muss dieser API_KEY hier gesetzt werden
#- name: managedServiceSecrets
# fields:
# # JSON-Array von Objekten
# password: |-
# [
# {
# "name": "postgres", # Provider-Name
# "version": "v1" # Provider-Version
# "api": {
# "secret": "MY-API-KEY-123123"
# }
# }
# ]

# --- Externe Registry-Zugangsdaten (falls verwendet) ---
# Optional bei Nutzung eines von Codesphere verwalteten K8s, verpflichtend bei externem 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 dem Dateinamen entsprechen
# 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 von externem 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, einschließlich *_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: Git-Provider-OAuth-Zugangsdaten (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 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 (in dem sich prod.vault.yaml befindet)

# Bei Nutzung einer externen Container-Registry
# Optional bei Nutzung eines von Codesphere verwalteten K8s, verpflichtend bei externem K8s
registry:
server: "my-registry.example.com"
replaceImagesInBom: true # Optional, sollte bei Nutzung einer externen Registry auf true gesetzt werden
loadContainerImages: true # Optional, auf true setzen, falls Images aus dem Installer-Bundle geladen werden sollen


# --- PostgreSQL-Konfiguration ---
# Wähle eine Option: "Neue PostgreSQL installieren" ODER "Externes PostgreSQL verwenden"
postgres:
# Option 1: Neue PostgreSQL installieren (Passwörter & Schlüssel siehe Secrets-Datei)
# CA-Zertifikat für PostgreSQL (pg_ca.pem aus Abschnitt 3.1.3)
caCertPem: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
primary:
sslConfig:
# Primäres PostgreSQL-Server-Zertifikat (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:
# Replica-PostgreSQL-Server-Zertifikat (pg_replica.pem aus Abschnitt 3.1.3)
serverCertPem: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
# Ende von Option 1

# Option 2: Externes PostgreSQL verwenden
# caCertPem: | # CA-Zertifikat deines externen PostgreSQL-Servers (bei Nutzung von SSL)
# -----BEGIN CERTIFICATE-----
# ...
# -----END CERTIFICATE-----
# serverAddress: "your-external-postgres-host:5432"
# # Stelle sicher, dass 'postgresPassword' in 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 kein 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 (per 'hostname' überprüfen).
# Hostnamen müssen nicht auflösbar sein (DNS), werden aber von Ceph überprüft
- hostname: ceph-node-0
ipAddress: 10.50.0.2 # Ersetze durch die reale IP eines Ceph-Nodes
isMaster: true # Nur ein Master erlaubt
- hostname: ceph-node-1
ipAddress: 10.50.0.3 # Ersetze durch die reale IP eines weiteren Ceph-Nodes
isMaster: false
- hostname: ceph-node-2
ipAddress: 10.50.0.4 # Ersetze durch die reale IP eines weiteren Ceph-Nodes
isMaster: false
# OSD-(Object Storage Daemon)-Konfiguration. An deine Hardware anpassen.
# 'dataDevices' darf nicht leer sein. Syntax für 'size' und 'limit' siehe Ceph-Dokumentation.
osds:
- specId: default
placement:
host_pattern: '*' # Auf alle oben definierten Hosts anwenden
dataDevices: # Geräte zur Datenspeicherung
# Beispiel: alle verfügbaren Geräte oder Angabe nach Größe, Modell usw.
# all: true
size: '300G:' # Festplatten mit 300 GB oder mehr
limit: 2 # Bis zu 2 solche Festplatten pro Host für Daten verwenden
dbDevices: # Geräte für BlueStore-interne 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: "Neues Kubernetes installieren" ODER "Externes Kubernetes verwenden"
# kubernetes.managedByCodesphere sollte entsprechend gesetzt werden
kubernetes:
# Option 1: Neues Kubernetes installieren (mittels 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: Externes 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 prod.vault.yaml für den externen Cluster gesetzt ist
# Ende von Option 2

# --- Cluster-weite Einstellungen (gilt für installiertes und externes k8s) ---
cluster:
certificates: # CA für Dienste, auf die Codesphere-Benutzer zugreifen
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, falls externes Monitoring durch Codesphere SRE vereinbart ist
remoteWrite:
enabled: false
clusterName: my-cluster-name
gateway: # Für interne Codesphere-Dienste
serviceType: "LoadBalancer" # oder "ExternalIP"
# annotations: # Optional: für Cloud-Provider-spezifische 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, wenn 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, wenn serviceType "ExternalIP" ist
- 10.52.0.2 # Beispiel-IP
- 10.52.0.3 # Beispiel-IP
metallb:
# Dies ist der Hauptschalter, um die MetalLB-Integration zu aktivieren oder zu deaktivieren.
# Auf 'true' setzen, damit MetalLB installiert und konfiguriert wird.
enabled: true

# Definiert eine Liste von IP-Adresspools, die MetalLB verwenden kann. Ein Dienst
# erhält eine IP aus einem Pool, der entweder per L2 oder BGP angekündigt wird.
pools:
- # Ein eindeutiger Name zur Identifizierung 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-Dienste verfügbar sind.
ipAddresses:
- "10.10.10.100-10.10.10.200" # Ein IP-Bereich für allgemeine Dienste.
- "192.168.5.0/24" # Ein CIDR-Block für einen anderen Satz von Diensten.

- # Du kannst mehrere Pools für unterschiedliche Zwecke definieren.
name: "special-services-pool"
ipAddresses:
- "172.17.15.1-172.17.15.10" # Ein kleinerer, dedizierter Bereich für bestimmte Dienste.

# (Optional) Konfiguriert Layer-2-Advertisement. Im L2-Modus kündigt ein Node im
# Cluster die Dienst-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 diese L2-Konfiguration ankündigen soll.
# Dies verknüpft den L2-Mechanismus mit den im Abschnitt 'pools' definierten IPs.
pools:
- "default-pool"
# (Optional) Schränkt ein, welche Nodes die IPs für diese L2-Konfiguration ankündigen dürfen.
# Ist dies nicht definiert, sind alle Nodes im Cluster dazu berechtigt.
nodeSelectors:
- matchLabels:
# Dieser Selektor stellt sicher, dass nur Nodes mit dem Label 'role' gleich 'frontend'
# IPs aus dem 'default-pool' per L2 ankündigen.
'role': 'frontend'

# (Optional) Konfiguriert BGP-(Border Gateway Protocol)-Advertisement. Im BGP-Modus
# peeren Nodes mit deinen Netzwerk-Routern, um Routen für die Dienst-IPs anzukündigen.
bgp:
- # Ein eindeutiger Name für diese BGP-Advertisement-Konfiguration.
name: "main-bgp-advertisement"
# Legt fest, welche IP-Adresspools diese BGP-Konfiguration ankündigen soll.
# 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, zu dem eine Verbindung aufgebaut werden soll.
peerAddress: "192.168.1.1"
# (Optional) Der Name eines BFD-Profils für schnelle Fehlererkennung.
# Dies müsste separat in der nativen Konfiguration von MetalLB eingerichtet werden.
bfdProfile: "fast-detection"
# (Optional) Schränkt ein, 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'
# gleich 'edge-node-01' mit 192.168.1.1 peeren.
'kubernetes.io/hostname': 'edge-node-01'

# --- Konfiguration der Codesphere-Anwendung ---
codesphere:
domain: "codesphere.yourcompany.com" # Hauptdomain für die Codesphere-UI/API
workspaceHostingBaseDomain: "ws.yourcompany.com" # Basisdomain für Workspaces (*.ws.yourcompany.com sollte auf publicGateway-IPs zeigen)
# Eine primäre öffentliche IP für Workspaces (verwende eine aus publicGateway). Falls von einem LoadBalancer
# zugewiesen und noch nicht bekannt, leer lassen und später hinzufügen, sobald bekannt.
publicIp: "10.52.0.2"
customDomains:
cNameBaseDomain: "custom.yourcompany.com" # Für Custom-Domain-CNAMEs
dnsServers: [] # z. B. ["1.1.1.1", "8.8.8.8"] IP-Adressen von DNS-Servern zur Auflösung von Custom Domains
# Liste experimenteller oder Vorschau-Flags, die aktiviert werden sollen. Verfügbare Flags siehe [Feature-Flags-Dokumentation](./feature-flags.mdx).
# Mit Vorsicht verwenden — diese Flags können instabil sein oder in zukünftigen Releases entfernt werden.
experiments: []
# Map langlebiger Feature-Flags. Details siehe [Feature-Flags-Dokumentation](./feature-flags.mdx).
features:
standalone-teams: false # Auf false setzen, um eine strikte Organisationshierarchie zu erzwingen
# email-signup: true
# email-signin: true
# billing: false
extraCaPem: "" # Optional: PEM einer zusätzlichen benutzerdefinierten Root-CA, der die 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 Workspace -> IP-Adress-Zuweisung verfügbar sein sollen
# ipService:
# loadBalancerKind: metallb
# addressPools:
# - "internal-pool"
# Standard-Workspace-Images überschreiben. Kann nötig sein, wenn eigene 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'
# Falls hier mehrere Images angegeben sind: Welches Image soll standardmäßig verwendet werden, wenn der Benutzer keines angibt
default: true
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 vorab bereitgehaltenen (warmen) Instanzen im Pool
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 # Verweis auf eine ID aus hostingPlans
maxReplicas: 3 # Maximale gleichzeitige Replikate für einen Workspace
onDemand: true # On-Demand (Start/Stopp) für Workspaces erlauben
# Optional, die tatsächlich angeforderten Ressourcen sind niedriger als im Plan definiert
# um diesen Faktor, zur besseren Auslastung. Standardwerte 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 Self-Hosted: "https://your-gitlab.example.com"
api:
baseUrl: "https://gitlab.com" # Für Self-Hosted 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" # 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:
# Managed-Service-Provider werden in diesem Abschnitt konfiguriert.
# Detaillierte Konfigurationsoptionen siehe Anhang
# - name: postgres
# version: # ...

# (Optional) Falls mehrere Cluster dieselbe Masterdata-Datenbank teilen,
# setze diese Scope-Variable, um Konflikte bei der Reconciliation zu vermeiden.
# managedServiceScope: production-cluster-1

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

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

Denke daran, die Platzhalterwerte durch deine tatsächliche Konfiguration zu ersetzen. Für detaillierte Informationen zur Konfiguration von plans und gitProviders (einschließlich der Generierung von OAuth-Zugangsdaten) siehe die entsprechenden Abschnitte am Ende dieser Anleitung oder den ursprünglichen Anhang.

Organisationen: Konfiguration der Team-Strenge (standalone-teams)

Bei Private-Cloud-Deployments wird das Organisationen-Feature über Konfigurationsflags in der config.yaml verwaltet. Administratoren haben die volle Kontrolle darüber, wie strikt Teams an eine Organisation gebunden sein müssen.

Du kannst entscheiden, ob Teams verpflichtend zu einer Organisation gehören müssen. Dieses Verhalten wird über das Feature-Flag standalone-teams unter codesphere.features gesteuert, wodurch du die organisatorische Governance schrittweise einführen oder je nach internen Anforderungen strikte Compliance-Regeln erzwingen kannst.

Flexibler Modus (Flag auf true gesetzt):

Wenn du das Feature standalone-teams aktivierst, erlaubt das System einen hybriden Ansatz:

  • Benutzer können Teams erstellen, die formal an eine Organisation angebunden sind.
  • Entscheidend ist, dass Benutzer außerdem unabhängige, "frei schwebende" Teams erstellen dürfen, die nicht mit einer Organisation verknüpft sind.

Strikter Modus (Flag auf false gesetzt oder ausgelassen):

Wenn das Flag standalone-teams deaktiviert ist, erzwingt die Plattform eine strikte organisatorische Governance:

  • Verpflichtende Zuordnung: Jedes neue Team muss innerhalb einer Organisation erstellt werden und zu ihr gehören. Es ist nicht möglich, ein unabhängiges Team zu erstellen.
  • Mitgliedschaftsprüfung: Ein Benutzer darf nur ein Team erstellen, wenn er bereits als Mitglied der übergeordneten Organisation anerkannt ist.

Best Practice

Für eine echte, einheitliche Governance und zur Vorbereitung auf kommende Verwaltungsfunktionen empfehlen wir, das Flag standalone-teams deaktiviert zu lassen (oder auszulassen). Dies erzwingt eine strikte "Organisation-first"-Hierarchie und verhindert die Entstehung untracker administrativer Inseln.

SOPS-Secrets-Manager initialisieren (dateibasiert)

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

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

  1. Stelle sicher, dass sich in der prod.vault.yaml keine Kommentare befinden. Dies ist notwendig, da SOPS Kommentare nicht ignoriert und diese die Dateistruktur der verschlüsselten Version verändern.
  2. Verschlüssele prod.vault.yaml auf deiner lokalen Maschine
  3. Speichere nur die verschlüsselte Variante von prod.vault.yaml auf jeder entfernten Maschine
  4. Kopiere den Entschlüsselungsschlüssel dort, wo nötig, vorübergehend auf die entfernte Maschine
  5. Alternativ kannst du SSH-Portweiterleitung nutzen, damit SOPS über HTTP auf den Entschlüsselungsschlüssel zugreifen kann (fortgeschritten, siehe 3.5)

Gehe dabei wie folgt vor:

  1. Installiere SOPS und Age auf deiner lokalen Maschine, z. B. unter 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... identifiziert. Bewahre diesen äußerst sicher auf.
  3. Verschlüssele die Secrets-Datei (prod.vault.yaml) lokal mit dem Age-Schlüsselpaar:
    # Ö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 entfernten Nodes (Multi-Node-Installer: nur auf dem Setup-Node erforderlich). Du kannst das Installer-Skript nutzen, um SOPS als Komponente zu installieren. Dazu muss zuerst deps.tar.gz entpackt werden, falls noch nicht erfolgt. Führe dann 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 später zu bearbeiten:

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

Dadurch wird die entschlüsselte Datei in deinem Standardeditor geöffnet. Speichern und schließen führt zur erneuten Verschlüsselung.

warnung

Falls du Änderungen an der prod.vault.yaml vornehmen musst, nachdem der Installer bereits einmal ausgeführt wurde, wende die Änderungen bitte direkt an der Datei auf der Setup-Maschine an. Grund: Die Installationsschritte fügen zur Laufzeit selbst generierte Secrets hinzu, d. h. die Datei wird verändert.

Sicherheitsüberlegungen für den 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 entfernten 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 du den Schlüssel unbedingt auf einem Server verwenden musst (z. B. während der Single-Node-Komponenteninstallation), übertrage ihn sicher und entferne ihn unmittelbar nach Gebrauch, oder nutze SSH-Portweiterleitung für vorübergehenden Zugriff, falls SOPS entfernte Schlüsseldateien via HTTP unterstützt (fortgeschritten).

Um die Secrets-Datei zu entschlüsseln, 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 (wo sich age_key.txt befindet):
cd /path/to/keypair_directory
python3 -m http.server 8000
  1. Von deiner lokalen Maschine per SSH zum entfernten Server verbinden, dabei den Port weiterleiten:
ssh -L 9000:localhost:8000 user@remote-host
  1. Auf dem entfernten Server:
export SOPS_AGE_KEY_FILE_URL=http://localhost:9000/age_key.txt
sops --decrypt /home/<myuser>/secrets/prod.vault.yaml

Diese HTTP-Methode ist für vorübergehenden Zugriff gedacht und sollte mit Vorsicht verwendet werden. Bevorzuge, wenn möglich, die direkte Angabe des Pfads zur Schlüsseldatei.

Multi-Node-Installationsanleitung

Dieser Installer nutzt SSH, um von einer zentralen Setup-Maschine aus eine Verbindung zu den verschiedenen Hosts aufzubauen und die Komponenten der Reihe nach zu installieren.

Voraussetzungen (Zusammenfassung & Besonderheiten)

  • Alle globalen Voraussetzungen (Abschnitt 2) sind erfüllt.
  • Installer-Maschine: OpenSSH-Client, scp, Node.js v22 (im Installer enthalten).
  • 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 befinden sich 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 für die Image-Verteilung

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

Bei Nutzung einer externen Container-Registry lädt der Installer alle Images aus dem Archiv deps.tar.gz und pusht sie vom Management-Node aus in die Registry. Dazu müssen registry.server in config.yaml sowie registryUsername und registryPassword in prod.vault.yaml korrekt ausgefüllt sein. Die angegebene Registry muss für alle Nodes erreichbar sein.

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

Synchronisierung 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 unter /etc/codesphere/. Der Multi-Node-Installer ändert vor dem Upload zu den Ziel-Nodes automatisch den Wert von secrets.baseDir in config.yaml.

Vorinstallationsschritte auf 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 auf der Festplatte sdx. Überprüfe die Festplattenkennung 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 Ziel-Festplatte, 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 Uhrzeiten

Stelle sicher, dass die Uhrzeit 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.

Installation durchführen

Führe das Hauptinstallerskript von deiner zentralen Setup-Maschine aus. Dieser Befehl installiert alle Komponenten, die in deiner config.yaml definiert sind.

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, Codesphere und schließlich MsBackends (falls Managed-Service-Backends konfiguriert sind).

Verfügbare Flags:

FlagBeschreibung
--archivePfad zur Datei deps.tar.gz. Erforderlich.
--configPfad zur Datei config.yaml. Erforderlich.
--privKeyPfad zur Age-Private-Key-Datei zur Entschlüsselung der Secrets. Erforderlich.
--skipStepEinen bestimmten Installationsschritt überspringen (mehrfach wiederholbar). Gültige Werte siehe Bestimmte Installationsschritte überspringen.
--directConnectionDirekt mit jedem Node verbinden, anstatt über den ersten Node als Jump-Host zu routen. Erfordert, dass alle Nodes von der Installer-Maschine aus erreichbar sind.
--codesphereOnlyNur die Codesphere-Komponente (neu) installieren, alle Infrastrukturschritte werden übersprungen. Nützlich zum Aktualisieren einer bestehenden Installation.

tipp

Du kannst --skipStep=load-container-images --skipStep=extract-dependencies hinzufügen, um Zeit zu sparen, wenn du den Installer aufgrund eines Fehlers ein zweites Mal ausführst und diese Schritte bereits abgeschlossen waren (siehe Bestimmte Installationsschritte überspringen unten für die vollständige Liste).

Nachinstallation und Fehlerbehebung

Ceph-Besonderheiten

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

  • Ceph-Fehlerbehebung: Wenn 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

Wird der Status nach manuellen Überprüfungen oder Korrekturen wieder gesund, kannst du möglicherweise den Installer neu starten, oder er setzt an der letzten Stelle fort (das Verhalten hängt von der Idempotenz des Installers für Ceph ab).

  • Debugging des Ceph-Managers (mgr):
# Auf einem Ceph-Node, auf dem ein Manager läuft
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 die laufenden Docker-Container auf, um OSDs zu sehen:
# Auf einem Ceph-OSD-Node
sudo docker ps | grep ceph-osd
  • Logs eines bestimmten OSD-Containers prüfen:
sudo docker logs <container_id_or_name_of_osd>

Bestimmte Installationsschritte überspringen

warnung

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

In bestimmten Fällen, z. B. beim Korrigieren eines Fehlers in der config.yaml oder beim Ändern eines Secrets, können einige zeitintensive Installationsschritte übersprungen werden. Das Flag --skipStep kann für mehrere Schritte wiederholt werden.

Verfügbare überspringbare Schritte:

SchrittBeschreibung
copy-dependenciesKopieren des Deps-Archivs auf die Ziel-Nodes überspringen.
extract-dependenciesEntpacken des Deps-Archivs auf den Ziel-Nodes überspringen.
load-container-imagesLaden der Container-Images aus dem Archiv überspringen.
sopsInstallation der SOPS-Binärdatei überspringen.
dockerInstallation von Docker überspringen.
postgresInstallation von PostgreSQL überspringen.
cephInstallation von Ceph überspringen.
kubernetesInstallation von Kubernetes (k0s) überspringen.
set-up-clusterDen Cluster-Setup-Schritt überspringen.
codesphereDas Deployment der Codesphere-Anwendung überspringen.
ms-backendsDas Deployment von Managed-Service-Backends überspringen.

Ein oder mehrere zu überspringende Schritte können über das Flag --skipStep von private-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

Single-Node-Installationsanleitung

Diese Methode beinhaltet das manuelle Ausführen von Installationsbefehlen für jede Komponente auf den jeweiligen Ziel-Hosts. Du musst die Abhängigkeiten und Konfigurationsdateien auf jeden Host kopieren.

Voraussetzungen (Zusammenfassung & Besonderheiten)

  • 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 wirst dich per SSH mit jedem Node verbinden, um Befehle auszuführen. Befehle erfordern in der Regel root oder sudo.
  • Abhängigkeiten: deps.tar.gz muss auf jeden Host hochgeladen und entpackt 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 eine Secrets-Entschlüsselung erfordern (z. B. auf dem Control-Plane-Node für die meisten Schritte).

Umgebung auf jedem Host einrichten

  1. Abhängigkeiten hochladen und entpacken: Für jeden Host (PostgreSQL-, Ceph-, Kubernetes-Nodes):
# Von deiner Management-Maschine aus
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 sich install-components.js innerhalb von ./installer/files/ im entpackten Verzeichnis befindet)

  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/. Mache außerdem die age_key.txt sicher zugänglich, falls sie für die Entschlüsselung auf diesem Host benötigt wird.

# Von deiner Management-Maschine aus
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 die Pfade in config.yaml (secrets.baseDir) entsprechend an, falls nicht /root/secrets verwendet wird.

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

Schrittweise Komponenteninstallation

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

Container-Engine einrichten (Docker)

Führe dies auf jedem Host aus (Ceph, Kubernetes, jeder Node, der Container für Codesphere-Komponenten ausführt, falls nicht alles über K8s läuft). Das Dateisystem unter /var/lib/docker (oder entsprechend 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 (primär 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

Überprüfen: sudo docker info und sudo docker image ls.

PostgreSQL installieren (falls kein externes verwendet wird)

A. Primären PostgreSQL-Node installieren: Per SSH mit dem festgelegten primären PostgreSQL-Server (gemäß deiner config.yaml) verbinden.

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

Überprüfen: sudo systemctl status codesphere-postgres.service

B. Replica-PostgreSQL-Node(s) installieren: Per SSH mit dem/den festgelegten Replica-PostgreSQL-Server(n) verbinden.

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

Überprü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 sauber gewischt sind.
  • Synchronisierte Uhrzeiten: (Abschnitt 4.3.3) Stelle sicher, dass die Uhrzeit auf allen Ceph-Nodes synchronisiert ist.

B. Ceph installieren: Führe den Befehl zunächst auf allen Nicht-Master-Ceph-Nodes und anschließend abschließend auf dem Ceph-Master-Node aus (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: Fehlerbehebungsbefehle für Ceph siehe Abschnitt 4.5.1.

Kubernetes installieren (k0s)

A. Control-Plane-Node(s) installieren: Per SSH mit dem/den festgelegten Kubernetes-Control-Plane-Node(s) verbinden.

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, hole 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: Per SSH mit jedem festgelegten Kubernetes-Worker-Node verbinden. Dieser Schritt ist nicht erforderlich, wenn ein Node sowohl Control-Plane als auch Worker ist (Single-Node-K8s-Setup oder gemeinsam ausgeführte 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üfen von einem Control-Plane-Node aus:

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

Hinweis: Control-Plane-Nodes werden in kubectl get nodes möglicherweise nicht als "Nodes" angezeigt, wenn sie nicht auch als Worker markiert sind oder wenn sie ausschließlich Master sind.

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-Error-Page-Server erstellen (vorübergehend): 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 neuesten 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. Dies setzt Nodes vorübergehend auf 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 werden (ca. 5 Minuten). Überprü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-Error-Page-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. Managed-Service-Backends installieren (falls konfiguriert): Falls du managedServiceBackends in deiner config.yaml konfiguriert hast, führe aus:
sudo ./installer/files/node ./installer/files/install-components.js \
--dependenciesDir=. \
--config=/root/secrets/config.yaml \
--privKey=/root/secrets/age_key.txt \
--component=msBackends
  1. Deine Codesphere-Installation ist nun abgeschlossen. Rufe sie über die in codesphere.domain in deiner config.yaml angegebene Domain auf.

Anhang

Konfiguration der Codesphere-Pläne

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

  • hostingPlans: Definiert die rohen Ressourcenzuteilungen. IDs müssen Zahlen sein.
    • cpuTenth: CPU-Kerne in Zehnteln (z. B. 10 = 1 Kern, 25 = 2,5 Kerne).
    • gpuParts: GPU-Zuteilung (spezifisch für dein GPU-Setup).
    • memoryMb: Speicher in Megabyte.
    • storageMb: Persistenter Speicher für den Workspace in Megabyte.
    • tempStorageMb: Flüchtiger Speicher in Megabyte.
    • pooledInstances: Anzahl der vorab bereitgehaltenen Instanzen dieses Plans, die einsatzbereit gehalten werden.
  • workspacePlans: Definiert für 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 laufend.

Beispiel: (Bereits im Haupt-config.yaml-Beispiel 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

Git-Provider-Konfiguration

Konfiguriere Git-Provider-Integrationen unter codesphere.gitProviders in config.yaml. Für jeden aktivierten Provider musst du außerdem die entsprechenden clientId und clientSecret in deiner Secrets-Datei prod.vault.yaml hinzufügen (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

Zugangsdaten generieren (Beispiele):

  • GitLab:

    1. Gehe zu deiner GitLab-Gruppe (oder den Benutzereinstellungen für eine benutzerbasierte App) > Settings > Applications.
    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 für Benutzerprofilinformationen benötigt).
    5. Speichere die Anwendung. Du erhältst eine "Application ID" (gitlabAppClientId) und ein "Secret" (gitlabAppClientSecret).
  • GitHub:

    1. Gehe zu den Einstellungen deiner GitHub-Organisation > Developer settings > GitHub Apps > New GitHub App.
    2. Application name: z. B. "Codesphere Git Integration"
    3. Homepage URL: https://<your-codesphere.domain>
    4. Authorization callback URL: https://<your-codesphere.domain>/ide/auth/github/callback
    5. Du erhältst eine "Client ID" (githubAppsClientId) und generierst ein "Client Secret" (githubAppsClientSecret).
    6. Optional kannst du ein Bild als Logo hochladen.
  • Bitbucket (Server/Data Center – in der Regel Application Links für OAuth 1.0a oder OAuth 2.0, falls unterstützt):

    1. Admin Settings > 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 Lesen/Schreiben.
    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. Stelle eine Erinnerung ein, um dieses Secret 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 zu deiner prod.vault.yaml-Datei hinzuzufügen und sie zu verschlüsseln. Beispiele für Secret-Namen:

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

Konfiguration der Managed Services

Jeder Dienst, der über den Bereich Managed Services angeboten wird, 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. In der aktuellen Version gibt es 1 solchen Provider für PostgreSQL.

Codesphere wird mit einer Reihe vorkonfigurierter Provider geliefert. Wenn du einen dieser Provider aktivieren möchtest, gib einfach Name und Version an:

managedServices:
- name: postgres
schemaVersion: v1
- name: babelfish
schemaVersion: v1
- name: s3
schemaVersion: v1
- name: virtualK8sV1
schemaVersion: v1

Wenn du einen dieser Provider verwendest, stelle sicher, dass du auch das entsprechende Backend im Abschnitt managedServiceBackends aktivierst.

Es ist möglich, Eigenschaften der vorkonfigurierten Provider zu überschreiben oder sogar eigene Provider zu implementieren und hinzuzufügen (siehe Eigenes REST-Backend erstellen). Der folgende Ausschnitt zeigt eine beispielhafte vollständige Konfiguration des Postgres-Managed-Service-Providers.

managedServices:
- name: postgres
schemaVersion: 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 Erweiterungen, die mit dieser Version kompatibel sind. Erweiterungsversionen 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, das auf effizientes Datenmanagement und
Skalierbarkeit ausgelegt ist. Wird auf Codesphere über den 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

Eigene Workspace-Basis-Images erstellen

Das Standard-Basis-Image für Workspaces bringt bereits viele nützliche Tools und Bibliotheken mit. Du kannst jedoch eigene benutzerdefinierte Basis-Images erstellen. Ein Grund für die Anpassung von Basis-Images sind Pakete, die nicht über Nix verfügbar sind, sondern über apt installiert werden müssen.

Das OMS CLI von Codesphere bietet eine bequeme Möglichkeit, mit dem Erstellen eigener benutzerdefinierter Basis-Images zu beginnen.

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 eigenen Abhängigkeiten hinzuzufügen.
  7. Als Best Practice solltest du das Dockerfile in ein Unterverzeichnis legen, z. B. ./docker. Dies stellt sicher, dass beim folgenden Docker-Build-Befehl nur die notwendigen Dateien an den Docker-Daemon gesendet werden.
  8. Ermittle das Basis-Image-Tag aus dem Dockerfile, z. B. codesphere-1-67-1-4dd9b346cc, und verwende denselben Tag für dein eigenes 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 angemeldet
    docker push <YOUR_REGISTRY_URL>/workspace-agent-24.04-mycorp:<TAG_TO_USE>

warnung

Der Image-Name kann frei gewählt werden, überprüfe jedoch sorgfältig, dass der Tag deines benutzerdefinierten Images exakt mit dem Tag des ursprünglichen Basis-Images übereinstimmt. Stimmen die Tags nicht überein, kann Codesphere derzeit dein benutzerdefiniertes Image beim Starten von Workspaces nicht finden.