Zum Hauptinhalt springen
Version: Weekly Build

Mehrere Rechenzentren: Konfiguration

Bevor du beginnst

Eine Codesphere-Installation kann mehrere Rechenzentren umfassen. Sie teilen sich einen PostgreSQL-Server, eine Plattform-Domain und eine OpenFGA-Instanz; jedes Rechenzentrum betreibt sein eigenes Kubernetes-Cluster und sein eigenes Ceph-Cluster.

Diese Seite behandelt nur die Unterschiede zu einer Installation mit einem einzelnen Rechenzentrum, den grundlegenden Ablauf beschreibt der Installationsleitfaden. Für das Vorgehen siehe Mehrere Rechenzentren: Installation.

Jedes Rechenzentrum hat seine eigene config.yaml und seine eigene prod.vault.yaml. Nichts führt sie zusammen: jeder oms install codesphere-Lauf installiert genau ein Rechenzentrum.

codesphere.domain = cs.example.com
|
+---------------+---------------+
| |
Data center 1 Data center 2
k0s + Ceph cluster A k0s + Ceph cluster B
jumpbox 1 jumpbox 2
config.yaml + its vault config.yaml + its vault
| |
+---------------+---------------+
|
one PostgreSQL server, one OpenFGA

Jedes Rechenzentrum wird normalerweise von seiner eigenen Jumpbox aus betrieben, deshalb sind die Dateinamen unten auf jeder Maschine dieselben. Eine einzelne Jumpbox für die gesamte Installation funktioniert ebenfalls, dann muss jeder rechenzentrumsspezifische Pfad eindeutig gemacht werden, siehe Die Dateien anlegen.

Was geteilt wird

Komponenten

  • Der PostgreSQL-Server mit der Codesphere-Datenbank — ihren Rollen, ihrem Schema und jeder Workspace-, Team- und Nutzerzeile. Ein Rechenzentrum installiert und betreibt ihn; jedes andere verbindet sich als externe Datenbank mit ihm.
  • Die OpenFGA-Instanz mit den Autorisierungs-Tupeln, zusammen mit der CloudNativePG-Datenbank, die sie mitbringt. Ein Rechenzentrum deployt sie und veröffentlicht sie über sein Gateway; jedes andere ruft diese URL auf.

Gemeinsame Konfiguration

Identisch in der config.yaml jedes Rechenzentrums:

  • codesphere.domain — ein Plattform-Name für die gesamte Installation.
  • dataCenters und defaultDataCenterId — die Topologie, die jedes Rechenzentrum kennen muss.
  • codesphere.plans, deployConfig, features, internal, preview, gitProviders, oauth, managedServices — Plattformverhalten, das von der geteilten Datenbank getragen wird.
  • registry — jedes Rechenzentrum zieht dieselben Images aus derselben Registry.

Und identisch in der prod.vault.yaml jedes Rechenzentrums: die Authentifizierungs- und Verschlüsselungsschlüssel, die Registry-Zugangsdaten und die Rollen der geteilten Datenbank — jedes Secret, das am anderen Ende von etwas Geteiltem verbraucht wird. tokenPrivateKey erzeugt die Sitzungen, die Rechenzentrumsgrenzen überschreiten, mounterHmacSecret und mongoDbPasswordEncryptionKey signieren und verschlüsseln Zeilen in der geteilten Datenbank, openFgaPresharedKey authentifiziert gegenüber der einen OpenFGA-Instanz, und jedes Paar aus postgresUser* / postgresPassword* ist eine Rolle auf dem einen Server.

warnung

Geteilte Werte lassen sich leicht in einer Konfiguration ändern und in der anderen vergessen. Ein auseinandergelaufener plans-Block ist ein Workspace, der sich im einen Rechenzentrum anlegen lässt und im anderen nicht, lange nach der Installation; ein auseinandergelaufener tokenPrivateKey ist eine Nutzerin, die im einen Rechenzentrum angemeldet ist und vom nächsten abgewiesen wird.

Was jedem Rechenzentrum gehört

Komponenten

Sein eigenes k0s-Cluster, sein eigenes Ceph-Cluster und seine eigenen drei extern erreichbaren Adressen — Plattform-Gateway, Workspace-Gateway und Workspace-SSH-Proxy. Nichts davon wird geteilt, und nichts in der Konfiguration eines Rechenzentrums darf auf die Hosts eines anderen zeigen.

Gemeinsame Konfiguration

  • dataCenter — die Identität dieses Rechenzentrums.
  • secrets.baseDir, seine age-Identität und seine Vault-Datei.
  • codesphere.workspaceHostingBaseDomain, customDomains.cNameBaseDomain und publicIp — die Domains und die Adresse, unter denen die Workspaces dieses Rechenzentrums ausgeliefert werden.
  • kubernetes.*, ceph.*, cluster.gateway und cluster.publicGateway.
  • operations.skip — welche Installer-Schritte dieses Rechenzentrum nie ausführt.

Dazu die Vault-Einträge, die an die Cluster dieses Rechenzentrums gebunden sind, aufgeführt unter Seine eigene Konfiguration weiter unten.

Das erste Rechenzentrum konfigurieren

Das Rechenzentrum, das PostgreSQL betreibt und OpenFGA deployt. Seine Konfiguration ist die übliche Konfiguration für ein einzelnes Rechenzentrum, ergänzt um die Topologie-Liste und die beiden Betreiberrollen.

Geteilte Konfiguration

Trage die vollständige Topologie in dataCenters ein und lege fest, wo neue Teams landen:

# Byte-identical in config.yaml and config-dc2.yaml
dataCenters:
- id: 1
name: karlsruhe
city: Karlsruhe
countryCode: DE
- id: 2
name: frankfurt
city: Frankfurt
countryCode: DE
defaultDataCenterId: 1

Der Installer weist eine widersprüchliche Liste zurück: doppelte IDs, ein dataCenter, das in dataCenters fehlt, ein Eintrag, dessen Name oder Stadt von dataCenter abweicht, oder eine defaultDataCenterId, die nicht in der Liste steht.

warnung

dataCenters ganz wegzulassen ist der eine Fall, der still bleibt: die Liste fällt auf [dataCenter] zurück und defaultDataCenterId auf dataCenter.id. Die Installation gelingt, das Cluster ist gesund, und die Plattform verhält sich schlicht wie eine Installation mit einem einzelnen Rechenzentrum — die Auswahl bietet nur das Rechenzentrum an, in dem du angemeldet bist. Setze die Liste in jeder Konfiguration, auch in dieser.

Dieses Rechenzentrum betreibt die beiden geteilten Komponenten. PostgreSQL behält die übliche Konfiguration postgres.mode: install, und OpenFGA wird über das Gateway veröffentlicht, damit die anderen Rechenzentren es erreichen:

codesphere:
domain: cs.example.com # shared by the whole installation
openFga:
# deploy defaults to true, apiUrl to the in-cluster service.
expose:
enabled: true
host: openfga.1.cs.example.com
  • expose.host muss auf die Plattform-Gateway-Adresse dieses Rechenzentrums auflösen und ist genau das, was die anderen Rechenzentren in apiUrl eintragen. Ein Host unterhalb der Plattform-Domain dieses Rechenzentrums — openfga.1.cs.example.com — wird bereits vom Eintrag *.1.cs.example.com aus DNS-Einträge abgedeckt.
  • Das Gateway-Zertifikat wird von dem ClusterIssuer ausgestellt, der nach codesphere.certIssuer.type benannt ist. Bei ACME muss der Host öffentlich auflösbar sein. Bei einem selbstsignierten Issuer vertrauen die anderen Rechenzentren ihm nicht — siehe deren geteilte Konfiguration.
  • OpenFGA wird nur genutzt, wenn das Preview-Flag openfga-authz aktiv ist (siehe Feature-Flags). Ohne dieses Flag lass den Block weg.

warnung

Der Preshared Key ist das, was OpenFGA absichert, sobald es das Cluster verlässt. Ohne openFgaPresharedKey im Vault wird OpenFGA unauthentifiziert deployt, und das Chart weigert sich dann, expose.enabled: true zu rendern — die openfga-Anwendung synchronisiert nicht, statt einen offenen Autorisierungsspeicher zu veröffentlichen. Füge den Schlüssel hinzu, bevor du OpenFGA exponierst:

SOPS_AGE_KEY_FILE=/etc/codesphere/secrets/age_key.txt \
oms update install-config \
--config /etc/codesphere/config.yaml \
--vault /etc/codesphere/secrets/prod.vault.yaml

Der Rest der geteilten Konfiguration ist das, was auch eine Installation mit einem einzelnen Rechenzentrum verwenden würde. Entscheidend ist, dass das nächste Rechenzentrum sie exakt wiederholt.

Seine eigene Konfiguration

Seine Identität, sein Secrets-Verzeichnis und die Domains und Adressen, unter denen seine eigenen Workspaces ausgeliefert werden:

dataCenter:
id: 1
name: karlsruhe
city: Karlsruhe
countryCode: DE
secrets:
baseDir: /etc/codesphere/secrets
codesphere:
workspaceHostingBaseDomain: 1.example.com
customDomains:
cNameBaseDomain: 1.example.com
publicIp: 203.0.113.20

dataCenter.id steht in jeder Workspace-Zeile der geteilten Datenbank und taucht in den rechenzentrumsspezifischen Domains auf. dataCenter.name benennt das k0s-Cluster (codesphere-<dataCenter.name>) und muss deshalb ebenfalls eindeutig sein.

Der Workspace-SSH-Proxy hat keinen eigenen Domain-Schlüssel. Pro Rechenzentrum konfiguriert wird die Adresse, die sein ssh-workspace-proxy-Service erhält, unter pcApps; die Domain ist nur ein DNS-Eintrag, der auf diese Adresse zeigt:

pcApps:
applications:
ssh-workspace-proxy:
enabled: true
valuesObject:
service:
enabled: true
type: LoadBalancer
loadBalancerIP: 203.0.113.30

kubernetes.*, ceph.*, cluster.gateway und cluster.publicGateway beschreiben die eigenen Hosts und Adressen dieses Rechenzentrums, genau wie bei einer Installation mit einem einzelnen Rechenzentrum.

Jedes weitere Rechenzentrum konfigurieren

Geteilte Konfiguration

Übernimm dataCenters, defaultDataCenterId, codesphere.domain, plans, deployConfig, die Flag-Blöcke, gitProviders, oauth, managedServices und registry unverändert aus der Konfiguration des ersten Rechenzentrums.

Richte dieses Rechenzentrum auf den geteilten PostgreSQL-Server, statt einen eigenen zu installieren:

postgres:
mode: external
# An IP address, not a hostname — see the warning below.
serverAddress: 10.10.0.10
port: 5432
# Copied verbatim from the hosting data center's config.yaml.
caCertPem: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

postgres.primary und postgres.replica entfallen — sie beschreiben einen Server, den dieses Rechenzentrum nicht installiert. caCertPem liegt in der Konfiguration, nicht im Vault, und lässt sich nicht aus dem CA-Schlüssel neu ableiten; kopiere den PEM-Block also hinüber.

warnung

postgres.serverAddress muss die IP-Adresse des Servers sein, nicht sein Hostname. Das von oms init install-config erzeugte Serverzertifikat enthält nur IP-SANs; der Hostname steht im Common Name, den moderne TLS-Clients ignorieren. Ein Hostname an dieser Stelle führt in jedem Service dieses Rechenzentrums zu einem Zertifikatsfehler, ohne dass irgendetwas auf die Adresse als Ursache hinweist.

Der Vorgabewert des Assistenten für diese Abfrage ist postgres.example.com:5432 — ersetze ihn durch die reine IP und setze den Port in postgres.port.

Ändert sich die IP des Servers, muss das Zertifikat für die neue IP neu ausgestellt und serverAddress in jedem Rechenzentrum angepasst werden, das sich mit ihm verbindet.

Richte es auf die OpenFGA-Instanz, die das erste Rechenzentrum deployt, statt eine eigene zu deployen:

codesphere:
openFga:
deploy: false
apiUrl: https://openfga.1.cs.example.com
# Only with a self-signed cluster issuer: trust the CA that signed
# the OpenFGA gateway certificate.
extraCaPem: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

apiUrl muss der expose.host des betreibenden Rechenzentrums sein. extraCaPem nimmt dessen cluster.certificates.ca.certPem auf und wird nur gebraucht, wenn codesphere.certIssuer.type auf self-signed steht — einem ACME-Zertifikat wird ohnehin vertraut.

Schließlich müssen die geteilten Vault-Einträge byte-identisch zu denen des ersten Rechenzentrums sein. Das Vault abzuleiten statt ein frisches zu erzeugen ist das, was das sicherstellt, siehe Das Vault des zweiten Rechenzentrums ableiten.

Seine eigene Konfiguration

Alles unter Seine eigene Konfiguration oben gilt auch hier, mit den eigenen Werten dieses Rechenzentrums: ein eindeutiger dataCenter-Block, seine eigenen Workspace-Domains und publicIp, seine eigenen kubernetes.*, ceph.* und Gateway-Adressen sowie seine eigene pcApps-SSH-Proxy-Adresse.

Es hat außerdem sein eigenes Vault in seinem eigenen Secrets-Verzeichnis und überspringt den Installer-Schritt für die Komponente, die es nicht betreibt:

secrets:
baseDir: /etc/codesphere/secrets
operations:
skip:
- postgres

secrets.baseDir ist ein Pfad auf der Maschine, die den Installer ausführt; auf der eigenen Jumpbox dieses Rechenzentrums ist es also derselbe Pfad, den Rechenzentrum 1 auf seiner Jumpbox verwendet — zwei Verzeichnisse auf zwei Maschinen, jedes mit einem Vault und einer age-Identität. postgres in operations.skip verhindert, dass jeder Lauf dieses Rechenzentrums — auch manuelle Wiederholungen — den geteilten Server anzufassen versucht.

gefahr

Rechenzentren, die von einer Maschine aus installiert werden, dürfen sich kein secrets.baseDir teilen.

Der Installer liest das Vault aus diesem Verzeichnis und schreibt Ergebnisse dorthin zurück — der kubernetes-Schritt schreibt kubeConfig, der ceph-Schritt schreibt sämtliche Ceph-Zugangsdaten. Betreibt eine gemeinsame Jumpbox beide Rechenzentren aus einem Verzeichnis, überschreibt die Installation des zweiten die Einträge des ersten und entschlüsselt dessen Vault mit dem age-Schlüssel des ersten. Zur Installationszeit schlägt nichts fehl, aber der nächste oms install codesphere- oder oms add-cluster-admin-Lauf für Rechenzentrum 1 liest kubeConfig aus dem Vault und wendet die Konfiguration von Rechenzentrum 1 auf das Cluster von Rechenzentrum 2 an.

Gib jedem Rechenzentrum dort sein eigenes Verzeichnis — /etc/codesphere/secrets und /etc/codesphere/secrets-dc2. Der Verzeichnisname benennt auch das Secrets-Verzeichnis, das auf den Knoten dieses Rechenzentrums abgelegt wird, eindeutige Namen halten die beiden also auch dort auseinander.

Eine eigene age-Identität pro Vault ist nicht zwingend erforderlich, hält aber den Schaden eines geleakten Schlüssels auf ein Rechenzentrum begrenzt.

Diese Vault-Einträge gehören zu den Clustern dieses Rechenzentrums und müssen für es neu erzeugt werden; jeder hier nicht aufgeführte Eintrag wird geteilt:

Vault-EintragZugehöriges Konfigurationsfeld
selfSignedCaKeyPemcluster.certificates.ca.certPem
cephSshPrivateKeyceph.cephAdmSshKey.publicKey
acmeEabMacKeycodesphere.certIssuer.acme.eabKeyId
kubeConfig— geschrieben vom kubernetes-Schritt oder von oms install k0s --vault
Alles, was mit ceph, csi oder rgw beginnt— geschrieben vom ceph-Schritt
privNixSigningKey, pubNixSigningKey— nur in wiederhergestellten Vaults vorhanden

warnung

Ändere ein Konfigurationsfeld und sein Vault-Secret immer als Paar. Die Generatoren hängen am Vault-Eintrag: fehlt selfSignedCaKeyPem, wird eine neue Ingress-CA erzeugt und cluster.certificates.ca.certPem überschrieben. Fehlt der Vault-Eintrag, während die Konfiguration noch das certPem des vorherigen Rechenzentrums trägt, entsteht ein frischer Schlüssel neben einem veralteten Zertifikat — Ingress liefert dann Zertifikate aus, die von einer CA signiert sind, der niemand vertraut, sichtbar nur als TLS-Fehler im Browser. Dasselbe gilt für cephSshPrivateKey / ceph.cephAdmSshKey.publicKey und für acmeEabMacKey / codesphere.certIssuer.acme.eabKeyId.

DNS-Einträge

codesphere.domain löst auf das Plattform-Gateway eines Rechenzentrums auf. Workspaces und ihre SSH-Endpunkte lösen pro Rechenzentrum auf, damit der Verkehr eines Workspace das Cluster erreicht, auf dem er läuft.

Mit der Basis-Domain example.com, codesphere.domain: cs.example.com und sechs reservierten Adressen:

Rechenzentrum 1Rechenzentrum 2
Plattform-Gateway (gateway-controller)203.0.113.10198.51.100.10
Workspace-Gateway (public-gateway-controller)203.0.113.20198.51.100.20
Workspace-SSH-Proxy (ssh-workspace-proxy)203.0.113.30198.51.100.30

lege an:

EintragTypZiel
cs.example.com, *.cs.example.comA203.0.113.10
1.cs.example.com, *.1.cs.example.comA203.0.113.10
2.cs.example.com, *.2.cs.example.comA198.51.100.10
1.example.com, *.1.example.comA203.0.113.20
2.example.com, *.2.example.comA198.51.100.20
*.1.ssh.example.comA203.0.113.30
*.2.ssh.example.comA198.51.100.30

warnung

Die Zeilen <dc-id>.cs.example.com sind die, die übersehen werden. Die Plattform bildet den Service-Endpunkt jedes Rechenzentrums als <dataCenter.id>.<codesphere.domain> und der Browser ruft ihn direkt auf, bevor irgendetwas gerendert wird. Ohne expliziten Eintrag fällt 2.cs.example.com auf die Wildcard *.cs.example.com zurück, löst auf das Gateway von Rechenzentrum 1 auf, das keine Route dafür hat — und die gesamte Oberfläche lädt nicht, nicht nur die Workspaces in Rechenzentrum 2.

Das Anlegen von 2.cs.example.com verhindert außerdem, dass *.cs.example.com Namen darunter abdeckt; *.2.cs.example.com muss deshalb ebenfalls explizit angelegt werden.

Vor der Installation

Prüfe für die Konfiguration jedes Rechenzentrums:

  • dataCenter.id und dataCenter.name sind installationsweit eindeutig.
  • dataCenters ist vorhanden und in jeder Konfiguration identisch, und defaultDataCenterId nennt eine ID, die darin vorkommt.
  • Der Rest der geteilten Konfiguration — Domain, Plans, Deploy-Konfiguration, Flags, Provider, Managed Services, Registry — ist in jeder Konfiguration identisch.
  • secrets.baseDir enthält das eigene Vault dieses Rechenzentrums, und kein anderes Rechenzentrum wird aus demselben Verzeichnis installiert.
  • Genau eine Konfiguration hat postgres.mode: install; jede andere hat mode: external, serverAddress auf die IP des Servers gesetzt, port, ein kopiertes caCertPem, kein primary/replica und postgres in operations.skip.
  • Genau eine Konfiguration hat codesphere.openFga.expose.enabled: true; jede andere hat deploy: false und eine apiUrl, die darauf zeigt.
  • Die Workspace-Domains, publicIp, kubernetes.*, ceph.* und beide Gateway-Adressen gehören diesem Rechenzentrum.
  • Die geteilten Vault-Einträge sind byte-identisch; die rechenzentrumsspezifischen sind frisch erzeugt, nicht geerbt.

Validiere anschließend das Dateipaar jedes Rechenzentrums auf der Jumpbox, die es hält:

oms init install-config --validate -c /etc/codesphere/config.yaml \
--vault /etc/codesphere/secrets/prod.vault.yaml

Die Validierung prüft eine Konfiguration für sich allein. Sie erkennt weder einen doppelten dataCenter.name, noch zwei Rechenzentren, die aus einem Secrets-Verzeichnis installiert werden, eine fehlende dataCenters-Liste oder ein auseinandergelaufenes geteiltes Secret — dafür ist die Liste oben da.

Weiter

Mehrere Rechenzentren: Installation.