Multi-Cluster-Bereitstellung für Spanner Omni in Kubernetes erstellen

In diesem Dokument wird beschrieben, wie Sie eine Spanner Omni-Bereitstellung in mehreren Kubernetes-Clustern einrichten. Sie können Spanner Omni mit oder ohne TLS-Verschlüsselung bereitstellen. Wenn Sie die Verschlüsselung verwenden, nutzt Spanner Omni Transport Layer Security (TLS) 1.3, um die Kommunikation innerhalb der Bereitstellung und mit den Clients zu verschlüsseln und zu authentifizieren.

Eine Bereitstellung ohne TLS-Verschlüsselung birgt die folgenden Sicherheitsrisiken:

  • Jeder kann auf die Bereitstellung zugreifen, wenn er die IP-Adresse erreichen kann.
  • Es gibt keine Netzwerkverschlüsselung zwischen dem Client und dem Server oder zwischen den Pods.

Aufgrund dieser Risiken sollten Sie Bereitstellungen vermeiden, die nicht mit TLS-Verschlüsselung für Produktionsumgebungen konfiguriert sind.

Hinweis

Zur Vorbereitung auf das Deployment müssen Sie die folgenden Anforderungen erfüllen:

  • Erstellen Sie für Ihr Deployment mehrere Kubernetes-Cluster an jedem Standort. Cluster können zonal sein, wenn Sie nur in einer Zone in diesem Cluster bereitstellen. Spanner Omni unterstützt die Helm-Chart-Konfiguration für Google Kubernetes Engine- (GKE) und Amazon Elastic Kubernetes Service-Umgebungen (Amazon EKS). Für andere Umgebungen sind möglicherweise benutzerdefinierte Konfigurationen erforderlich.

  • Zugriff auf das in Artifact Registry gehostete Container-Image erhalten

  • Installieren und konfigurieren Sie das kubectl-Befehlszeilentool und Helm.

  • Wenn Sie die Kubernetes-Umgebung auf Maschinen der vSphere-Virtualisierungsplattform einrichten, deaktivieren Sie die TSC-Virtualisierung (Time Stamp Counter), indem Sie monitor_control.virtual_rdtsc = FALSE in die Konfigurationsdatei .vmx der virtuellen Maschine einfügen. So kann TrueTime richtig funktionieren.

  • Konfigurieren Sie das Kubernetes-Clusternetzwerk so, dass Pods in einem Cluster eine Verbindung zu Pods in einem anderen Cluster herstellen können. Standardmäßig verwendet Spanner Omni die TCP-Ports 15000 bis 15025 für die interne Kommunikation. Damit die Kommunikation zwischen Pods in diesen Clustern möglich ist, müssen Sie diese Ports für Traffic öffnen.

  • Konfigurieren Sie das Cluster-DNS so, dass der Hostname eines Pods, z. B. spanner-a-0.pod.spanner-ns-r1, in seine IP-Adresse aufgelöst wird. Für Spanner Omni ist die Hostnamensauflösung für TCP-Verbindungen zwischen Pods in verschiedenen Clustern erforderlich.

Helm-Diagrammkonfiguration vorbereiten

Erstellen Sie eine Helm-Konfiguration. Weitere Informationen finden Sie unter Helm-Konfiguration erstellen.

Die Anzahl der Root-Server pro Zone muss eine ungerade Zahl zwischen 1 und 9 (einschließlich) sein, um die Konsistenz zu gewährleisten. Wenn die Anzahl der Server eine gerade Zahl ist, können Bereitstellungen fehlschlagen. Weisen Sie beim Konfigurieren Ihrer Zonen Server als Stammserver zu. Wir empfehlen, eine für die Entwicklung oder das Testen und drei für hochverfügbare Produktionszonen zu verwenden.

Da es sich um eine Multi-Cluster-Bereitstellung handelt, muss Ihre Helm-Konfigurations-YAML-Datei Folgendes enthalten:

# This is required for a multi-cluster deployment setup.

deployment:
  multiCluster: true

Beispiel für die Helm-Diagrammkonfiguration für die Multi-Cluster-Bereitstellung

Das Folgende ist ein Beispiel für ein Helm-Diagramm, das für eine Spanner Omni-Bereitstellung mit mehreren Clustern konfiguriert ist. Bei dieser Konfiguration wird eine Bereitstellung in drei Google Cloud Regionen erstellt: us-west1, us-west2 und us-west3. Die Bereitstellung erfolgt über fünf Zonen, wobei jede Zone ein Replikat darstellt. Die Replikate in us-west1 und us-west2 sind Lese-/Schreibreplikate, während das einzelne Replikat in us-west3 ein Zeugenreplikat ist.

# The platform of the deployment
global:
  platform: gke

# This is required for a multi-cluster deployment setup.
deployment:
  multiCluster: true

# Locations and zones where clusters are created for the deployment
locations:
  - name: us-west1
    namespace: spanner-ns-usw1
    zones:
      - name: "us-west1-a"
        shortName: "a"
      - name: "us-west1-b"
        shortName: "b"
  - name: us-west2
    namespace: spanner-ns-usw2
    zones:
      - name: "us-west2-a"
        shortName: "a"
      - name: "us-west2-b"
        shortName: "b"
  - name: us-west3
    namespace: spanner-ns-usw3
    zones:
      - name: "us-west3-a"
        shortName: "a"
        replicaType: WITNESS

# Remaining configuration like storage, resources, isn't included in this sample.

kubectl für die Verbindung mit mehreren Clustern konfigurieren

Bevor Sie fortfahren, erstellen Sie Cluster mit kubectl-Kontexten. In der YAML-Datei für die Helm-Konfiguration können Sie die Kontexte beispielsweise nach dem Standort benennen, z. B. ctx-usw1, ctx-usw2 und ctx-usw3.

TLS-Verschlüsselung konfigurieren

Wenn Sie eine Bereitstellung ohne Verschlüsselung einrichten, fahren Sie mit Helm-Diagramm für jeden Cluster installieren fort.

Wenn Sie die TLS-Verschlüsselung für eine Bereitstellung mit mehreren Clustern konfigurieren möchten, müssen Sie eine Zertifizierungsstelle (Certificate Authority, CA) erstellen und Zertifikate für jeden Cluster generieren. Weitere Informationen finden Sie unter TLS-Verschlüsselung für Ihre Kubernetes-Bereitstellung hinzufügen.

Zertifikate generieren

Erstellen Sie die CA und die Zertifikate für den Server und die API. Die Server- und API-Zertifikate müssen die Hosts aller Cluster enthalten.

Spanner Omni-Serverzertifikat erstellen

Die Spanner Omni-Server verwenden Serverzertifikate, um die Kommunikation zwischen Servern zu verschlüsseln.

Führen Sie den folgenden Befehl aus, um das Serverzertifikat zu erstellen. Ersetzen Sie SERVER_LIST durch eine durch Kommas getrennte Liste von FQDNs für Spanner Omni-Server-Pods oder verwenden Sie Platzhalter.

SERVER_NAMES=*.pod.spanner-ns-usw1,*.pod.spanner-ns-usw2,*.pod.spanner-ns-usw3
Spanner Omni CLI certificates create-server --hostnames=${SERVER_NAMES} --ca-certificate-directory certs --output-directory certs

API-Zertifikat erstellen

API-Zertifikate verschlüsseln die Kommunikation von Systemen, die mit der Bereitstellung interagieren.

Führen Sie den folgenden Befehl aus, um das API-Zertifikat zu erstellen. Ersetzen Sie OMNI_ENDPOINT durch die Dienstendpunkte für jeden Cluster.

OMNI_ENDPOINT=spanner.spanner-ns-usw1,spanner.spanner-ns-usw2,spanner.spanner-ns-usw3
Spanner Omni CLI certificates create-server --filename-prefix=api --hostnames=${OMNI_ENDPOINT} --ca-certificate-directory certs --output-directory certs

Zertifikate in jeden Kubernetes-Cluster übertragen

Erstellen Sie für jeden Cluster den Namespace und ein generisches Secret, das die Zertifikate enthält.

# Repeat for each context (for example, ctx-usw1, ctx-usw2, ctx-usw3)
# Replace NAMESPACE with the appropriate namespace for each region

kubectl create namespace <var>NAMESPACE</var> --context <var>CONTEXT</var>
kubectl create secret generic tls-certs \
  --from-file=ca.crt="certs/ca.crt" \
  --from-file=ca-api.crt="certs/ca-api.crt" \
  --from-file=server.crt="certs/server.crt" \
  --from-file=server.key="certs/server.key" \
  --from-file=api.crt="certs/api.crt" \
  --from-file=api.key="certs/api.key" \
  -n <var>NAMESPACE</var> \
  --context <var>CONTEXT</var>

Helm-Diagramm für jeden Cluster installieren

Erstellen Sie eine Helm-Konfiguration. Weitere Informationen finden Sie unter Helm-Konfiguration erstellen.

Bei einer Multi-Cluster-Bereitstellung wenden Sie die Helm-Diagrammkonfiguration aus Ihrer Helm-Konfigurationsdatei auf jeden Kubernetes-Cluster an. Richten Sie jeden Befehl auf einen bestimmten Standort und seinen Namespace aus, um ihn an die Spanner Omni-Bereitstellung zu binden. Wenden Sie die Konfiguration auf jeden Speicherort in derselben Reihenfolge an, wie in Ihrer Helm-Konfigurationsdatei aufgeführt. Wenn Sie die Konfiguration auf den endgültigen Standort anwenden, wird in diesem Cluster ein Bootstrap-Job für die Bereitstellung erstellt.

Bevor Sie Helm für jeden Cluster installieren, erstellen Sie den Monitoring-Namespace in dem Cluster, in dem Sie den Observability-Stack hosten möchten:

kubectl create namespace monitoring --context ctx-usw1

Beispiele für Helm-Diagramm-Installationsbefehle

Mit den folgenden Befehlen wird ein Helm-Diagramm in Clustern installiert. In jedem Befehl ist PATH_TO_HELM_CONFIG_FILE der Pfad zur YAML-Datei für die Helm-Diagrammkonfiguration, die Sie für Ihr Deployment erstellt haben.

Diagramm in us-west1 mit aktiviertem Monitoring installieren

helm upgrade --install spanner-omni oci://us-docker.pkg.dev/spanner-omni/charts/spanner-omni --version 1.0.0 \
  -f PATH_TO_HELM_CONFIG_FILE \
  --namespace spanner-ns-usw1 \
  --set currentLocation=us-west1 \
  --set monitoring.enabled=true \
  --create-namespace \
  --kube-context ctx-usw1

Diagramm in us-west2 ohne Monitoring installieren

helm upgrade --install spanner-omni oci://us-docker.pkg.dev/spanner-omni/charts/spanner-omni --version 1.0.0 \
  -f  PATH_TO_HELM_CONFIG_FILE \
  --namespace spanner-ns-usw2 \
  --set currentLocation=us-west2 \
  --create-namespace \
  --kube-context ctx-usw2

Diagramm in us-west3 ohne Monitoring installieren

helm upgrade --install spanner-omni oci://us-docker.pkg.dev/spanner-omni/charts/spanner-omni --version 1.0.0 \
  -f  PATH_TO_HELM_CONFIG_FILE \
  --namespace spanner-ns-usw3 \
  --set currentLocation=us-west3 \
  --create-namespace \
  --kube-context ctx-usw3

Bereitstellungsfortschritt verfolgen

Nachdem Sie die Helm-Diagrammkonfiguration angewendet haben, wird in jedem Kubernetes-Cluster ein Bootstrap-Job gestartet. Nachdem der Bootstrap-Job im letzten Cluster gestartet wurde, führen Sie den folgenden Befehl aus, um den Bereitstellungsprozess zu verfolgen:

kubectl logs -n spanner-ns-usw3 -l app.kubernetes.io/component=bootstrap -f

Wenn die Logs darauf hinweisen, dass die Bereitstellung nicht alle Server erreichen kann, prüfen Sie, ob der DNS-Dienst in jedem Cluster richtig konfiguriert ist.

Cluster-DNS-Dienst konfigurieren

Wenn Sie externes DNS mit Ihrem Kubernetes-Cluster verwenden und damit DNS-Einträge für Headless-Dienste verwalten, können Sie diesen Schritt überspringen.

Spanner verwendet den Pod-Hostnamen für die gesamte interne Kommunikation. Konfigurieren Sie das DNS so, dass Pods Hostnamen auch dann auflösen können, wenn sie in verschiedenen Kubernetes-Clustern ausgeführt werden. Dazu müssen Sie den kube-dns-Dienst in jedem Cluster verfügbar machen, damit andere Cluster ihn durch Ausführen des dns-setup.sh-Scripts erreichen können.

Mit diesem Skript wird in jedem Cluster ein Load-Balancer-Dienst für die kube-dns-Anwendung bereitgestellt und die DNS-Konfiguration wird so aktualisiert, dass sie auf die Load-Balancer-Dienste verweist. Während dns-setup.sh kube-dns und CoreDNS in GKE und Amazon EKS konfiguriert, müssen Sie sie möglicherweise für Ihre Umgebung konfigurieren.

So konfigurieren Sie den Cluster-DNS-Dienst:

  1. Laden Sie das dns-setup.sh-Skript aus dem spanner-omni Cloud Storage-Bucket herunter, falls noch nicht geschehen.

    Spanner Omni-Bucket aufrufen

  2. Führen Sie das Skript dns-setup.sh aus:

    dns-setup.sh -n CSV_NAME_SPACE_LIST CONTEXTS
    
    • Ersetzen Sie CSV_NAME_SPACE_LIST durch eine kommagetrennte Liste Ihrer Namespaces.

    • Ersetzen Sie CONTEXTS durch eine Liste Ihrer Kontexte.

    Hier ist ein Beispiel für die Verwendung des dns-setup.sh-Skripts:

    dns-setup.sh -n spanner-ns-usw1,spanner-ns-usw2,spanner-ns-usw3 ctx-usw1 ctx-usw2 ctx-usw3
    

Prüfen Sie nach dem Ausführen des Skripts die Logs des Bereitstellungsjobs. Meldungen weisen darauf hin, dass die Bereitstellung fortschreitet, und die Meldung Deployment created successfully wird angezeigt.

API-Zertifikat aktualisieren

Wenn Sie die Bereitstellung ohne TLS-Verschlüsselung einrichten, fahren Sie mit Interaktion mit Spanner Omni fort.

Um die TLS-Verschlüsselung zu implementieren, müssen Sie das API-Zertifikat mit den externen IP-Adressen oder DNS-Namen der Load Balancer für jeden Cluster aktualisieren. So können Clients über sichere Kanäle eine Verbindung zur Bereitstellung herstellen.

  1. Rufen Sie die Dienstdetails für jeden Cluster ab:

    kubectl get service spanner -n spanner-ns-usw1 --context ctx-usw1
    kubectl get service spanner -n spanner-ns-usw2 --context ctx-usw2
    kubectl get service spanner -n spanner-ns-usw3 --context ctx-usw3
    
  2. Aktualisieren Sie das API-Zertifikat mit den externen IP-Adressen:

    # Replace <var>EXTERNAL_IP_USW1</var>, <var>EXTERNAL_IP_USW2</var>, and <var>EXTERNAL_IP_USW3</var>
    # with the actual external IP addresses or DNS names.
    
    OMNI_ENDPOINT=<var>EXTERNAL_IP_USW1</var>,<var>EXTERNAL_IP_USW2</var>,<var>EXTERNAL_IP_USW3</var>,spanner.spanner-ns.svc
    Spanner Omni CLI certificates update --filename_prefix=api --hostnames=${OMNI_ENDPOINT} --ca-certificate-directory certs --output_directory certs --overwrite
    
  3. Aktualisieren Sie die Secrets in jedem Kubernetes-Cluster mit dem neuen API-Zertifikat:

    # Repeat for each context
    kubectl patch secret tls-certs -n spanner-ns-usw1 --context ctx-usw1 -p "{\"data\":{\"api.crt\":\"$(base64 -w 0 certs/api.crt)\"}}"
    kubectl patch secret tls-certs -n spanner-ns-usw2 --context ctx-usw2 -p "{\"data\":{\"api.crt\":\"$(base64 -w 0 certs/api.crt)\"}}"
    kubectl patch secret tls-certs -n spanner-ns-usw3 --context ctx-usw3 -p "{\"data\":{\"api.crt\":\"$(base64 -w 0 certs/api.crt)\"}}"
    

Mit Spanner Omni interagieren

Jeder Cluster in einer Multi-Cluster-Einrichtung hat einen Load-Balancer-Dienst. Sie können jede der externen IP-Adressen des Dienstes verwenden, um mit Spanner Omni zu interagieren. Verwenden Sie für Schreibvorgänge und strikte Lesevorgänge die Adresse, die als führende Region fungiert. Verwenden Sie für Anfragen für Lesevorgänge veralteter Daten die Region, die Ihrer Anwendung am nächsten ist, um eine optimale Leistung zu erzielen.

  1. Führen Sie den folgenden Befehl aus, um die Dienstadresse abzurufen:

    kubectl get service spanner -n spanner-ns-usw1 --context ctx-usw1
    

    EXTERNAL-IP:PORT ist die DEPLOYMENT_ENDPOINT für Ihr Deployment.

  2. Laden Sie die Spanner Omni CLI aus dem Cloud Storage-Bucket spanner-omni herunter, falls noch nicht geschehen.

    Spanner Omni-Bucket aufrufen

  3. Wenn Sie ein Deployment mit TLS-Verschlüsselung erstellt haben, müssen Sie das CA-Zertifikat in jeden Befehl einfügen, um eine verschlüsselte Verbindung herzustellen. Wenn Sie mTLS für Clients aktiviert haben, fügen Sie auch das Clientzertifikatsverzeichnis hinzu.

    • --ca-certificate-file=certs/ca-api.crt
    • --client-certificate-directory=clientcerts
  4. Mit der Spanner Omni CLI können Sie eine GoogleSQL- oder PostgreSQL-Datenbank erstellen und mit ihr interagieren.

    GoogleSQL

    Führen Sie Folgendes aus, um eine GoogleSQL-Datenbank zu erstellen und mit ihr zu interagieren:

    Spanner Omni CLI databases create DATABASE_NAME \
      --deployment-endpoint=dns:///DEPLOYMENT_ENDPOINT \
      --ca-certificate-file=certs/ca-api.crt
    Spanner Omni CLI sql --database=DATABASE_NAME \
      --deployment-endpoint=dns:///DEPLOYMENT_ENDPOINT \
      --ca-certificate-file=certs/ca-api.crt
    

    PostgreSQL

    Führen Sie Folgendes aus, um eine PostgreSQL-Datenbank zu erstellen und mit ihr zu interagieren:

    Spanner Omni CLI databases create POSTGRESQL_DATABASE_NAME \
      --database_dialect POSTGRESQL \
      --deployment-endpoint=dns:///DEPLOYMENT_ENDPOINT \
      --ca-certificate-file=certs/ca-api.crt
    Spanner Omni CLI sql --database=POSTGRESQL_DATABASE_NAME \
      --deployment-endpoint=dns:///DEPLOYMENT_ENDPOINT \
      --ca-certificate-file=certs/ca-api.crt
    

    Sie können auch mit einer PostgreSQL-Datenbank interagieren, indem Sie der Anleitung unter Mit PGAdapter verbinden folgen, um PGAdapter zu konfigurieren und PostgreSQL-Tools wie psql mit Ihren Datenbanken im PostgreSQL-Dialekt zu verwenden.

Nächste Schritte