Mehrere Rechenzentren: Konfiguration
Bevor du startest
Eine Codesphere-Installation kann sich über mehrere Rechenzentren erstrecken. 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 das, was sich von einer Installation mit einem einzigen Rechenzentrum unterscheidet, siehe Installationsanleitung für den grundlegenden Ablauf. Für das Vorgehen siehe Mehrere Rechenzentren: Installation.
Jedes Rechenzentrum hat seine eigene config.yaml und seine eigene prod.vault.yaml.
Nichts wird zusammengeführt: Jeder Durchlauf von oms install codesphere installiert
genau ein Rechenzentrum.
codesphere.domain = cs.example.com
|
+---------------+---------------+
| |
Rechenzentrum 1 Rechenzentrum 2
k0s + Ceph-Cluster A k0s + Ceph-Cluster B
Jumpbox 1 Jumpbox 2
config.yaml + eigener Vault config.yaml + eigener Vault
| |
+---------------+---------------+
|
ein PostgreSQL-Server, ein OpenFGA
Jedes Rechenzentrum wird normalerweise über seine eigene Jumpbox gesteuert, sodass die unten genannten Dateinamen auf jeder Maschine gleich sind. Eine Jumpbox für die gesamte Installation funktioniert ebenfalls, dann muss jedoch jeder Pfad pro Rechenzentrum eindeutig gemacht werden, siehe Dateien anlegen.
Was gemeinsam genutzt wird
Komponenten
- Der PostgreSQL-Server, der die Codesphere-Datenbank enthält — seine Rollen, sein Schema und jede Workspace-, Team- und Benutzerzeile. Ein Rechenzentrum installiert und hostet ihn; jedes andere verbindet sich mit ihm als externe Datenbank.
- Die OpenFGA-Instanz, die die Autorisierungs-Tupel enthält, zusammen mit der CloudNativePG-Datenbank, mit der sie ausgeliefert wird. Ein Rechenzentrum stellt sie bereit 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 Plattformname für die gesamte Installation.dataCentersunddefaultDataCenterId— die Topologie, die jedes Rechenzentrum kennen muss.codesphere.plans,deployConfig,features,internal,preview,gitProviders,oauth,managedServices— Plattformverhalten, das auf der gemeinsamen Datenbank basiert.codesphere.email— jedes Rechenzentrum versendet transaktionale E-Mails über denselben Anbieter.registry— jedes Rechenzentrum bezieht 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 gemeinsamen
Datenbank — jedes Secret, das auf der anderen Seite von etwas Gemeinsamem verwendet wird.
tokenPrivateKey erstellt die Sessions, die Rechenzentren übergreifen,
mounterHmacSecret und mongoDbPasswordEncryptionKey signieren und verschlüsseln
Zeilen in der gemeinsamen Datenbank, openFgaPresharedKey authentifiziert gegenüber der
einen OpenFGA-Instanz, und jedes postgresUser*/postgresPassword*-Paar ist eine Rolle
auf dem einen Server. Kopiere auch die ausgewählte E-Mail-Zugangsdaten
(sendGridApiKey oder smtpPassword) in den Vault jedes Rechenzentrums.
Gemeinsame Werte lassen sich leicht in einer Konfiguration ändern und in der anderen
vergessen. Ein abweichender plans-Block bedeutet, dass ein Workspace in einem
Rechenzentrum erstellt werden kann und im anderen nicht, lange nach der Installation;
ein abweichender tokenPrivateKey bedeutet, dass ein Benutzer sich bei einem
Rechenzentrum anmeldet und vom nächsten abgewiesen wird.
Was jedes Rechenzentrum selbst besitzt
Komponenten
Sein eigenes k0s-Cluster, sein eigenes Ceph-Cluster und seine eigenen drei extern erreichbaren Adressen — Plattform-Gateway, Workspace-Gateway und Workspace-SSH-Proxy. Keine davon werden gemeinsam genutzt, und nichts in der Konfiguration eines Rechenzentrums darf auf die Hosts eines anderen verweisen.
Gemeinsame Konfiguration
dataCenter— die Identität dieses Rechenzentrums.secrets.baseDir, seine Age-Identität und seine Vault-Datei.codesphere.workspaceHostingBaseDomain,customDomains.cNameBaseDomainundpublicIp— die Domains und Adressen, über die die Workspaces dieses Rechenzentrums bereitgestellt werden.kubernetes.*,ceph.*,cluster.gatewayundcluster.publicGateway.operations.skip— welche Installer-Schritte dieses Rechenzentrum nie ausführt.
Plus die Vault-Einträge, die den Clustern dieses Rechenzentrums zugeordnet sind, unten unter eigene Konfiguration aufgeführt.
Das erste Rechenzentrum konfigurieren
Das Rechenzentrum, das PostgreSQL hostet und OpenFGA bereitstellt. Seine Konfiguration ist die normale Konfiguration für ein einzelnes Rechenzentrum, plus die Topologieliste und die zwei Hosting-Rollen.
Gemeinsame Konfiguration
Schreibe die vollständige Topologie in dataCenters und lege fest, wo neue Teams
landen:
# Byte-identisch in config.yaml und config-dc2.yaml
dataCenters:
- id: 1
name: karlsruhe
city: Karlsruhe
countryCode: DE
- id: 2
name: frankfurt
city: Frankfurt
countryCode: DE
defaultDataCenterId: 1
Der Installer lehnt eine Liste ab, die sich selbst widerspricht: 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
enthalten ist.
dataCenters vollständig auszulassen ist der einzige Fall, der unauffällig bleibt: Es
wird standardmäßig zu [dataCenter] und defaultDataCenterId zu dataCenter.id. Die
Installation gelingt, das Cluster ist gesund, und die Plattform verhält sich einfach wie
eine Installation mit einem einzigen Rechenzentrum — die Auswahl bietet nur das
Rechenzentrum an, bei dem man angemeldet ist. Setze die Liste in jeder
Konfiguration, einschließlich dieser.
Dieses Rechenzentrum hostet die beiden gemeinsam genutzten Komponenten. PostgreSQL
behält die normale Konfiguration postgres.mode: install, und OpenFGA wird über das
Gateway veröffentlicht, damit die anderen Rechenzentren es erreichen können:
codesphere:
domain: cs.example.com # von der gesamten Installation gemeinsam genutzt
openFga:
# deploy ist standardmäßig true, apiUrl der Dienst im Cluster.
expose:
enabled: true
host: openfga.1.cs.example.com
expose.hostmuss auf die Plattform-Gateway-Adresse dieses Rechenzentrums auflösen, und ist das, was die anderen Rechenzentren inapiUrleintragen. Gib ihm einen eigenen A-Record, siehe DNS-Records, anstatt dich auf einen Wildcard zu verlassen, der ihn abdeckt.- Das Gateway-Zertifikat wird vom ClusterIssuer ausgestellt, der nach
codesphere.certIssuer.typebenannt ist. Mit ACME muss der Host öffentlich auflösbar sein. Mit einem selbstsignierten Issuer vertrauen die anderen Rechenzentren ihm nicht — siehe ihre gemeinsame Konfiguration. - OpenFGA wird nur verwendet, wenn das Preview-Flag
openfga-authzaktiviert ist (siehe Feature-Flags). Ohne dieses lässt man den Block weg.
Jeder Name unter einer codesphere.workspaceHostingBaseDomain entspricht dem
Wildcard-Record dieser Domain, der auf das Workspace-Gateway verweist — und das
Workspace-Gateway hat keine Route für OpenFGA. Mit
workspaceHostingBaseDomain: 1.cs.example.com zum Beispiel ist
openfga.1.cs.example.com ein solcher Name: Nur sein eigener A-Record hält ihn auf dem
Plattform-Gateway, und nichts meldet dies, wenn dieser Record fehlt. Die anderen
Rechenzentren können OpenFGA dann einfach nicht erreichen. Wähle einen expose.host
außerhalb der Workspace-Domain jedes Rechenzentrums.
Der Preshared Key ist das, was OpenFGA authentifiziert, sobald es das Cluster verlässt.
Ohne openFgaPresharedKey im Vault wird OpenFGA unauthentifiziert bereitgestellt, und
das Chart verweigert dann das Rendern von expose.enabled: true — die
openfga-Anwendung schlägt bei der Synchronisierung fehl, statt einen offenen
Autorisierungsspeicher zu veröffentlichen. Füge den Schlüssel dem Vault dieses
Rechenzentrums hinzu, bevor du ihn freigibst, und bevor du den Vault eines anderen
Rechenzentrums daraus ableitest:
# Nur auf Jumpbox 1.
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 Vault jedes anderen Rechenzentrums braucht genau diesen Wert, siehe Jedes weitere Rechenzentrum konfigurieren.
Der Rest der gemeinsamen Konfiguration ist das, was eine Installation mit einem einzigen Rechenzentrum ebenfalls verwenden würde. Wichtig ist, dass das nächste Rechenzentrum sie exakt wiederholt.
Eigene Konfiguration
Seine Identität, sein Secrets-Verzeichnis und die Domains und Adressen, über die seine eigenen Workspaces bereitgestellt 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 wird in jeder Workspace-Zeile der gemeinsamen Datenbank gespeichert und
erscheint in den Domains pro Rechenzentrum. dataCenter.name benennt das k0s-Cluster
(codesphere-<dataCenter.name>), muss also ebenfalls eindeutig sein.
Der Workspace-SSH-Proxy hat keinen eigenen Domain-Schlüssel. Was pro Rechenzentrum
konfiguriert wird, ist die Adresse, die sein Dienst ssh-workspace-proxy unter
pcApps erhält; die Domain ist nur ein DNS-Record, der auf diese Adresse verweist:
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 einzigen Rechenzentrum.
Jedes weitere Rechenzentrum konfigurieren
Gemeinsame Konfiguration
Kopiere dataCenters, defaultDataCenterId, codesphere.domain, plans,
deployConfig, die Flag-Gruppen, gitProviders, oauth, managedServices und
registry aus der Konfiguration des ersten Rechenzentrums unverändert.
Verweise dieses Rechenzentrum auf den gemeinsamen PostgreSQL-Server, statt einen zu installieren:
postgres:
mode: external
# Eine IP-Adresse, kein Hostname — siehe die Warnung unten.
serverAddress: 10.10.0.10
port: 5432
# Wörtlich aus der config.yaml des hostenden Rechenzentrums kopiert.
caCertPem: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
postgres.primary und postgres.replica werden ausgelassen — sie beschreiben einen
Server, den dieses Rechenzentrum nicht installiert. caCertPem steht in der
Konfiguration, nicht im Vault, und kann nicht aus dem CA-Schlüssel neu abgeleitet
werden, also kopiere den PEM-Block.
postgres.serverAddress muss die IP-Adresse des Servers sein, nicht sein
Hostname. Das Serverzertifikat, das oms init install-config generiert, enthält nur
IP-SANs; der Hostname erscheint im Common Name, den moderne TLS-Clients ignorieren. Ein
Hostname hier führt zu einem Fehler bei der Zertifikatsprüfung in jedem Dienst dieses
Rechenzentrums, ohne dass etwas auf die Adresse als Ursache hinweist.
Der Standardwert des Assistenten für diese Eingabeaufforderung ist
postgres.example.com:5432 — ersetze ihn durch die reine IP und setze den Port in
postgres.port.
Wenn sich die IP-Adresse des Servers jemals ändert, muss das Zertifikat für die neue
IP neu ausgestellt und serverAddress in jedem verbundenen Rechenzentrum aktualisiert
werden.
Verweise es auf die OpenFGA-Instanz, die das erste Rechenzentrum bereitstellt, statt eine eigene bereitzustellen:
codesphere:
openFga:
deploy: false
apiUrl: https://openfga.1.cs.example.com
# Nur bei einem selbstsignierten ClusterIssuer: vertraue der CA,
# die das OpenFGA-Gateway-Zertifikat signiert hat.
extraCaPem: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
apiUrl muss der expose.host des bereitstellenden Rechenzentrums sein. extraCaPem
übernimmt cluster.certificates.ca.certPem dieses Rechenzentrums und wird nur benötigt,
wenn codesphere.certIssuer.type self-signed ist — einem ACME-Zertifikat wird
bereits vertraut.
Schließlich müssen die gemeinsamen Vault-Einträge byte-identisch mit denen des ersten Rechenzentrums sein. Den Vault abzuleiten, statt einen neuen zu erzeugen, ist das, was dies garantiert, siehe Den Vault des zweiten Rechenzentrums ableiten.
openFgaPresharedKey muss in jedem Vault denselben Wert enthalten. OpenFGA akzeptiert
nur den Schlüssel im Vault des Rechenzentrums, das es bereitstellt, und weist jede
Autorisierungsprüfung aus einem Rechenzentrum mit einem anderen Schlüssel als nicht
authentifiziert zurück.
oms init install-config und oms update install-config erzeugen einen neuen
Zufallsschlüssel, wann immer ein Vault keinen hat. Ein abgeleiteter Vault erbt den
Schlüssel nur, wenn der Vault von Rechenzentrum 1 bereits einen hatte — andernfalls
erzeugt der Schritt oms update install-config auf Jumpbox 2 stillschweigend einen
zweiten, anderen Schlüssel. Dasselbe passiert, wenn der Schlüssel einer bestehenden
Installation hinzugefügt wird, indem dieser Befehl auf jeder Jumpbox ausgeführt wird.
Erzeuge den Schlüssel einmal, in dem Rechenzentrum, das OpenFGA bereitstellt, und kopiere diesen Wert in jeden anderen Vault. Für eine bereits laufende Installation siehe Den OpenFGA-Preshared-Key in einer laufenden Installation teilen.
Eigene Konfiguration
Alles unter eigene Konfiguration oben gilt hier ebenfalls,
mit den eigenen Werten dieses Rechenzentrums: einem eindeutigen dataCenter-Block,
seinen eigenen Workspace-Domains und publicIp, seinen eigenen kubernetes.*,
ceph.* und Gateway-Adressen, und seiner eigenen SSH-Proxy-Adresse unter pcApps.
Es hat außerdem seinen eigenen Vault, in seinem eigenen Secrets-Verzeichnis, und überspringt den Installer-Schritt für die Komponente, die es nicht hostet:
secrets:
baseDir: /etc/codesphere/secrets
operations:
skip:
- postgres
secrets.baseDir ist ein Pfad auf der Maschine, die den Installer ausführt, sodass er
auf der eigenen Jumpbox dieses Rechenzentrums derselbe Pfad ist, 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
Durchlauf dieses Rechenzentrums, einschließlich manueller erneuter Läufe, versucht, den
gemeinsamen Server zu verwalten.
Rechenzentren, die von einer Maschine aus installiert werden, dürfen sich kein
secrets.baseDir teilen.
Der Installer liest den Vault aus diesem Verzeichnis und schreibt Ergebnisse zurück in
ihn — der Schritt kubernetes schreibt kubeConfig, der Schritt ceph schreibt jede
Ceph-Zugangsdaten. Wenn eine gemeinsam genutzte Jumpbox beide Rechenzentren aus einem
Verzeichnis heraus steuert, überschreibt die Installation des zweiten die Einträge des
ersten und entschlüsselt seinen Vault mit dem Age-Schlüssel des ersten. Zum
Installationszeitpunkt schlägt nichts fehl, aber der nächste Durchlauf von
oms install codesphere oder oms add-cluster-admin 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 Nodes dieses Rechenzentrums bereitgestellt wird, sodass
unterschiedliche Namen die beiden auch auf den Nodes getrennt halten.
Eine separate Age-Identität pro Vault ist nicht strikt erforderlich, begrenzt aber den Schaden eines kompromittierten Schlüssels auf ein Rechenzentrum.
Diese Vault-Einträge gehören zu den Clustern dieses Rechenzentrums und müssen dafür neu erzeugt werden; jeder hier nicht aufgeführte Eintrag wird gemeinsam genutzt:
| Vault-Eintrag | Zugehöriges Konfigurationsfeld |
|---|---|
selfSignedCaKeyPem | cluster.certificates.ca.certPem |
cephSshPrivateKey | ceph.cephAdmSshKey.publicKey |
acmeEabMacKey | codesphere.certIssuer.acme.eabKeyId |
acmeCustomDomainsEabMacKey | codesphere.certIssuer.acme.customDomainsEabKeyId |
kubeConfig | — wird vom Schritt kubernetes geschrieben, oder von oms install k0s --vault |
Alles, das mit ceph, csi oder rgw beginnt | — wird vom Schritt ceph geschrieben |
privNixSigningKey, pubNixSigningKey | — nur in wiederhergestellten Vaults vorhanden |
Ändere ein Konfigurationsfeld und sein zugehöriges Vault-Secret immer als Paar.
Die Generatoren richten sich nach dem Vault-Eintrag: Fehlt selfSignedCaKeyPem, wird
eine neue Ingress-CA erzeugt und cluster.certificates.ca.certPem überschrieben. Fehlt
der Vault-Eintrag, während die Konfiguration aber noch das certPem des vorherigen
Rechenzentrums enthält, erhältst du einen neuen Schlüssel neben einem veralteten
Zertifikat — der Ingress liefert dann Zertifikate, die von einer CA signiert sind, der
niemand vertraut, was nur als TLS-Fehler im Browser sichtbar wird. Dasselbe gilt für
cephSshPrivateKey/ceph.cephAdmSshKey.publicKey, für acmeEabMacKey/
codesphere.certIssuer.acme.eabKeyId und für acmeCustomDomainsEabMacKey/
codesphere.certIssuer.acme.customDomainsEabKeyId.
DNS-Records
codesphere.domain löst zu einem Plattform-Gateway eines Rechenzentrums auf.
Workspaces und ihre SSH-Endpunkte lösen pro Rechenzentrum auf, sodass der Datenverkehr
eines Workspaces das Cluster erreicht, auf dem er läuft.
Mit der Basisdomain example.com, codesphere.domain: cs.example.com und sechs
reservierten Adressen:
| Rechenzentrum 1 | Rechenzentrum 2 | |
|---|---|---|
Plattform-Gateway (gateway-controller) | 203.0.113.10 | 198.51.100.10 |
Workspace-Gateway (public-gateway-controller) | 203.0.113.20 | 198.51.100.20 |
Workspace-SSH-Proxy (ssh-workspace-proxy) | 203.0.113.30 | 198.51.100.30 |
erstelle:
| Record | Typ | Ziel |
|---|---|---|
cs.example.com, *.cs.example.com | A | 203.0.113.10 |
1.cs.example.com, *.1.cs.example.com | A | 203.0.113.10 |
openfga.1.cs.example.com | A | 203.0.113.10 |
2.cs.example.com, *.2.cs.example.com | A | 198.51.100.10 |
1.example.com, *.1.example.com | A | 203.0.113.20 |
2.example.com, *.2.example.com | A | 198.51.100.20 |
*.1.ssh.example.com | A | 203.0.113.30 |
*.2.ssh.example.com | A | 198.51.100.30 |
Der OpenFGA-Host erhält seinen eigenen Record, selbst wenn bereits ein Wildcard darauf passt. Welcher Wildcard passt, hängt davon ab, wie die Plattform- und Workspace-Domains verschachtelt sind, und der für eine Workspace-Domain zeigt auf das Workspace-Gateway.
Die Zeilen <dc-id>.cs.example.com sind diejenigen, die am ehesten übersehen werden.
Die Plattform baut den Service-Endpunkt jedes Rechenzentrums als
<dataCenter.id>.<codesphere.domain> auf, und der Browser ruft ihn direkt auf, noch
bevor irgendetwas gerendert wird. Ohne expliziten Record fällt 2.cs.example.com auf
den Wildcard *.cs.example.com zurück, löst zum Gateway von Rechenzentrum 1 auf, das
dafür keine Route hat — und die gesamte Benutzeroberflä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, sodass *.2.cs.example.com ebenfalls explizit angelegt werden muss.
Bevor du installierst
Prüfe für jede Konfiguration jedes Rechenzentrums:
-
dataCenter.idunddataCenter.namesind über die gesamte Installation hinweg eindeutig. -
dataCentersist vorhanden und in jeder Konfiguration identisch, unddefaultDataCenterIdbenennt eine darin enthaltene ID. - Der Rest der gemeinsamen Konfiguration — Domain, Pläne, Deploy-Konfiguration, Flags, Provider, Managed Services, Registry — ist in jeder Konfiguration identisch.
-
secrets.baseDirenthält den eigenen Vault dieses Rechenzentrums, und kein anderes Rechenzentrum wird aus demselben Verzeichnis installiert. - Genau eine Konfiguration hat
postgres.mode: install; jede andere hatmode: external,serverAddressgesetzt auf die IP des Servers,port, ein kopiertescaCertPem, keinprimary/replica, undpostgresinoperations.skip. - Genau eine Konfiguration hat
codesphere.openFga.expose.enabled: true; jede andere hatdeploy: falseund eineapiUrl, die darauf verweist. - Dieser
expose.hosthat seinen eigenen A-Record, der auf das Plattform-Gateway des bereitstellenden Rechenzentrums verweist, und liegt unter keinerworkspaceHostingBaseDomain. - Die Workspace-Domains,
publicIp,kubernetes.*,ceph.*und beide Gateway-Adressen sind die eigenen dieses Rechenzentrums. - Die gemeinsamen Vault-Einträge sind byte-identisch; die pro Rechenzentrum spezifischen sind neu erzeugt, nicht übernommen.
-
openFgaPresharedKeyist in jedem Vault vorhanden, mit überall demselben Wert.
Validiere anschließend das Dateipaar jedes Rechenzentrums, auf der Jumpbox, die sie enthält:
oms init install-config --validate -c /etc/codesphere/config.yaml \
--vault /etc/codesphere/secrets/prod.vault.yaml
Der Validator prüft eine Konfiguration isoliert. Er erkennt keinen doppelten
dataCenter.name, zwei Rechenzentren, die aus einem Secrets-Verzeichnis installiert
wurden, eine fehlende dataCenters-Liste oder ein abweichendes gemeinsames Secret —
das sind die oben genannten Prüfungen.