Zum Hauptinhalt springen
Version: 1.89.x (Q2 26)

Installationsanleitung

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

Dieses Dokument behandelt 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 Komponenten nacheinander installiert. Sie ist dafür konzipiert, ein komplettes Codesphere-Rechenzentrum von Grund auf (Bare Metal, VMs) zu provisionieren oder bestehende 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 mithilfe eines Helm-Charts bereitgestellt. Für kritische Infrastrukturkomponenten wie PostgreSQL und Ceph (für verteilten, hochverfügbaren Storage) empfehlen wir jedoch, diese als robuste, externe Services aufzusetzen, statt sie in das Helm-Chart einzubetten. Dieser Ansatz sorgt für eine stabilere und widerstandsfähigere Umgebung.

Diese Installer sind modulare Werkzeuge, mit denen du:

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

Zentrale Installer-Komponenten

Der Installationsprozess umfasst mehrere Schlüsselkomponenten:

KomponentennameBeschreibung
SecretsVerwaltet sensible Daten mithilfe von Age und Sops-Schlüsseldateien.
DockerContainer-Runtime für die Bereitstellung der Codesphere-Services.
PostgreSQLDie primäre Datenbank für Codesphere.
CephVerteilte Storage-Lösung für Hochverfügbarkeit.
KubernetesPlattform zur Container-Orchestrierung.
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 (bei 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 Storage sollte schnell sein (z. B. SSD/NVMe) und mindestens 4 % der gesamten Block-Storage-Kapazität ausmachen. Muss vollständig leer sein (kein Dateisystem).
    • 1 oder mehrere Festplatten mit jeweils mindestens 300 GB für Ceph-Block-Storage (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-Storage).
    • 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 Softwarepakete

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 ausgeliefert)
  • 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 remote Ziel-Maschinen (PostgreSQL-, Ceph-, Kubernetes-Nodes) haben.
  • 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 und kein Nutzername erforderlich sein.
  • Um ein passwortloses Login zu ermöglichen, konfiguriere ein Public-Key-Paar 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 Public Key (*.pub) in /root/.ssh/authorized_keys auf allen VMs
    ssh-copy-id -i ~/.ssh/id_ed25519_csinstall root@host
  • Der Nutzer auf den Remote-Maschinen MUSS derzeit root sein.
  • Du kannst den SSH-Zugriff für verschiedene Hosts über deine SSH-Konfigurationsdatei (z. B. ~/.ssh/config) einrichten. 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 ssh_config-Manpage.
  • SSH-Verbindung testen: Bevor du mit der Installation beginnst, prüfe, ob du dich per SSH mit jedem Node verbinden kannst, indem du einfach ssh <IP-ADDRESS> ausführst, ohne Nutzer, Port oder Key-Datei anzugeben. Die erste Verbindung könnte folgende Meldung anzeigen:
    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 Speichergerät 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: Du musst dieses Archiv auf jedem Host, der an der Installation beteiligt ist, hochladen und entpacken.
  4. Entpacke das Installer-Archiv in ein Verzeichnis (z. B. /etc/codesphere). Du kannst außerdem das Abhängigkeiten-Archiv deps.tar.gz entpacken, 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 Installer-Methoden 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 erzeugen

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

Ceph SSH-Schlüssel

Dieser Schlüssel ermöglicht es cephadm, Ceph-Nodes zu bootstrappen und zu verwalten. Erzeuge 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 Nutzer, die auf Codesphere zugreifen, müssen dieser CA vertrauen. Du kannst:

  • Eine neue, selbstsignierte CA erzeugen (Standard, einfach für einen schnellen Start)
  • Die bestehende CA oder Intermediate-CA deiner Organisation verwenden (empfohlen für den Produktivbetrieb)
  • Eine externe Zertifizierungsstelle integrieren (z. B. HashiCorp Vault, AWS PCA, Let's Encrypt) für automatisierte Zertifikatsverwaltung

Eine Übersicht findest du in der folgenden Tabelle:

OptionBeschreibung
Selbstsigniert (Standard)Erzeugt lokal eine neue selbstsignierte CA.
Organisations-CANutzt die bestehende CA oder Intermediate-CA deiner Organisation zur Signierung von Ingress-Zertifikaten.
Externer AusstellerIntegriert eine externe Zertifizierungsstelle (z. B. Vault, AWS PCA, Let's Encrypt).

Details zur Konfiguration und Beispiele findest du unter Optionen für die Cluster-Ingress-CA.

(Optional): Eine neue CA erzeugen

Ersetze MyOrg, DE, KA durch die Angaben deiner Organisation.

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

# CA-Zertifikat erzeugen
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.

# 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'

# Den 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

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

PostgreSQL-Zertifikate (falls PostgreSQL installiert wird)

Wenn du planst, PostgreSQL mit den bereitgestellten Skripten zu installieren, musst du dafür Zertifikate erzeugen. Dies erfordert ebenfalls eine CA. Du kannst dafür die gleiche CA verwenden, die für Ingress erzeugt wurde, oder eine dedizierte.

CA erzeugen (falls für Ingress noch nicht erfolgt): Folge den Schritten unter „Eine neue CA erzeugen“ in Abschnitt 3.1.2, wenn du eine separate CA für PostgreSQL benötigst. Wir gehen davon aus, dass du pg_ca.key und pg_ca.pem verwendest.

Primäres PostgreSQL-Server-Zertifikat erzeugen: 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 einen anderen beschreibenden 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 erzeugen: 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-Nutzer erzeugen

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

openssl rand -base64 16

Domain-Auth-Schlüssel erzeugen

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. Nutze folgende Befehle zur Erzeugung:

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 Nutzer 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 als Platzhalter gedacht. Ersetze sie durch den Inhalt/das Format deiner erzeugten Dateien. Hintergrundinformationen findest du unter OpenSSH- vs. OpenSSL-Format.

# /home/<myuser>/secrets/prod.vault.yaml
secrets:
# --- Gemeinsame Secrets ---
- name: cephSshPrivateKey
file:
# Inhalt von 'ceph_id_rsa' aus 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 dein bestehender CA-Schlüssel, falls für Ingress verwendet
file:
name: key.pem
# Inhalt von 'ca.key' (oder deinem bestehenden 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 du dein Managed Services-Backend so bereitgestellt hast, dass
# Requests mit einem API_KEY authentifiziert werden, musst du diesen API_KEY hier setzen
#- name: managedServiceSecrets
# fields:
# # JSON-Array von Objekten
# password: |-
# [
# {
# "name": "postgres", # Anbietername
# "version": "v1" # Anbieterversion
# "api": {
# "secret": "MY-API-KEY-123123"
# }
# }
# ]

# --- Zugangsdaten für externe Registry (falls verwendet) ---
# Optional bei einem von Codesphere verwalteten K8s, verpflichtend bei einem externen K8s
- name: registryUsername
fields:
password: 'YOUR_REGISTRY_USERNAME'
- name: registryPassword
fields:
password: 'YOUR_REGISTRY_PASSWORD'

# --- Optional: Bei Installation von PostgreSQL ---
- name: postgresPassword
fields:
# Erzeuge ein starkes primäres Admin-Passwort (z. B. 25 Zeichen)
password: 'YOUR_POSTGRES_ADMIN_PASSWORD'
- name: postgresReplicaPassword
fields:
# Erzeuge 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 Nutzer & Passwörter
# Nutzernamen 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-Zugangsdaten 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 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 # Die Stadt deines Rechenzentrums
countryCode: DE # Der Ländercode deines Rechenzentrums
secrets:
baseDir: /home/<myuser>/secrets/ # Pfad zu deinem Secrets-Verzeichnis (wo prod.vault.yaml liegt)

# Bei Nutzung einer externen Container-Registry
# Optional bei einem von Codesphere verwalteten K8s, verpflichtend bei einem externen 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, wenn Images aus dem Installer-Bundle geladen werden sollen


# --- PostgreSQL-Konfiguration ---
# Wähle eine Option: "Neues PostgreSQL installieren" ODER "Externes PostgreSQL verwenden"
postgres:
# Option 1: Neues PostgreSQL installieren (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:
# 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 (falls SSL verwendet wird)
# -----BEGIN CERTIFICATE-----
# ...
# -----END CERTIFICATE-----
# serverAddress: "your-external-postgres-host:5432"
# # Stelle sicher, dass 'postgresPassword' in prod.vault.yaml für den externen DB-Nutzer gesetzt ist
# Ende von Option 2

# --- Ceph-Konfiguration ---
ceph:
csiKubeletDir: /var/lib/k0s/kubelet # Optional, setzen, wenn k0s nicht verwendet wird
cephAdmSshKey:
# Öffentlicher Schlüsselteil von 'ceph_id_rsa.pub' aus 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' überprüfen).
# Hostnamen müssen nicht auflösbar (DNS) sein, werden aber von Ceph geprüft
- hostname: ceph-node-0
ipAddress: 10.50.0.2 # Ersetzen durch die reale IP eines Ceph-Nodes
isMaster: true # Nur ein Master erlaubt
- hostname: ceph-node-1
ipAddress: 10.50.0.3 # Ersetzen durch die reale IP eines weiteren Ceph-Nodes
isMaster: false
- hostname: ceph-node-2
ipAddress: 10.50.0.4 # Ersetzen durch die reale IP eines weiteren Ceph-Nodes
isMaster: false
# OSD-Konfiguration (Object Storage Daemon). 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 zum Speichern von Daten
# Beispiel: alle verfügbaren Geräte, oder nach Größe, Modell etc. angeben
# all: true
size: '300G:' # Festplatten mit 300 GB oder mehr
limit: 2 # Bis zu 2 solcher Festplatten pro Host für Daten nutzen
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 nutzen

# --- 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 (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: 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/externes k8s) ---
cluster:
certificates: # CA für von Codesphere-Nutzern aufgerufene Services
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 wurde
remoteWrite:
enabled: false
clusterName: my-cluster-name
gateway: # Für interne Codesphere-Services
serviceType: "LoadBalancer" # oder "ExternalIP"
# annotations: # Optional: für cloudanbieterspezifische 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 Nutzer-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 primäre 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 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 bestimmen, 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 einen weiteren Satz von Services.

- # 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 spezifische Services.

# (Optional) Konfiguriert Layer-2-Advertisement. 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 diese L2-Konfiguration ankündigen soll.
# 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, kommen alle Nodes im Cluster in Frage.
nodeSelectors:
- matchLabels:
# Dieser Selector stellt sicher, dass nur Nodes mit dem Label 'role' auf 'frontend'
# IPs aus dem 'default-pool' per L2 ankündigen.
'role': 'frontend'

# (Optional) Konfiguriert BGP-Advertisement (Border Gateway Protocol). Im BGP-Modus
# bilden Nodes Peerings 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 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 (deines Routers).
peerASN: 65100
# Die IP-Adresse des BGP-Peers, mit dem eine Verbindung aufgebaut wird.
peerAddress: "192.168.1.1"
# (Optional) Der Name eines BFD-Profils für schnelle Fehlererkennung.
# Dies müsste separat in der nativen MetalLB-Konfiguration eingerichtet werden.
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 Selector 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'

# --- Codesphere-Anwendungskonfiguration ---
codesphere:
domain: "codesphere.yourcompany.com" # Haupt-Domain für 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 (eine der publicGateway-IPs verwenden). Falls durch einen 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 der DNS-Server zur Auflösung von Custom Domains
experiments: [] # Liste der zu aktivierenden experimentellen Codesphere-Funktionen
features: # Map aktivierter/deaktivierter Codesphere-Funktionen. Siehe [Feature-Flags-Dokumentation](./feature-flags.mdx) für weitere Details.
standalone-teams: false # Auf false setzen, um eine strikte Organisationshierarchie durchzusetzen
# email-signup: true
# email-signin: true
# billing: false
extraCaPem: "" # Optional: PEM einer zusätzlichen, vertrauenswürdigen Root-CA für Codesphere-Services/Workspaces
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 Zuweisung von IP-Adressen zu Workspaces verfügbar sein sollen
# ipService:
# loadBalancerKind: metallb
# addressPools:
# - "internal-pool"
# Standard-Workspace-Images überschreiben. Kann bei Verwendung eigener Base-Images nötig sein
# 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 Nutzer keines angibt
default: true
flavors:
default:
# Bei Custom 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:
# Bei Standard-Base-Images: muss einem Workspace-Image in der Installer-BOM entsprechen.
# Im Zweifelsfall <deps.tar.gz>/bom.json überprüfen
bomRef: 'workspace-agent-24.04'
pool:
1: 1 # Anzahl der vorgehaltenen (warm) 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 Storage
tempStorageMb: 1024 # Temporärer Storage
workspacePlans:
1: # ID muss eine Zahl sein
name: "Standard Developer" # Anzeigename des Plans
hostingPlanId: 1 # Verweist auf eine ID aus hostingPlans
maxReplicas: 3 # Max. gleichzeitige Replicas für einen Workspace
onDemand: true # On-Demand-Workspaces (Start/Stopp) erlauben
# Optional, tatsächlich angeforderte Ressourcen liegen um diesen Faktor unter den im Plan
# definierten Werten, um die Auslastung zu verbessern. Standardwerte belassen, sofern keine besonderen Anforderungen bestehen.
# 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
# version: # ...

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

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

managedServiceBackends:
# Wenn du Provider in codesphere.managedServices konfigurierst, musst du
# in diesem Abschnitt auch die entsprechenden Backends 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 Erzeugung von OAuth-Zugangsdaten) siehe die entsprechenden Abschnitte am Ende dieser Anleitung bzw. den ursprünglichen Anhang.

Organizations: Team-Strenge konfigurieren (standalone-teams)

Bei Private-Cloud-Deployments wird das Feature Organizations über Konfigurationsflags in deiner config.yaml verwaltet. Administratoren haben volle Kontrolle darüber, wie streng Teams an eine Organization gebunden sein müssen.

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

Flexibler Modus (Flag auf true gesetzt):

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

  • Nutzer können Teams erstellen, die formal an eine Organization gebunden sind.
  • Entscheidend: Nutzer dürfen auch unabhängige, „freistehende“ Teams erstellen, die keiner Organization zugeordnet 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 Organization erstellt werden und dieser zugehören. Es ist nicht möglich, ein unabhängiges Team zu erstellen.
  • Mitgliedschaftsprüfung: Ein Nutzer darf nur dann ein Team erstellen, wenn er bereits ein anerkanntes Mitglied der übergeordneten Organization ist.

Best Practice

Für echte Unified Governance und zur Vorbereitung auf kommende Administrationsfunktionen empfehlen wir, das Flag standalone-teams deaktiviert zu lassen (oder auszulassen). Dies erzwingt eine strikte „Organization-first“-Hierarchie und verhindert die Entstehung unerfasster administrativer Inseln.

SOPS-Secret-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 keine Kommentare in prod.vault.yaml 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 einer beliebigen Remote-Maschine
  4. Kopiere den Entschlüsselungsschlüssel dort, wo es notwendig ist, temporär auf die Remote-Maschine
  5. Nutze alternativ SSH-Port-Forwarding, damit SOPS über HTTP auf den Entschlüsselungsschlüssel zugreifen kann (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. Erzeuge ein Age-Schlüsselpaar (privater + öffentlicher Schlüssel)
    age-keygen -o age_key.txt
    Dies erzeugt age_key.txt mit dem privaten und dem öffentlichen Schlüssel. Notiere den öffentlichen Schlüssel (beginnt mit age1...). Du benötigst ihn für die Verschlüsselung. Der private Schlüsselteil ist durch AGE-SECRET-KEY-1... gekennzeichnet. Bewahre diesen äußerst sicher auf.
  3. Verschlüssele die Secrets-Datei (prod.vault.yaml) lokal mithilfe des Age-Schlüsselpaars:
    # 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 entpackt 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 # Zeige auf die Datei mit deinem privaten Schlüssel
sops /home/<myuser>/secrets/prod.vault.yaml

Dies öffnet die entschlüsselte Datei in deinem Standardeditor. 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 diese 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 geändert.

Sicherheitsüberlegungen zum Age-Private-Key

  • Bewahre die age_key.txt (mit dem privaten Schlüssel) äußerst 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: Wenn du den Schlüssel unbedingt auf einem Server verwenden musst (z. B. während der Installation von Single-Node-Komponenten), übertrage ihn sicher und entferne ihn sofort nach Gebrauch, oder nutze SSH-Port-Forwarding für temporären Zugriff, falls SOPS Remote-Schlüsseldateien über 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 lokalen age_key via SSH-Port-Forwarding

  1. Auf deiner lokalen Maschine (wo sich age_key.txt befindet):
cd /path/to/keypair_directory
python3 -m http.server 8000
  1. Baue von deiner lokalen Maschine per SSH eine Verbindung zum Remote-Server auf, mit Port-Forwarding:
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. Bevorzuge, wo möglich, die direkte Angabe des Schlüsseldatei-Pfads.

Multi-Node-Installationsanleitung

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

Voraussetzungen (Zusammenfassung & Spezifika)

  • Alle globalen Voraussetzungen (Abschnitt 2) sind erfüllt.
  • Installer-Maschine: OpenSSH-Client, scp, Node.js v22 (mit dem Installer ausgeliefert).
  • 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 verschlüsselte prod.vault.yaml sind vorbereitet (Abschnitt 3, siehe auch unten).
  • Age-Private-Key: Die Datei age_key.txt ist für die Installer-Maschine zugänglich.

Optionen zur Image-Verteilung

Der Multi-Node-Installer bietet zwei unterschiedliche Optionen, um alle benötigten Container-Images an alle Ziel-Nodes zu verteilen.

Bei Verwendung einer externen Container-Registry lädt der Installer alle Images aus dem Archiv deps.tar.gz und pusht sie von der Management-Node 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 bereitgestellte Registry muss von allen Nodes aus erreichbar sein.

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

Synchronisierung von Konfigurationsdateien und Secrets

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

Vor-Installationsschritte 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 von der Festplatte sdx. Überprüfe die Festplattenbezeichnung 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. Nutze 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 durchläuft die Komponenten: 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, wenn du den Installer ein zweites Mal aufgrund eines Fehlers ausführst und diese beiden Schritte bereits abgeschlossen wurden (weitere Details unten).

Nachinstallation und Fehlerbehebung

Ceph-Spezifika

  • 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: Falls Ceph Probleme hat, kannst du dich per Shell 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 eventuell den Installer neu starten, oder er setzt dort fort, wo er aufgehört hat (Verhalten hängt von der Idempotenz des Installers für Ceph ab).

  • Debugging des Ceph-Managers (mgr):
# Auf einem Ceph-Node, der einen Manager ausführt
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 chronologisch umgekehrte Reihenfolge (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 für einen bestimmten OSD-Container prüfen:
sudo docker logs <container_id_or_name_of_osd>

Bestimmte Installationsschritte überspringen

warnung

Mit Vorsicht anwenden! --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. bei der Korrektur eines Fehlers in der config.yaml oder beim Ändern eines Secrets, können einige zeitaufwendige 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 Flag --skipStep von private-cloud-installer.js festgelegt 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 umfasst das manuelle Ausführen von Installationsbefehlen für jede Komponente auf dem jeweiligen Ziel-Host. 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 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 verschlüsselte prod.vault.yaml müssen auf jedem Host verfügbar sein, auf dem install-components.js ausgeführt wird.
  • Age-Private-Key: age_key.txt muss zugänglich sein, wenn Befehle ausgeführt werden, die eine Secret-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, typischerweise in ein Verzeichnis wie /home/<user>/secrets/ oder /root/secrets/. Stelle außerdem age_key.txt sicher zur Verfügung, falls für die Entschlüsselung auf diesem Host benötigt.

# 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 Zugriff auf den Schlüssel 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: (Siehe 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. Wechsle in das Verzeichnis, in das du die Abhängigkeiten entpackt 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, wenn nicht alles über K8s abgewickelt wird). 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

# Erforderliche 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

Prü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 verbinden (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: Per SSH mit 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

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

Ceph installieren

A. Nodes vorbereiten (Bereinigung & Synchronisierung):

  • Festplatten bereinigen: (Abschnitt 4.3.2) Stelle auf jedem Ceph-Node sicher, dass die Festplatten für OSDs vollständig leer 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 schließlich auf dem Ceph-Master-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 Befehle zur Ceph-Fehlerbehebung.

Kubernetes (k0s) installieren

A. Control-Plane-Node(s) installieren: Per SSH mit 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, ein Bootstrap-Token für Worker-Nodes abrufen:

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 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. Prü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 konfiguriert (getaintet) sind oder wenn sie ausschließlich als Master fungieren.

Anfängliche Kubernetes-Ressourcen erstellen

Führe diese 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 (temporär): Dies ist ein Platzhalter, den setUpCluster benötigt, falls bestimmte Services 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 Updates oder um die neuesten Versionen 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 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-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. Deine Codesphere-Installation sollte jetzt vollständig sein. Zugriff erfolgt über die in codesphere.domain in deiner config.yaml angegebene Domain.

Anhang

Codesphere-Plänekonfiguration

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

  • hostingPlans: Definiert Roh-Ressourcenzuweisungen. IDs müssen Zahlen sein.
    • cpuTenth: CPU-Kerne in Zehnteln (z. B. 10 = 1 Kern, 25 = 2,5 Kerne).
    • gpuParts: GPU-Zuweisung (spezifisch für dein GPU-Setup).
    • memoryMb: Speicher in Megabyte.
    • storageMb: Persistenter Storage für den Workspace in Megabyte.
    • tempStorageMb: Flüchtiger Storage in Megabyte.
    • pooledInstances: Anzahl vorgewärmter Instanzen dieses Plans, die bereitgehalten werden.
  • workspacePlans: Definiert für Nutzer auswä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 Nutzer diese Workspaces starten/stoppen können, false für dauerhaft aktive.

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

Git-Provider-Konfiguration

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

  • GitLab:

    1. Gehe zu deiner GitLab-Gruppe (oder den Nutzereinstellungen für eine App auf Nutzerebene) > 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 Nutzerprofilinformationen 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 Lese-/Schreibzugriff.
    5. Du erhältst je nach OAuth-Version einen „Consumer Key“ (bitbucketAppsClientId) und ein „Consumer Secret“ (bitbucketAppsClientSecret) oder Ähnliches.
  • 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 zu rotieren, 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

Managed-Services-Konfiguration

Jeder über den Bereich Managed Services angebotene Service 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 liefert eine Reihe vorkonfigurierter Provider mit. Wenn du einen dieser Provider aktivieren möchtest, gib einfach Name und Version an:

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

Wenn du einen dieser Provider verwendest, stelle bitte sicher, dass du das entsprechende Backend auch 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 Provider.

managedServices:
- name: postgres
version: v1
backend:
api:
endpoint: "http://ms-backend-postgres.postgres-operator:3000/api/v1/postgres"
author: Codesphere
category: Database
displayName: PostgreSQL
# Auf true setzen, um pro Team nur einen nicht gelöschten Service für diese Provider-Version zuzulassen.
# teamSingleton: true
iconUrl: /ide/assets/managed-services/postgresql.svg
configSchema:
type: object
properties:
version:
type: string
description: Version der Postgres-DB. Enthält vorinstallierte Extensions, die mit dieser Version kompatibel sind. 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, das für effizientes Datenmanagement und
Skalierbarkeit ausgelegt ist. Wird auf Codesphere mithilfe des CNPG-K8s-Operators bereitgestellt.
plans:
- id: 0
description: 0.5 vCPU / 500 MB Speicher
name: Small
parameters:
storage:
pricedAs: storage-mb
schema:
description: Storage (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: Storage (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-Base-Images erstellen

Das Standard-Base-Image für Workspaces bringt bereits viele nützliche Tools und Bibliotheken mit. Du kannst jedoch auch eigene Custom-Base-Images erstellen. Ein Grund für die Anpassung von Base-Images 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, mit dem Erstellen eigener Custom-Base-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. Nutze den Befehl extend baseimage in der OMS CLI, siehe
    oms-cli beta extend baseimage -h
  4. Dieser Befehl extrahiert das Standard-Base-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 Base-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 den Base-Image-Tag aus dem Dockerfile, z. B. codesphere-1-67-1-4dd9b346cc, und verwende denselben Tag für dein Custom-Image.
  9. Baue das Custom-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 Original-Image 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 Custom-Images exakt mit dem Tag des Original-Base-Images übereinstimmt. Wenn die Tags nicht übereinstimmen, kann Codesphere derzeit dein Custom-Image beim Starten von Workspaces nicht finden.