Mehrere Rechenzentren: Installation
Bevor du beginnst
Eine Konfiguration und ein Vault pro Rechenzentrum, vorbereitet wie in Mehrere Rechenzentren: Konfiguration beschrieben, sowie die Infrastruktur jedes Rechenzentrums — privates Netz, Knoten, Datenträger, reservierte Adressen, DNS — vorbereitet genau wie für eine Installation mit einem einzelnen Rechenzentrum.
Jedes Rechenzentrum wird durch einen eigenen oms install codesphere-Lauf gegen seine
eigene Konfigurationsdatei installiert. Es gibt keinen einzelnen Befehl, der die gesamte
Installation durchführt.
Installationsreihenfolge
Installiere das Rechenzentrum, das PostgreSQL betreibt, zuerst vollständig, und installiere niemals zwei Rechenzentren parallel. Seine Installation legt die Datenbank, die Rollen und das Schema an, die jedes andere Rechenzentrum weiterverwendet. Ein Rechenzentrum, das gegen eine noch nicht existierende Datenbank installiert wird, scheitert am ersten Service, der sich verbindet; zwei gleichzeitige Installationen konkurrieren um dieselben Rollen und Schema-Migrationen.
"Vollständig" heißt, dass die Installation erfolgreich zurückgekehrt ist und die Prüfungen unter Die Installation verifizieren für dieses Rechenzentrum bestehen.
Die Dateien anlegen
Jedes Rechenzentrum wird üblicherweise von seiner eigenen Jumpbox aus betrieben, und genau diese Topologie setzt der Rest dieser Seite voraus. Jede Jumpbox hält dann eine Konfiguration, ein Secrets-Verzeichnis, eine age-Identität und ein Vault — unter denselben Pfaden, denn es sind verschiedene Maschinen:
jumpbox 1 (data center 1) jumpbox 2 (data center 2)
/etc/codesphere/config.yaml /etc/codesphere/config.yaml
/etc/codesphere/secrets/ /etc/codesphere/secrets/
age_key.txt age_key.txt (its own identity)
prod.vault.yaml prod.vault.yaml (derived from jumpbox 1's)
install -d -m 0700 /etc/codesphere/secrets # on each jumpbox
Nichts an der Installation verlangt eine Jumpbox pro Rechenzentrum — verlangt wird, dass
keine zwei Rechenzentren aus einem Secrets-Verzeichnis installiert werden. Betreibt
eine einzelne Jumpbox die gesamte Installation, gib jedem Rechenzentrum dort seine eigene
Konfigurationsdatei und sein eigenes Verzeichnis, und verwende diese Pfade überall dort,
wo auf dieser Seite /etc/codesphere/config.yaml oder /etc/codesphere/secrets steht:
/etc/codesphere/config.yaml /etc/codesphere/config-dc2.yaml
/etc/codesphere/secrets/ /etc/codesphere/secrets-dc2/
Ein gemeinsames Verzeichnis zerstört das Vault des ersten Rechenzentrums stillschweigend, siehe Seine eigene Konfiguration.
Das Vault des zweiten Rechenzentrums ableiten
Das Vault von Rechenzentrum 2 muss die geteilten Einträge von Rechenzentrum 1
byte-identisch tragen und seine eigenen rechenzentrumsspezifischen Einträge enthalten.
Leite es ab, statt eines von Grund auf zu erzeugen: kopieren, alles entfernen, was zu den
Clustern von Rechenzentrum 1 gehört, und oms genau das neu erzeugen lassen.
Beginne auf Jumpbox 2, mit ihrer eigenen age-Identität. Ihr öffentlicher Empfänger ist das, wofür Jumpbox 1 das Ergebnis verschlüsselt — so ist das abgeleitete Vault während der Übertragung nie lesbar und der Klartext verlässt Jumpbox 1 nie:
# On jumpbox 2.
install -d -m 0700 /etc/codesphere/secrets
age-keygen -o /etc/codesphere/secrets/age_key.txt
chmod 0600 /etc/codesphere/secrets/age_key.txt
age-keygen -y /etc/codesphere/secrets/age_key.txt # age1... — take this along
# On jumpbox 1.
umask 077
# 1. Data center 1's vault as a starting point.
SOPS_AGE_KEY_FILE=/etc/codesphere/secrets/age_key.txt \
sops --decrypt /etc/codesphere/secrets/prod.vault.yaml > /tmp/dc2.vault.yaml
# 2. Drop everything that belongs to data center 1's clusters.
yq -i 'del(.secrets[] | select(.name | test("^(ceph|csi|rgw)")))' /tmp/dc2.vault.yaml
yq -i 'del(.secrets[] | select(.name == "selfSignedCaKeyPem"
or .name == "kubeConfig"
or .name == "acmeEabMacKey"
or .name == "privNixSigningKey"
or .name == "pubNixSigningKey"))' /tmp/dc2.vault.yaml
# 3. Encrypt to jumpbox 2's recipient and hand it over.
sops --encrypt --age age1... /tmp/dc2.vault.yaml > /tmp/dc2.vault.enc.yaml
shred -u /tmp/dc2.vault.yaml
scp /tmp/dc2.vault.enc.yaml jumpbox2:/etc/codesphere/secrets/prod.vault.yaml
shred -u /tmp/dc2.vault.enc.yaml
Auf einer einzelnen gemeinsamen Jumpbox ist das eine Maschine und ein Schritt weniger:
lass die Übertragung weg und verschlüssele direkt nach
/etc/codesphere/secrets-dc2/prod.vault.yaml, mit der age-Identität dieses
Verzeichnisses.
cephSshPrivateKey wird zusammen mit den übrigen ceph*-Namen entfernt, muss aber —
anders als die Ceph-Cluster-Zugangsdaten — vor der Installation wieder vorhanden sein:
der Installer braucht ihn, um die Ceph-Hosts von Rechenzentrum 2 zu erreichen. Für
selfSignedCaKeyPem gilt dasselbe. Beide neu zu erzeugen, zusammen mit den zugehörigen
Konfigurationsfeldern, ist genau das, was der nächste Schritt tut.
Kopiere die config.yaml von Rechenzentrum 1 auf Jumpbox 2 und passe sie zur
Konfiguration von Rechenzentrum 2 an, wie in
Mehrere Rechenzentren: Konfiguration
beschrieben — einschließlich des Leerens der drei Felder, deren Schlüssel du gerade
entfernt hast:
cluster:
certificates:
ca:
certPem: '' # regenerated with selfSignedCaKeyPem
ceph:
cephAdmSshKey:
publicKey: '' # regenerated with cephSshPrivateKey
codesphere:
certIssuer:
acme:
eabKeyId: '' # only if you use ACME with external account binding
Lass anschließend auf Jumpbox 2 oms ergänzen, was fehlt. Es erzeugt jedes fehlende
Secret und schreibt das zugehörige Konfigurationsfeld, sodass die beiden Hälften nie
auseinanderlaufen können:
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 Befehl zeigt an, was er hinzufügen will, und fragt vor dem Schreiben nach; --yes
stimmt vorab zu.
warnung
Setze SOPS_AGE_KEY_FILE wie oben für das Vault, an dem du gerade arbeitest. Die
Variable hat Vorrang vor der Identität neben dem Vault; auf einer gemeinsamen Jumpbox
verschlüsselt ein von Rechenzentrum 1 übriggebliebener Wert das Vault von
Rechenzentrum 2 also für den Empfänger von Rechenzentrum 1 — und eine Jumpbox, die nur
ihren eigenen Schlüssel hat, kann es dann nicht mehr lesen.
Ein External Account Binding lässt sich nicht lokal neu erzeugen: hole ein neues von
deiner ACME-CA und setze acmeEabMacKey und codesphere.certIssuer.acme.eabKeyId
gemeinsam.
Validiere zum Schluss das Dateipaar jedes Rechenzentrums, wie unter Vor der Installation beschrieben.
Die Installationen durchführen
Rechenzentrum 1 zuerst, von Jumpbox 1 aus, und erst danach Rechenzentrum 2 von Jumpbox 2 aus. Der Befehl ist auf beiden derselbe — jede Jumpbox hält nur die Dateien ihres eigenen Rechenzentrums:
# On jumpbox 1: the data center that hosts PostgreSQL. Must finish and verify first.
# Then the same command on jumpbox 2.
oms install codesphere \
-c /etc/codesphere/config.yaml \
-k /etc/codesphere/secrets/age_key.txt \
--vault /etc/codesphere/secrets/prod.vault.yaml \
-p codesphere-<version>-installer-lite.tar.gz \
-s load-container-images
Rechenzentrum 2 braucht postgres nicht auf der Kommandozeile — operations.skip in
seiner Konfiguration trägt es bereits, und genau das verhindert, dass ein manueller Lauf
einer Kollegin den geteilten Server anfasst. Jeder andere Schritt läuft in jedem
Rechenzentrum.
warnung
Von einer gemeinsamen Jumpbox aus richtet jeder Lauf -c, -k und --vault auf einen
anderen Satz Dateien: drei Flags, drei Gelegenheiten, sie zu verwechseln. Das --vault
von Rechenzentrum 1 für Rechenzentrum 2 wiederzuverwenden beschädigt das Vault von
Rechenzentrum 1; sein -c wiederzuverwenden installiert die Knoten von Rechenzentrum 2
mit der Identität von Rechenzentrum 1. oms install codesphere gibt eine Warnung aus,
wenn Konfiguration und Vault nicht zusammenpassen — ignoriere sie nicht:
Warning: config secrets.baseDir (/etc/codesphere/secrets) does not match the directory of --vault (/etc/codesphere/secrets-dc2)
Sichere jede Konfiguration, jedes verschlüsselte Vault und jede age-Identität in einem freigegebenen Secret-Store. Ohne die age-Identität lässt sich ihr Rechenzentrum weder wiederherstellen noch aktualisieren.
Die Installation verifizieren
Führe zuerst in jedem Rechenzentrum die üblichen Prüfungen für ein einzelnes Rechenzentrum durch (siehe Den Installer ausführen), danach die vier Prüfungen unten.
Jedes Cluster steht für sich
Auf einem Control-Plane-Knoten jedes Rechenzentrums:
/etc/codesphere/deps/kubernetes/files/k0s kubectl get nodes -o wide
Die Knotenliste muss zu kubernetes.controlPlanes und kubernetes.workers dieses
Rechenzentrums passen. Liefern beide Befehle dieselbe Liste, zeigen die beiden
Konfigurationen auf ein Cluster — prüfe kubernetes.apiServerHost und den Eintrag
kubeConfig in jedem Vault.
Auch die Ceph-Cluster müssen getrennt sein. Ihre FSIDs müssen sich unterscheiden:
grep fsid /etc/ceph/ceph.conf # on each data center's Ceph master
Zwei identische FSIDs bedeuten, dass sich die Rechenzentren ein secrets.baseDir geteilt
haben und eine Installation die Ceph-Zugangsdaten der anderen überschrieben hat.
Beide Rechenzentren kennen die vollständige Topologie
Auf einem Control-Plane-Knoten jedes Rechenzentrums:
/etc/codesphere/deps/kubernetes/files/k0s kubectl -n codesphere \
get configmap -l codesphere.com/purpose=config \
-o jsonpath='{.items[0].data.dataCenters}'
Jedes Cluster muss dieselbe availableDcs-Liste melden — jedes Rechenzentrum der
Installation — mit currentDc auf seiner eigenen dataCenter.id. Eine Liste, die nur
das lokale Rechenzentrum enthält, bedeutet, dass dataCenters in dieser Konfiguration
fehlt.
Beide Rechenzentren schreiben in dieselbe Datenbank
Lege in jedem Rechenzentrum einen Workspace an und frage dann den geteilten Server ab. Jede Workspace-Zeile trägt die ID des Rechenzentrums, in dem sie läuft; je eine Zeile pro Rechenzentrum ist also nur möglich, wenn beide Cluster in dieselbe Datenbank schreiben:
psql "host=10.10.0.10 port=5432 dbname=codesphere user=postgres sslmode=verify-full" \
-c 'select data_center_id, count(*)
from "workspaceService".workspaces
group by data_center_id
order by data_center_id;'
data_center_id | count
----------------+-------
1 | 1
2 | 1
Fehlen die Workspaces von Rechenzentrum 2, sprechen dessen Services mit einer anderen
Datenbank — prüfe postgres.serverAddress in seiner Konfiguration. (codesphere ist der
Standardname der Datenbank; nutze postgres.database, falls die Konfiguration ihn
überschreibt.)
Eine Sitzung überschreitet Rechenzentrumsgrenzen
Die Ende-zu-Ende-Prüfung, und diejenige, die einen abweichenden tokenPrivateKey oder
einen fehlenden <dc-id>.<codesphere.domain>-DNS-Eintrag aufdeckt:
- Melde dich unter
https://cs.example.coman. - Wechsle in der Auswahl zum anderen Rechenzentrum. Wird nur eines angeboten, geh zurück zur Topologie-Prüfung oben.
- Lege dort einen Workspace an und öffne ihn, ohne dich erneut anzumelden.
- Öffne darin ein Terminal und erreiche ihn per SSH unter seinem Namen
*.<dc-id>.ssh.<base-domain>.
Eine Weiterleitung zurück zur Anmeldeseite in Schritt 3 bedeutet, dass sich die
Token-Schlüssel zwischen den Rechenzentren unterscheiden. Ein Verbindungsfehler, bevor
irgendeine Oberfläche erscheint, bedeutet, dass <dc-id>.cs.example.com fehlt oder auf
das falsche Gateway zeigt.
Ein Rechenzentrum zu einer laufenden Installation hinzufügen
Das bestehende Rechenzentrum läuft durchgehend weiter; es braucht am Ende eine Konfigurationsänderung und einen erneuten Lauf seiner Plattform-Installation.
-
Planen. Wähle eine ungenutzte
dataCenter.idund einendataCenter.name, der sich von jedem bestehenden unterscheidet. Reserviere seine drei externen Adressen. -
Infrastruktur vorbereiten wie für eine Installation mit einem einzelnen Rechenzentrum — einschließlich seiner eigenen Jumpbox und der Erreichbarkeit des bestehenden PostgreSQL-Servers von seinen Knoten aus über TCP 5432.
-
Konfiguration und Vault ableiten von denen des bestehenden Rechenzentrums, wie oben. Das ist es, was die geteilten Rollen und Token-Schlüssel hinüberträgt.
-
DNS aktualisieren. Ergänze die Einträge des neuen Rechenzentrums — und die
<dc-id>.<codesphere.domain>-Einträge des bestehenden Rechenzentrums, die eine Installation mit einem einzelnen Rechenzentrum nie brauchte. Prüfe sie von außerhalb des privaten Netzes. -
Das neue Rechenzentrum installieren, von seiner eigenen Jumpbox aus. Das bestehende betreibt PostgreSQL bereits und ist bereits vollständig, die Reihenfolgeregel ist also erfüllt.
-
Die Konfiguration des bestehenden Rechenzentrums aktualisieren um die
dataCenters-Liste mit beiden Rechenzentren unddefaultDataCenterId, dann seine Plattform erneut ausrollen:oms install codesphere \-c /etc/codesphere/config.yaml \-k /etc/codesphere/secrets/age_key.txt \--vault /etc/codesphere/secrets/prod.vault.yaml \-p codesphere-<version>-installer-lite.tar.gz \-s copy-dependencies,extract-dependencies,load-container-images,docker,postgres,ceph,kubernetesSoll das neue Rechenzentrum die geteilte OpenFGA-Instanz betreiben, setze zusätzlich
codesphere.openFga.apiUrlin der Konfiguration des bestehenden Rechenzentrums. -
Verifizieren mit den Prüfungen oben. Beide Cluster müssen nun beide Rechenzentren melden.
warnung
Schritt 6 wird leicht aufgeschoben und leicht vergessen. Sein Fehlen ist in jeder Gesundheitsprüfung unsichtbar: beide Cluster sind grün, beide bedienen ihre eigenen Workspaces, und das einzige Symptom ist, dass die Nutzenden des bestehenden Rechenzentrums das neue nie in der Auswahl sehen.
Auf GCP testen
Zur Evaluierung stellt oms beta bootstrap-gcp --multi-dc eine vollständige Installation
mit zwei Rechenzentren in einem GCP-Projekt bereit und wendet alles auf dieser Seite
automatisch an:
oms beta bootstrap-gcp \
--project-name multidc-test \
--billing-account "$BILLING_ACCOUNT" \
--base-domain oms-testing.example.com \
--multi-dc \
--datacenter-name multidc \
--install-version <version>
Die Rechenzentren teilen sich VPC und PostgreSQL-VM des Projekts sowie — anders als ein
Produktivaufbau — eine einzelne Jumpbox; jedes erhält seine eigenen drei Ceph-Knoten,
drei k0s-Knoten und drei statischen Adressen. Die Ressourcen von Rechenzentrum 2 tragen
deshalb das Suffix -dc2, darunter /etc/codesphere/config-dc2.yaml und
/etc/codesphere/secrets-dc2/ auf dieser Jumpbox — die oben beschriebene Ablage für eine
gemeinsame Jumpbox.
Zwei Rechenzentren bedeuten 14 VMs (~100 vCPUs) und 6 regionale statische Adressen, die
Quotas der Region müssen also meist zuerst erhöht werden. --multi-dc lässt sich nicht
mit --datacenter-id kombinieren — die IDs werden abgeleitet (1 und 2), weil sie die
rechenzentrumsspezifischen Domains bestimmen. Der Bootstrap bedient Workspaces unter
<dc-id>.ws.<base-domain> und SSH unter *.<dc-id>.ssh.cs.<base-domain> statt nach dem
Schema der Beispiele auf dieser Seite; nur die DNS-Einträge und
workspaceHostingBaseDomain müssen zueinander passen.
oms beta bootstrap-gcp ist nicht für den Produktivbetrieb gedacht. Die vollständige
Flag-Liste steht in der
bootstrap-gcp-Dokumentation.