Zum Hauptinhalt springen
Version: Weekly Build

Mehrere Rechenzentren: Konfiguration

Bevor du beginnst​

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 einzelnen 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 führt sie zusammen: Jeder Lauf 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 von seiner eigenen Jumpbox aus betrieben, sodass die unten genannten Dateinamen auf jeder Maschine gleich sind. Eine einzige Jumpbox für die gesamte Installation funktioniert ebenfalls, dann muss aber jeder rechenzentrumsspezifische Pfad eindeutig gemacht werden, siehe Dateien anlegen.

Was gemeinsam genutzt wird​

Komponenten​

  • Der PostgreSQL-Server, der die Codesphere-Datenbank hält — seine Rollen, sein Schema und jede Zeile zu Workspace, Resource Group und Benutzer. Ein Rechenzentrum installiert und hostet ihn; jedes andere verbindet sich mit ihm als externer Datenbank.
  • Die OpenFGA-Instanz, die die Autorisierungs-Tupel hält, zusammen mit der CloudNativePG-Datenbank, die sie mitbringt. 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.
  • dataCenters und defaultDataCenterId — 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 sendet transaktionale E-Mails über denselben Anbieter.
  • 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 gemeinsamen Datenbank — jedes Secret, das auf der anderen Seite von etwas Gemeinsamem konsumiert wird. tokenPrivateKey prägt die Sessions, die Rechenzentren überschreiten, mounterHmacSecret und mongoDbPasswordEncryptionKey signieren und verschlüsseln Zeilen in der gemeinsamen Datenbank, openFgaPresharedKey authentifiziert gegen das eine OpenFGA, und jedes Paar aus postgresUser* / postgresPassword* ist eine Rolle auf dem einen Server. Kopiere auch die gewählte E-Mail-Zugangsdaten (sendGridApiKey oder smtpPassword) in den Vault jedes Rechenzentrums.

warnung

Gemeinsame Werte lassen sich leicht in einer Konfiguration ändern und in der anderen vergessen. Ein abweichender plans-Block ist ein Workspace, der in einem Rechenzentrum angelegt werden kann und im anderen nicht, lange nach der Installation; ein abweichender tokenPrivateKey ist ein Benutzer, der bei einem Rechenzentrum angemeldet ist 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 — Platform Gateway, Workspace Gateway und Workspace-SSH-Proxy. Keine davon wird geteilt, 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.cNameBaseDomain und publicIp — die Domains und Adressen, über die Workspaces dieses Rechenzentrums bereitgestellt werden.
  • kubernetes.*, ceph.*, cluster.gateway und cluster.publicGateway.
  • operations.skip — welche Installer-Schritte dieses Rechenzentrum nie ausführt.

Plus die Vault-Einträge, die mit den Clustern dieses Rechenzentrums verknüpft sind, aufgeführt unter seiner eigenen Konfiguration weiter unten.

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 Resource Groups 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 weist eine Liste zurück, 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 steht.

warnung

dataCenters komplett wegzulassen ist der einzige Fall, der stillschweigend durchgeht: Es wird standardmäßig zu [dataCenter] und defaultDataCenterId zu 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, bei dem gerade angemeldet ist. Setze die Liste in jeder Konfiguration, auch in dieser.

Dieses Rechenzentrum hostet die zwei gemeinsamen Komponenten. PostgreSQL behält die normale postgres.mode: install-Konfiguration, und OpenFGA wird über das Gateway veröffentlicht, damit die anderen Rechenzentren darauf zugreifen können:

codesphere:
domain: cs.example.com # gemeinsam für die gesamte Installation
openFga:
# deploy ist standardmäßig true, apiUrl zeigt auf den clusterinternen Service.
expose:
enabled: true
host: openfga.1.cs.example.com
  • expose.host muss auf die Adresse des Platform Gateways dieses Rechenzentrums auflösen, und ist das, was die anderen Rechenzentren in apiUrl eintragen. Gib ihm einen eigenen A-Record, siehe DNS-Einträge, statt dich auf einen Wildcard zu verlassen, der ihn mit abdeckt.
  • Das Gateway-Zertifikat wird vom ClusterIssuer ausgestellt, der nach codesphere.certIssuer.type benannt ist. Mit ACME muss der Host öffentlich auflösbar sein. Mit einem selbstsignierten Issuer vertrauen ihm die anderen Rechenzentren nicht — siehe ihre gemeinsame Konfiguration.
  • OpenFGA wird nur verwendet, wenn das Preview-Flag openfga-authz aktiv ist (siehe Feature-Flags). Ohne dieses Flag den Block weglassen.
Den OpenFGA-Host aus der Workspace-Domain heraushalten

Jeder Name unter einer codesphere.workspaceHostingBaseDomain trifft auf den Wildcard-Record dieser Domain zu, der auf das Workspace Gateway zeigt — und das Workspace Gateway hat keine Route für OpenFGA. Bei workspaceHostingBaseDomain: 1.cs.example.com ist zum Beispiel openfga.1.cs.example.com so ein Name: Nur sein eigener A-Record hält ihn beim Platform Gateway, und nichts meldet es, wenn dieser Record fehlt. Die anderen Rechenzentren können OpenFGA dann schlicht nicht erreichen. Wähle einen expose.host außerhalb der Workspace-Domain jedes Rechenzentrums.

warnung

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, expose.enabled: true zu rendern — die openfga-Anwendung schlägt beim Sync fehl, anstatt einen offenen Autorisierungs-Store zu veröffentlichen. Füge den Schlüssel zum Vault dieses Rechenzentrums hinzu, bevor OpenFGA veröffentlicht wird, und bevor der Vault eines anderen Rechenzentrums davon abgeleitet wird:

# 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 auch eine Installation mit einem einzelnen Rechenzentrum verwenden würde. Wichtig ist, dass das nächste Rechenzentrum sie exakt wiederholt.

Seine 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 rechenzentrumsspezifischen Domains. dataCenter.name benennt das k0s-Cluster (codesphere-<dataCenter.name>), muss also ebenfalls eindeutig sein.

Der Workspace-SSH-Proxy hat keinen eigenen Domain-Schlüssel. Konfiguriert wird pro Rechenzentrum die Adresse, die sein ssh-workspace-proxy-Service erhält, unter pcApps; die Domain ist nur ein DNS-Record, 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​

Gemeinsame Konfiguration​

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

Richte dieses Rechenzentrum auf den gemeinsamen PostgreSQL-Server aus, statt einen zu installieren:

postgres:
mode: external
# Eine IP-Adresse, kein Hostname — siehe die Warnung unten.
serverAddress: 10.10.0.10
port: 5432
# Wortwörtlich aus der config.yaml des hostenden Rechenzentrums kopiert.
caCertPem: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

postgres.primary und postgres.replica werden weggelassen — 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 den PEM-Block übernehmen.

warnung

postgres.serverAddress muss die IP-Adresse des Servers sein, nicht sein Hostname. Das Serverzertifikat, das oms init install-config erzeugt, trägt nur IP-SANs; der Hostname erscheint im Common Name, den moderne TLS-Clients ignorieren. Ein Hostname an dieser Stelle erzeugt einen Zertifikatsprüfungsfehler in jedem Dienst dieses Rechenzentrums, ohne dass irgendetwas auf die Adresse als Ursache hinweist.

Die Vorgabe des Assistenten für diese Eingabeaufforderung ist postgres.example.com:5432 — ersetze sie durch die reine IP und setze den Port in postgres.port.

Sollte sich die IP des Servers jemals ändern, muss das Zertifikat für die neue IP neu ausgestellt und serverAddress in jedem Rechenzentrum aktualisiert werden, das sich damit verbindet.

Richte es auf die OpenFGA-Instanz aus, die das erste Rechenzentrum bereitstellt, statt eine eigene bereitzustellen:

codesphere:
openFga:
deploy: false
apiUrl: https://openfga.1.cs.example.com
# Nur bei einem selbstsignierten Cluster-Issuer: Vertraue der CA, die das
# OpenFGA-Gateway-Zertifikat signiert hat.
extraCaPem: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

apiUrl muss dem expose.host des bereitstellenden Rechenzentrums entsprechen. extraCaPem übernimmt den Wert cluster.certificates.ca.certPem dieses Rechenzentrums und wird nur benötigt, wenn codesphere.certIssuer.type auf self-signed steht — einem ACME-Zertifikat wird bereits vertraut.

Schließlich müssen die gemeinsamen Vault-Einträge byte-identisch zu denen des ersten Rechenzentrums sein. Den Vault abzuleiten statt einen neuen zu erzeugen ist das, was dies sicherstellt, siehe Den Vault des zweiten Rechenzentrums ableiten.

Der OpenFGA-Preshared-Key wird gemeinsam genutzt

openFgaPresharedKey muss im Vault jedes Rechenzentrums denselben Wert tragen. OpenFGA akzeptiert nur den Schlüssel im Vault des Rechenzentrums, das es bereitstellt, und weist jede Autorisierungsprüfung von einem Rechenzentrum mit einem anderen Schlüssel als nicht authentifiziert zurück.

oms init install-config und oms update install-config erzeugen einen neuen zufälligen Schlüssel, sobald ein Vault keinen hat. Ein abgeleiteter Vault übernimmt den Schlüssel nur, wenn der Vault von Rechenzentrum 1 bereits einen hatte — andernfalls erzeugt der oms update install-config-Schritt auf Jumpbox 2 still und leise einen zweiten, abweichenden Schlüssel. Dasselbe passiert, wenn der Schlüssel zu 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.

Seine eigene Konfiguration​

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

Es hat auch 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, also ist es auf der eigenen Jumpbox dieses Rechenzentrums 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 hält jeden Lauf dieses Rechenzentrums, auch manuelle Wiederholungsläufe, davon ab, den gemeinsamen Server verwalten zu wollen.

gefahr

Von einer Maschine aus installierte Rechenzentren dürfen sich kein secrets.baseDir teilen.

Der Installer liest den Vault aus diesem Verzeichnis und schreibt Ergebnisse zurück hinein — der kubernetes-Schritt schreibt kubeConfig, der ceph-Schritt schreibt jede Ceph-Zugangsdaten. Wenn eine gemeinsame Jumpbox beide Rechenzentren aus einem Verzeichnis heraus betreibt, ü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 Lauf 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 Knoten dieses Rechenzentrums bereitgestellt wird, sodass unterschiedliche Namen die beiden auch auf den Knoten auseinanderhalten.

Eine separate Age-Identität pro Vault ist nicht zwingend erforderlich, begrenzt aber den Schaden eines durchgesickerten Schlüssels auf ein Rechenzentrum.

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 ist gemeinsam genutzt:

Vault-EintragZugehöriges Konfigurationsfeld
selfSignedCaKeyPemcluster.certificates.ca.certPem
cephSshPrivateKeyceph.cephAdmSshKey.publicKey
acmeEabMacKeycodesphere.certIssuer.acme.eabKeyId
acmeCustomDomainsEabMacKeycodesphere.certIssuer.acme.customDomainsEabKeyId
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 sind an den Vault-Eintrag gekoppelt: Fehlt selfSignedCaKeyPem, wird eine neue Ingress-CA erzeugt und cluster.certificates.ca.certPem überschrieben. Fehlt der Vault-Eintrag, trägt die Konfiguration aber noch das certPem des vorherigen Rechenzentrums, erhältst du einen frischen Schlüssel neben einem veralteten Zertifikat — Ingress liefert dann Zertifikate aus, die von einer CA signiert sind, der niemand vertraut, erkennbar nur als TLS-Fehler im Browser. Dasselbe gilt für cephSshPrivateKey / ceph.cephAdmSshKey.publicKey, für acmeEabMacKey / codesphere.certIssuer.acme.eabKeyId und für acmeCustomDomainsEabMacKey / codesphere.certIssuer.acme.customDomainsEabKeyId.

DNS-Einträge​

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

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

Rechenzentrum 1Rechenzentrum 2
Platform 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

anlegen:

RecordTypZiel
cs.example.com, *.cs.example.comA203.0.113.10
1.cs.example.com, *.1.cs.example.comA203.0.113.10
openfga.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

Der OpenFGA-Host erhält seinen eigenen Record, auch dort, wo bereits ein Wildcard auf ihn zutrifft. Welcher Wildcard zutrifft, hängt davon ab, wie Plattform- und Workspace-Domain ineinander verschachtelt sind, und der für eine Workspace-Domain zeigt auf das Workspace Gateway.

warnung

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

Durch das Anlegen von 2.cs.example.com deckt *.cs.example.com auch keine Namen darunter mehr ab, sodass *.2.cs.example.com ebenfalls explizit angelegt werden muss.

Vor der Installation​

Für die Konfiguration jedes Rechenzentrums prüfen:

  • dataCenter.id und dataCenter.name sind über die gesamte Installation hinweg eindeutig.
  • dataCenters ist vorhanden und in jeder Konfiguration identisch, und defaultDataCenterId benennt eine darin enthaltene ID.
  • Der Rest der gemeinsamen Konfiguration — Domain, Plans, Deploy-Konfiguration, Flags, Provider, Managed Services, Registry — ist in jeder Konfiguration identisch.
  • secrets.baseDir enthält den eigenen 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 verweist.
  • Dieser expose.host hat seinen eigenen A-Record, der auf das Platform Gateway des bereitstellenden Rechenzentrums zeigt, und liegt nicht unter irgendeiner workspaceHostingBaseDomain.
  • Die Workspace-Domains, publicIp, kubernetes.*, ceph.* und beide Gateway-Adressen gehören diesem Rechenzentrum selbst.
  • Die gemeinsamen Vault-Einträge sind byte-identisch; die rechenzentrumsspezifischen sind frisch erzeugt, nicht übernommen.
  • openFgaPresharedKey ist in jedem Vault vorhanden, überall mit demselben Wert.

Validiere anschließend das Dateipaar jedes Rechenzentrums, auf der Jumpbox, die sie hä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, keine zwei aus einem Secrets-Verzeichnis installierten Rechenzentren, keine fehlende dataCenters-Liste und kein abweichendes gemeinsames Secret — das sind die oben genannten Prüfungen.

Weiter​

Mehrere Rechenzentren: Installation.