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 Netzwerk, Nodes, Disks, reservierte Adressen, DNS — genau so vorbereitet wie bei einer Installation mit nur einem 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 zuerst das Rechenzentrum, das PostgreSQL hostet, vollständig, und installiere niemals zwei Rechenzentren parallel. Dessen Installation erstellt die Datenbank, die Rollen und das Schema, das jedes andere Rechenzentrum wiederverwendet. Ein Rechenzentrum, das gegen eine Datenbank installiert wird, die noch nicht existiert, schlägt beim ersten Service fehl, der sich verbindet; zwei gleichzeitige Installationen laufen sich bei denselben Rollen und Schema-Migrationen in die Quere.
"Vollständig" bedeutet, dass die Installation erfolgreich zurückgekehrt ist und die Prüfungen in Die Installation verifizieren für dieses Rechenzentrum bestehen.
Die Dateien anlegen
Jedes Rechenzentrum wird üblicherweise von seiner eigenen Jumpbox aus betrieben, was auch die Topologie ist, von der der Rest dieser Seite ausgeht. Jede Jumpbox enthält dann eine Konfiguration, ein Secrets-Verzeichnis, eine age-Identität und einen Vault — unter denselben Pfaden, weil es unterschiedliche Maschinen sind:
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 erfordert eine Jumpbox pro Rechenzentrum — was erforderlich ist,
ist, dass keine zwei Rechenzentren aus einem Secrets-Verzeichnis installiert werden. Wenn eine einzelne
Jumpbox die gesamte Installation steuert, gib jedem Rechenzentrum seine eigene Konfigurationsdatei und sein
eigenes Verzeichnis dort und verwende diese Pfade überall dort, wo diese Seite
/etc/codesphere/config.yaml oder /etc/codesphere/secrets schreibt:
/etc/codesphere/config.yaml /etc/codesphere/config-dc2.yaml
/etc/codesphere/secrets/ /etc/codesphere/secrets-dc2/
Das gemeinsame Nutzen eines Verzeichnisses zerstört stillschweigend den Vault des ersten Rechenzentrums, siehe seine eigene Konfiguration.
Den Vault des zweiten Rechenzentrums ableiten
Der Vault von Rechenzentrum 2 muss die gemeinsamen Einträge von Rechenzentrum 1 byte-identisch sowie
seine eigenen rechenzentrumsspezifischen Einträge enthalten. Leite ihn ab, anstatt einen von Grund auf neu zu erzeugen:
kopiere, entferne, was zu den Clustern von Rechenzentrum 1 gehört, und lass oms genau diese
neu generieren.
Prüfe zunächst, ob der Vault von Rechenzentrum 1 bereits openFgaPresharedKey enthält. Vaults,
die erstellt wurden, bevor oms diesen Schlüssel generierte, tun dies nicht, und ein abgeleiteter Vault ohne ihn erhält
im Schritt oms update install-config unten einen neuen, anderen Schlüssel — was jeden
OpenFGA-Aufruf von Rechenzentrum 2 aus zunichtemacht. Der Befehl gibt entweder den Namen des Eintrags oder nichts aus:
# On jumpbox 1.
SOPS_AGE_KEY_FILE=/etc/codesphere/secrets/age_key.txt \
sops --decrypt /etc/codesphere/secrets/prod.vault.yaml \
| yq '.secrets[] | select(.name == "openFgaPresharedKey") | .name'
Wenn nichts ausgegeben wird, führe zunächst oms update install-config auf Jumpbox 1 aus, wie
in Das erste Rechenzentrum konfigurieren gezeigt.
Beginne dann auf Jumpbox 2 mit ihrer eigenen age-Identität. Ihr öffentlicher Empfänger ist das, wofür Jumpbox 1 das Ergebnis verschlüsselt, sodass der abgeleitete Vault während der Übertragung nie lesbar ist und der Klartext Jumpbox 1 nie verlässt:
# 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 == "acmeCustomDomainsEabMacKey"
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 einzigen gemeinsam genutzten Jumpbox ist das eine Maschine und ein Schritt weniger: Überspringe die Übertragung und
verschlüssele direkt nach /etc/codesphere/secrets-dc2/prod.vault.yaml, unter Verwendung der
eigenen age-Identität dieses Verzeichnisses.
cephSshPrivateKey wird zusammen mit den anderen ceph*-Namen entfernt, muss aber, anders als die Ceph-
Cluster-Zugangsdaten, vor der Installation wieder vorhanden sein — der Installer benötigt ihn, um
die Ceph-Hosts von Rechenzentrum 2 zu erreichen. selfSignedCaKeyPem ebenso. Das Neugenerieren beider,
zusammen mit den dazugehörigen Konfigurationsfeldern, ist das, was der nächste Schritt tut.
Kopiere die config.yaml von Rechenzentrum 1 auf Jumpbox 2 und bearbeite sie zur Konfiguration von
Rechenzentrum 2, wie in
Mehrere Rechenzentren: Konfiguration beschrieben, einschließlich
des Leerens der Felder, deren Schlüssel gerade entfernt wurden:
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
customDomainsEabKeyId: '' # likewise, for custom-domain certificates
Lass dann auf Jumpbox 2 oms das Fehlende ergänzen. Es generiert jedes fehlende Secret
und schreibt das dazugehörige Konfigurationsfeld, sodass die beiden Hälften nie
inkonsistent zueinander sein 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
Es meldet, was es hinzufügen wird, und fragt vor dem Schreiben nach; --yes bestätigt im Voraus.
Setze SOPS_AGE_KEY_FILE für den Vault, an dem gerade gearbeitet wird, wie oben. Dies hat
Vorrang vor der Identität neben dem Vault, sodass auf einer gemeinsam genutzten Jumpbox ein von
Rechenzentrum 1 übrig gebliebener Wert den Vault von Rechenzentrum 2 für den Empfänger von Rechenzentrum 1
neu verschlüsselt — und eine Jumpbox, die nur ihren eigenen Schlüssel besitzt, kann ihn dann nicht mehr lesen.
Eine External Account Binding kann nicht lokal neu generiert werden: Besorge eine neue von
deiner ACME-CA und setze acmeEabMacKey und codesphere.certIssuer.acme.eabKeyId gemeinsam. Das
Gleiche gilt für acmeCustomDomainsEabMacKey und
codesphere.certIssuer.acme.customDomainsEabKeyId, das eine eigene Bindung benötigt, die sich
von der ersten unterscheidet.
Validiere abschließend das Dateipaar jedes Rechenzentrums, wie in Bevor du installierst beschrieben.
Die Installationen durchführen
Zuerst Rechenzentrum 1, von Jumpbox 1 aus, und erst danach Rechenzentrum 2 von Jumpbox 2 aus. Der Befehl ist auf beiden gleich — jede Jumpbox enthä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 benötigt postgres nicht in der Kommandozeile — operations.skip in seiner
Konfiguration übernimmt das, was einen Kollegen davon abhält, den gemeinsamen Server durch einen manuellen
erneuten Lauf zu berühren. Jeder andere Schritt läuft in jedem Rechenzentrum.
Von einer gemeinsam genutzten Jumpbox aus zeigt jeder Lauf mit -c, -k und --vault auf einen anderen
Satz von Dateien: drei Flags, drei Möglichkeiten, sie zu vertauschen. Das Wiederverwenden des --vault von
Rechenzentrum 1 für Rechenzentrum 2 zerstört den Vault von Rechenzentrum 1; das Wiederverwenden seines -c installiert die
Nodes von Rechenzentrum 2 mit der Identität von Rechenzentrum 1. oms install codesphere protokolliert eine Warnung, wenn
die Konfiguration und der Vault nicht übereinstimmen — ignoriere sie nicht:
Warning: config secrets.baseDir (/etc/codesphere/secrets) does not match the directory of --vault (/etc/codesphere/secrets-dc2)
Sichere jede Konfiguration, jeden verschlüsselten Vault und jede age-Identität in einem zugelassenen Secret-Speicher. Eine age-Identität ist erforderlich, um dessen Rechenzentrum wiederherzustellen oder zu aktualisieren.
Die Installation verifizieren
Führe zunächst die normalen Prüfungen für ein einzelnes Rechenzentrum aus (siehe Den Installer ausführen) in jedem Rechenzentrum, dann die vier unten stehenden Prüfungen.
Jeder Cluster ist eigenständig
Auf einem Control-Plane-Node jedes Rechenzentrums:
/etc/codesphere/deps/kubernetes/files/k0s kubectl get nodes -o wide
Die Node-Liste muss mit den kubernetes.controlPlanes und kubernetes.workers dieses
Rechenzentrums übereinstimmen. Wenn beide Befehle dieselbe Liste zurückgeben, zeigen die beiden Konfigurationen auf
einen Cluster — prüfe kubernetes.apiServerHost und den kubeConfig-Eintrag in jedem Vault.
Die Ceph-Cluster müssen ebenfalls 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-Node jedes Rechenzentrums:
/etc/codesphere/deps/kubernetes/files/k0s kubectl -n codesphere \
get configmap -l codesphere.com/purpose=config \
-o jsonpath='{.items[0].data.dataCenters}'
Jeder Cluster muss dieselbe availableDcs-Liste melden — jedes Rechenzentrum der
Installation — mit currentDc, das auf seine eigene dataCenter.id gesetzt ist. Eine Liste, die nur
das lokale Rechenzentrum enthält, bedeutet, dass dataCenters in dieser Konfiguration weggelassen wurde.
Beide Rechenzentren schreiben in dieselbe Datenbank
Erstelle in jedem Rechenzentrum einen Workspace und frage dann den gemeinsamen Server ab. Jede Workspace- Zeile trägt die ID des Rechenzentrums, in dem sie läuft, sodass eine Zeile pro Rechenzentrum nur möglich ist, 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
Wenn die Workspaces von Rechenzentrum 2 fehlen, sprechen dessen Services mit einer anderen
Datenbank — prüfe postgres.serverAddress in seiner Konfiguration. (codesphere ist der Standard-
Datenbankname; verwende postgres.database, falls die Konfiguration ihn überschreibt.)
Eine Sitzung überspannt Rechenzentren
Die End-to-End-Prüfung, und diejenige, die einen abweichenden tokenPrivateKey oder einen
fehlenden <dc-id>.<codesphere.domain>-DNS-Eintrag erkennt:
- Melde dich unter
https://cs.example.coman. - Wechsle in der Auswahl zum anderen Rechenzentrum. Wenn die Auswahl nur eines anbietet, gehe zur obigen Topologieprüfung zurück.
- Erstelle und öffne dort einen Workspace, ohne dich erneut anzumelden.
- Öffne darin ein Terminal und erreiche es per SSH unter seinem Namen
*.<dc-id>.ssh.<base-domain>.
Eine Weiterleitung zurück zur Anmeldeseite bei Schritt 3 bedeutet, dass sich die Token-Schlüssel zwischen den
Rechenzentren unterscheiden. Ein Verbindungsfehler, bevor eine Oberfläche gerendert wird, bedeutet, dass
<dc-id>.cs.example.com fehlt oder auf das falsche Gateway zeigt.
Den OpenFGA-Preshared-Key in einer laufenden Installation teilen
Eine Installation, die eingerichtet wurde, bevor oms openFgaPresharedKey generierte, hat in keinem
Vault einen Schlüssel. Eine, bei der der Schlüssel durch Ausführen von oms update install-config auf jeder
Jumpbox hinzugefügt wurde, hat in jedem einen anderen Schlüssel. Vergleiche die Vaults per Hash, damit der
Schlüssel niemals in einem Terminal erscheint:
# On every jumpbox.
SOPS_AGE_KEY_FILE=/etc/codesphere/secrets/age_key.txt \
sops --decrypt /etc/codesphere/secrets/prod.vault.yaml \
| yq '.secrets[] | select(.name == "openFgaPresharedKey") | .fields.password' \
| sha256sum
Derselbe Hash überall bedeutet, dass nichts zu tun ist. e3b0c442… ist der Hash eines
leeren Werts: dieser Vault hat keinen Schlüssel.
Behebe dies nicht, indem du oms update install-config auf den Jumpboxes ausführst, denen der
Schlüssel fehlt. Jeder Lauf generiert seinen eigenen Zufallswert, sodass die Rechenzentren am Ende
unterschiedliche Schlüssel haben und OpenFGA alle bis auf einen ablehnt.
Übernimm den Wert aus dem Vault des Rechenzentrums, das OpenFGA bereitstellt. Wenn dieser Vault ebenfalls
keinen Schlüssel hat, generiere dort einen, im selben Format, das oms verwendet:
openssl rand -hex 32
Schreibe diesen Wert in jeden Vault, dem er fehlt oder der einen anderen enthält. sops edit
entschlüsselt den Vault nur im Editor und verschlüsselt ihn beim Speichern erneut:
SOPS_AGE_KEY_FILE=/etc/codesphere/secrets/age_key.txt \
sops edit /etc/codesphere/secrets/prod.vault.yaml
secrets:
# ... existing entries
- name: openFgaPresharedKey
fields:
password: <the 64 hexadecimal characters>
Rolle ihn dann aus, Rechenzentrum für Rechenzentrum: zuerst jedes Rechenzentrum, das OpenFGA nur aufruft, zuletzt das, das es bereitstellt.
-
Wende dessen Plattform erneut an mit
oms install codesphere, wobei die Infrastruktur- Schritte übersprungen werden, wie in Schritt 6 von Ein Rechenzentrum zu einer laufenden Installation hinzufügen. Dies synchronisiert den Vault in den Cluster. In dem Rechenzentrum, das OpenFGA bereitstellt, schaltet dies auch die Authentifizierung von OpenFGA ein, falls sie aus war. -
Erzwinge, dass der Schlüssel aus dem Vault ausgelesen wird. Die ExternalSecrets, die ihn in die Services und in OpenFGA kopieren, lesen den Vault nur alle 24 Stunden neu ein:
# On a control plane node of that data center.KUBECTL="/etc/codesphere/deps/kubernetes/files/k0s kubectl"$KUBECTL -n codesphere get externalsecret -o name | grep openfga-token \| xargs -I{} $KUBECTL -n codesphere annotate {} force-sync="$(date +%s)" --overwrite# Only in the data center that deploys OpenFGA:$KUBECTL -n openfga annotate externalsecret openfga-preshared-keys \force-sync="$(date +%s)" --overwrite -
Starte neu, was den Schlüssel liest. Die Services und OpenFGA lesen ihn nur beim Start ein:
$KUBECTL -n codesphere rollout restart deployment# Only in the data center that deploys OpenFGA:$KUBECTL -n openfga rollout restart deployment
In dem Rechenzentrum, das OpenFGA bereitstellt, schlagen Autorisierungsprüfungen von dem Moment an fehl, in dem Schritt 1 die Authentifizierung einschaltet, bis Schritt 3 die Services neu gestartet hat. Führe die drei Schritte dort unmittelbar nacheinander aus.
Ein Rechenzentrum zu einer laufenden Installation hinzufügen
Das bestehende Rechenzentrum läuft während des gesamten Vorgangs weiter; es benötigt eine Konfigurationsaktualisierung und am Ende einen erneuten Lauf der Plattforminstallation.
-
Plane es. Wähle eine unbenutzte
dataCenter.idund einendataCenter.name, der sich von jedem bestehenden unterscheidet. Reserviere seine drei externen Adressen. -
Bereite seine Infrastruktur vor, wie bei einer Installation mit nur einem Rechenzentrum — einschließlich einer eigenen Jumpbox und der Konnektivität von seinen Nodes zum bestehenden PostgreSQL-Server über TCP 5432.
-
Leite seine Konfiguration und seinen Vault ab von denen des bestehenden Rechenzentrums, wie oben. Das ist der Weg, wie die gemeinsamen Rollen und Token-Schlüssel übertragen werden. Ein bestehendes Rechenzentrum stammt oft aus einer Zeit vor
openFgaPresharedKey; die Prüfung am Anfang dieses Abschnitts erkennt das. -
Aktualisiere DNS. Füge die Einträge des neuen Rechenzentrums hinzu — sowie die
<dc-id>.<codesphere.domain>- Einträge des bestehenden Rechenzentrums und den Eintrag für dasexpose.hostvon OpenFGA, die eine Installation mit nur einem Rechenzentrum nie benötigte. Verifiziere sie von außerhalb des privaten Netzwerks. -
Installiere das neue Rechenzentrum von seiner eigenen Jumpbox aus. Das bestehende hostet bereits PostgreSQL und ist bereits vollständig, sodass die Reihenfolgeregel erfüllt ist.
-
Aktualisiere die Konfiguration des bestehenden Rechenzentrums mit der
dataCenters-Liste, die beide Rechenzentren enthält, unddefaultDataCenterId, und wende dann seine Plattform erneut an: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,kubernetesWenn das neue Rechenzentrum das gemeinsame OpenFGA betreiben soll, setze auch
codesphere.openFga.apiUrlin der Konfiguration des bestehenden Rechenzentrums.Wenn
openFgaPresharedKeyin Schritt 3 nur zum Vault dieses Rechenzentrums hinzugefügt wurde, schaltet diese erneute Anwendung dessen OpenFGA-Authentifizierung ein. Folge unmittelbar mit den Schritten 2 und 3 aus Den OpenFGA-Preshared-Key in einer laufenden Installation teilen. -
Verifiziere mit den obigen Prüfungen. Beide Cluster müssen jetzt beide Rechenzentren melden.
Schritt 6 lässt sich leicht aufschieben und leicht vergessen. Sein Fehlen ist in keiner Gesundheitsprüfung sichtbar: beide Cluster sind grün, beide bedienen ihre eigenen Workspaces, und das einzige Symptom ist, dass Benutzer des bestehenden Rechenzentrums das neue nie in der Auswahl sehen.
Auf GCP testen
Zu Evaluierungszwecken stellt oms beta bootstrap-gcp --multi-dc eine vollständige
Zwei-Rechenzentren-Installation in einem GCP-Projekt bereit und wendet dabei automatisch alles
auf dieser Seite 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 die VPC, die PostgreSQL-VM des Projekts und — anders als bei einem
Produktionssetup — eine einzige Jumpbox; jedes erhält seine eigenen drei Ceph-Nodes, drei k0s-Nodes und drei
statische Adressen. Die Ressourcen von Rechenzentrum 2 tragen daher ein -dc2-Suffix, einschließlich
/etc/codesphere/config-dc2.yaml und /etc/codesphere/secrets-dc2/ auf dieser Jumpbox,
was dem oben beschriebenen Layout mit gemeinsam genutzter Jumpbox entspricht.
Zwei Rechenzentren bedeuten 14 VMs (~100 vCPUs) und 6 regionale statische Adressen, sodass die
Kontingente der Region üblicherweise zuerst erhöht werden müssen. --multi-dc kann nicht mit
--datacenter-id kombiniert werden — die IDs werden abgeleitet (1 und 2), weil sie die
rechenzentrumsspezifischen Domains steuern. Das Bootstrap bedient Workspaces unter <dc-id>.ws.<base-domain>
und SSH unter *.<dc-id>.ssh.cs.<base-domain>, statt dem in den Beispielen dieser Seite
verwendeten Schema; nur die DNS-Einträge und workspaceHostingBaseDomain müssen
miteinander übereinstimmen.
oms beta bootstrap-gcp ist nicht für den Produktivbetrieb bestimmt. Siehe die
bootstrap-gcp-Dokumentation
für die vollständige Liste der Flags.