PostgreSQL mit Zalando in GKE bereitstellen

In dieser Anleitung erfahren Sie, wie Sie mit dem Zalando-Postgres-Operator Postgres-Cluster in Google Kubernetes Engine (GKE) bereitstellen.

PostgreSQL ist ein leistungsstarkes, objektrelationales Open-Source-Datenbanksystem, das über mehrere Jahrzehnte hinweg aktiv entwickelt wurde und sich einen guten Ruf für Zuverlässigkeit, Robustheit von Features und Leistung verdient hat.

Dieser Leitfaden richtet sich an Plattformadministratoren, Cloud-Architekten und Betriebsexperten, die PostgreSQL als Datenbankanwendung in GKE ausführen möchten, anstatt Cloud SQL für PostgreSQL zu verwenden.

Ziele

  • GKE-Infrastruktur für Redis planen und bereitstellen
  • Zalando Postgres-Operator bereitstellen und konfigurieren
  • Postgres mit dem Operator konfigurieren, um Verfügbarkeit, Sicherheit, Beobachtbarkeit und Leistung zu gewährleisten

Vorteile

Zalando bietet folgende Vorteile:

  • Eine deklarative und Kubernetes-native Methode zum Verwalten und Konfigurieren der PostgreSQL-Cluster
  • Hochverfügbarkeit durch Patroni
  • Unterstützung der Sicherungsverwaltung mit Cloud Storage-Buckets
  • Rolling Updates für Postgres-Clusteränderungen, einschließlich schneller Aktualisierungen von Nebenversionen
  • Deklarative Nutzerverwaltung mit Passwortgenerierung und ‑rotation mit benutzerdefinierten Ressourcen
  • Unterstützung für TLS, Zertifikatsrotation und Verbindungspools
  • Cluster-Klonierung und Datenreplikation

Bereitstellungsarchitektur

In dieser Anleitung verwenden Sie den Zalando Postgres-Operator, um einen hochverfügbaren Postgres-Cluster in GKE bereitzustellen und zu konfigurieren. Der Cluster hat ein Leader-Replikat und zwei schreibgeschützte Standby-Replikate, die von Patroni verwaltet werden. Patroni ist eine von Zalando gepflegte Open-Source-Lösung, die Hochverfügbarkeits- und automatischen Failover-Funktionen für Postgres bereitstellt. Bei einem Leader-Fehler wird ein Standby-Replikat automatisch zur Leader-Rolle hochgestuft.

Außerdem stellen Sie einen hochverfügbaren regionalen GKE-Cluster für Postgres bereit, wobei mehrere Kubernetes-Knoten über verschiedene Verfügbarkeitszonen verteilt sind. Diese Konfiguration sorgt für Fehlertoleranz, Skalierbarkeit und geografische Redundanz. Damit können Rolling Updates und Wartungen durchgeführt werden, während SLAs für Verfügbarkeit und Verfügbarkeit bereitgestellt werden. Weitere Informationen finden Sie unter Regionale Cluster.

Das folgende Diagramm zeigt einen Postgres-Cluster, der auf mehreren Knoten und Zonen in einem GKE-Cluster ausgeführt wird:

Im Diagramm wird das Postgres-StatefulSet auf drei Knoten in drei verschiedenen Zonen bereitgestellt. Sie können steuern, wie GKE auf Knoten bereitgestellt wird. Dazu legen Sie den erforderlichen Pod-Regeln für Affinität und Anti-Affinität für die postgresql benutzerdefinierte Ressourcenspezifikation. Wenn eine Zone gemäß der empfohlenen Konfiguration ausfällt, verschiebt GKE die Pods auf andere verfügbare Knoten in Ihrem Cluster. Zum Speichern von Daten verwenden Sie SSD-Laufwerke (premium-rwo StorageClass). Diese werden in den meisten Fällen für stark ausgelastete Datenbanken aufgrund ihrerniedrigen Latenz und hohen IOPS empfohlen.

Kosten

In diesem Dokument verwenden Sie die folgenden kostenpflichtigen Komponenten von Google Cloud:

Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen.

Neuen Nutzern von Google Cloud steht möglicherweise ein kostenloser Testzeitraum zur Verfügung.

Nach Abschluss der in diesem Dokument beschriebenen Aufgaben können Sie weitere Kosten vermeiden, indem Sie die erstellten Ressourcen löschen. Weitere Informationen finden Sie unter Bereinigen.

Hinweise

Die Software, die Sie für diese Anleitung benötigen, ist in Cloud Shell vorinstalliert, einschließlich kubectl, gcloud CLI, Helm und Terraform. Wenn Sie Cloud Shell nicht verwenden, müssen Sie die gcloud CLI installieren.

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. Install the Google Cloud CLI.

  3. Wenn Sie einen externen Identitätsanbieter (IdP) verwenden, müssen Sie sich zuerst mit Ihrer föderierten Identität in der gcloud CLI anmelden.

  4. Führen Sie den folgenden Befehl aus, um die gcloud CLI zu initialisieren:

    gcloud init
  5. Create or select a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.
    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  6. Verify that billing is enabled for your Google Cloud project.

  7. Enable the Compute Engine, IAM, GKE, Backup for GKE APIs:

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    gcloud services enable compute.googleapis.com iam.googleapis.com container.googleapis.com gkebackup.googleapis.com
  8. Install the Google Cloud CLI.

  9. Wenn Sie einen externen Identitätsanbieter (IdP) verwenden, müssen Sie sich zuerst mit Ihrer föderierten Identität in der gcloud CLI anmelden.

  10. Führen Sie den folgenden Befehl aus, um die gcloud CLI zu initialisieren:

    gcloud init
  11. Create or select a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.
    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  12. Verify that billing is enabled for your Google Cloud project.

  13. Enable the Compute Engine, IAM, GKE, Backup for GKE APIs:

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    gcloud services enable compute.googleapis.com iam.googleapis.com container.googleapis.com gkebackup.googleapis.com
  14. Grant roles to your user account. Run the following command once for each of the following IAM roles: roles/storage.objectViewer, roles/container.admin, roles/iam.serviceAccountAdmin, roles/compute.admin, roles/gkebackup.admin, roles/monitoring.viewer

    gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE

    Replace the following:

    • PROJECT_ID: Your project ID.
    • USER_IDENTIFIER: The identifier for your user account. For example, myemail@example.com.
    • ROLE: The IAM role that you grant to your user account.
  15. Umgebung einrichten

    So richten Sie Ihre Umgebung ein:

    1. Legen Sie Umgebungsvariablen fest:

      export PROJECT_ID=PROJECT_ID
      export KUBERNETES_CLUSTER_PREFIX=postgres
      export REGION=us-central1
      

      Ersetzen Sie PROJECT_ID durch Ihre Google Cloud Projekt-ID.

    2. Klonen Sie das GitHub-Repository:

      git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
      
    3. Wechseln Sie in das Arbeitsverzeichnis:

      cd kubernetes-engine-samples/databases/postgres-zalando
      

    Clusterinfrastruktur erstellen

    In diesem Abschnitt führen Sie ein Terraform-Skript aus, um einen privaten, hochverfügbaren regionalen GKE-Cluster zu erstellen.

    Sie können den Operator mit einem Standard- oder Autopilot-Cluster installieren.

    Standard

    Das folgende Diagramm zeigt einen privaten regionalen Standard-GKE-Cluster, der in drei verschiedenen Zonen bereitgestellt wird:

    Stellen Sie diese Infrastruktur bereit:

    export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token)
    terraform -chdir=terraform/gke-standard init
    terraform -chdir=terraform/gke-standard apply \
      -var project_id=${PROJECT_ID} \
      -var region=${REGION} \
      -var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}
    

    Geben Sie bei Aufforderung yes ein. Es kann einige Minuten dauern, bis dieser Befehl abgeschlossen ist und der Cluster den Status „Bereit“ anzeigt.

    Terraform erstellt die folgenden Ressourcen:

    • Ein VPC-Netzwerk und ein privates Subnetz für die Kubernetes-Knoten
    • Ein Router für den Zugriff auf das Internet über NAT
    • Ein privater GKE-Cluster in der Region us-central1
    • Knotenpools mit aktiviertem Autoscaling (ein bis zwei Knoten pro Zone, mindestens ein Knoten pro Zone)
    • Ein ServiceAccount mit Logging- und Monitoring-Berechtigungen
    • Backup for GKE zur Notfallwiederherstellung
    • Google Cloud Managed Service for Prometheus für das Clustermonitoring

    Die Ausgabe sieht in etwa so aus:

    ...
    Apply complete! Resources: 14 added, 0 changed, 0 destroyed.
    ...
    

    Autopilot

    Das folgende Diagramm zeigt einen privaten regionalen Autopilot-GKE-Cluster:

    Stellen Sie die Infrastruktur bereit:

    export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token)
    terraform -chdir=terraform/gke-autopilot init
    terraform -chdir=terraform/gke-autopilot apply \
      -var project_id=${PROJECT_ID} \
      -var region=${REGION} \
      -var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}
    

    Geben Sie bei Aufforderung yes ein. Es kann einige Minuten dauern, bis dieser Befehl abgeschlossen ist und der Cluster den Status „Bereit“ anzeigt.

    Terraform erstellt die folgenden Ressourcen:

    • Ein VPC-Netzwerk und ein privates Subnetz für die Kubernetes-Knoten
    • Ein Router für den Zugriff auf das Internet über NAT
    • Ein privater GKE-Cluster in der Region us-central1
    • Ein ServiceAccount mit Logging- und Monitoring-Berechtigung
    • Google Cloud Managed Service for Prometheus für das Clustermonitoring

    Die Ausgabe sieht in etwa so aus:

    ...
    Apply complete! Resources: 12 added, 0 changed, 0 destroyed.
    ...
    

    Mit dem Cluster verbinden

    Konfigurieren Sie kubectl für die Kommunikation mit dem Cluster:

    gcloud container clusters get-credentials ${KUBERNETES_CLUSTER_PREFIX}-cluster --location ${REGION}
    

    Zalando-Operator in Ihrem Cluster bereitstellen

    Stellen Sie den Zalando-Operator mithilfe eines Helm-Diagramms in Ihrem Kubernetes-Cluster bereit.

    1. Fügen Sie das Helm-Diagramm-Repository für den Zalando-Operator hinzu:

      helm repo add postgres-operator-charts https://opensource.zalando.com/postgres-operator/charts/postgres-operator
      
    2. Erstellen Sie einen Namespace für den Zalando-Operator und den Postgres-Cluster:

      kubectl create ns postgres
      kubectl create ns zalando
      
    3. Stellen Sie den Zalando-Operator mit dem Helm-Befehlszeilentool bereit:

      helm install postgres-operator postgres-operator-charts/postgres-operator -n zalando \
          --set configKubernetes.enable_pod_antiaffinity=true \
          --set configKubernetes.pod_antiaffinity_preferred_during_scheduling=true \
          --set configKubernetes.pod_antiaffinity_topology_key="topology.kubernetes.io/zone" \
          --set configKubernetes.spilo_fsgroup="103"
      

      Sie können die Einstellungen von podAntiAffinity nicht direkt für die benutzerdefinierte Ressource konfigurieren, die den Postgres-Cluster darstellt. Legen Sie stattdessen die podAntiAffinity-Einstellungen global für alle Postgres-Cluster in den Operatoreinstellungen fest.

    4. Prüfen Sie den Bereitstellungsstatus des Zalando-Operators mit Helm:

      helm ls -n zalando
      

      Die Ausgabe sieht in etwa so aus:

      NAME                 NAMESPACE    REVISION    UPDATED                                STATUS      CHART                       APP VERSION
      postgres-operator    zalando     1           2023-10-13 16:04:13.945614 +0200 CEST    deployed    postgres-operator-1.10.1    1.10.1
      

    Postgres bereitstellen

    Die grundlegende Konfiguration für die Postgres-Clusterinstanz umfasst die folgenden Komponenten:

    • Drei Postgres-Replikate: ein Leader und zwei Standby-Replikate.
    • CPU-Ressourcenzuweisung: eine CPU-Anfrage und zwei CPU-Limits mit 4 GB Speicheranfragen und -Limits.
    • Toleranzen, nodeAffinities und topologySpreadConstraints, die für jede Arbeitslast konfiguriert sind und eine ordnungsgemäße Verteilung auf Kubernetes-Knoten mithilfe ihrer jeweiligen Knotenpools und verschiedenen Verfügbarkeitszonen gewährleisten.

    Diese Konfiguration stellt die minimale Einrichtung dar, die zum Erstellen eines produktionsfertigen Postgres-Clusters erforderlich ist.

    Das folgende Manifest beschreibt einen Postgres-Cluster:

    apiVersion: "acid.zalan.do/v1"
    kind: postgresql
    metadata:
      name: my-cluster
    spec:
      dockerImage: ghcr.io/zalando/spilo-15:3.0-p1
      teamId: "my-team"
      numberOfInstances: 3
      users:
        mydatabaseowner:
        - superuser
        - createdb
        myuser: []
      databases:
        mydatabase: mydatabaseowner
      postgresql:
        version: "15"
        parameters:
          shared_buffers: "32MB"
          max_connections: "10"
          log_statement: "all"
          password_encryption: scram-sha-256
      volume:
        size: 5Gi
        storageClass: premium-rwo
      enableShmVolume: true
      podAnnotations:
        cluster-autoscaler.kubernetes.io/safe-to-evict: "true"
      tolerations:
      - key: "app.stateful/component"
        operator: "Equal"
        value: "postgres-operator"
        effect: NoSchedule
      nodeAffinity:
        preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 1
          preference:
            matchExpressions:
            - key: "app.stateful/component"
              operator: In
              values:
              - "postgres-operator"
      resources:
        requests:
          cpu: "1"
          memory: 4Gi
        limits:
          cpu: "2"
          memory: 4Gi
      sidecars:
        - name: exporter
          image: quay.io/prometheuscommunity/postgres-exporter:v0.14.0
          args:
          - --collector.stat_statements
          ports:
          - name: exporter
            containerPort: 9187
            protocol: TCP
          resources:
            limits:
              cpu: 500m
              memory: 256M
            requests:
              cpu: 100m
              memory: 256M
          env:
          - name: "DATA_SOURCE_URI"
            value: "localhost/postgres?sslmode=require"
          - name: "DATA_SOURCE_USER"
            value: "$(POSTGRES_USER)"
          - name: "DATA_SOURCE_PASS"
            value: "$(POSTGRES_PASSWORD)"

    Dieses Manifest hat die folgenden Felder:

    • spec.teamId ist ein Präfix für die von Ihnen ausgewählten Clusterobjekte
    • spec.numberOfInstances ist die Gesamtzahl der Instanzen für einen Cluster
    • spec.users ist die Nutzerliste mit Berechtigungen
    • spec.databases ist die Datenbankliste im Format dbname: ownername
    • spec.postgresql sind die Postgres-Parameter
    • spec.volume sind die Parameter für den nichtflüchtigen Speicher
    • spec.tolerations ist die Toleranz-Pod-Vorlage, mit der Cluster-Pods auf pool-postgres-Knoten geplant werden können
    • spec.nodeAffinity ist die Pod-Vorlage nodeAffinity, die GKE mitteilt, dass Cluster-Pods lieber auf pool-postgres-Knoten geplant werden sollen.
    • spec.resources sind Anfragen und Limits für Cluster-Pods
    • spec.sidecars ist eine Liste der Sidecar-Container, die postgres-exporter enthält

    Weitere Informationen finden Sie in der Referenz zu Clustermanifesten in der Postgres-Dokumentation.

    Einfachen Postgres-Cluster erstellen

    1. Erstellen Sie mithilfe der grundlegenden Konfiguration einen neuen Postgres-Cluster:

      kubectl apply -n postgres -f manifests/01-basic-cluster/my-cluster.yaml
      

      Mit diesem Befehl wird eine benutzerdefinierte PostgreSQL-Ressource des Zalando-Betreibers mit folgenden Eigenschaften erstellt:

      • CPU- und Speicheranforderungen und -limits
      • Markierungen und Affinitäten, um die bereitgestellten Pod-Replikate auf GKE-Knoten zu verteilen.
      • Eine Datenbank
      • Zwei Nutzer mit Datenbankinhaberberechtigungen
      • Ein Nutzer ohne Berechtigungen
    2. Warten Sie, bis GKE die erforderlichen Arbeitslasten gestartet hat:

      kubectl wait pods -l cluster-name=my-cluster  --for condition=Ready --timeout=300s -n postgres
      

      Die Verarbeitung dieses Befehls kann einige Minuten dauern.

    3. Prüfen Sie, ob GKE die Postgres-Arbeitslasten erstellt hat:

      kubectl get pod,svc,statefulset,deploy,pdb,secret -n postgres
      

      Die Ausgabe sieht in etwa so aus:

      NAME                                    READY   STATUS  RESTARTS   AGE
      pod/my-cluster-0                        1/1     Running   0         6m41s
      pod/my-cluster-1                        1/1     Running   0         5m56s
      pod/my-cluster-2                        1/1     Running   0         5m16s
      pod/postgres-operator-db9667d4d-rgcs8   1/1     Running   0         12m
      
      NAME                        TYPE        CLUSTER-IP  EXTERNAL-IP   PORT(S)   AGE
      service/my-cluster          ClusterIP   10.52.12.109   <none>       5432/TCP   6m43s
      service/my-cluster-config   ClusterIP   None        <none>      <none>  5m55s
      service/my-cluster-repl     ClusterIP   10.52.6.152 <none>      5432/TCP   6m43s
      service/postgres-operator   ClusterIP   10.52.8.176 <none>      8080/TCP   12m
      
      NAME                        READY   AGE
      statefulset.apps/my-cluster   3/3   6m43s
      
      NAME                                READY   UP-TO-DATE   AVAILABLE   AGE
      deployment.apps/postgres-operator   1/1     1           1           12m
      
      NAME                                                MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
      poddisruptionbudget.policy/postgres-my-cluster-pdb   1              N/A             0                   6m44s
      
      NAME                                                            TYPE                DATA   AGE
      secret/my-user.my-cluster.credentials.postgresql.acid.zalan.do  Opaque              2   6m45s
      secret/postgres.my-cluster.credentials.postgresql.acid.zalan.do   Opaque            2   6m44s
      secret/sh.helm.release.v1.postgres-operator.v1                  helm.sh/release.v1   1      12m
      secret/standby.my-cluster.credentials.postgresql.acid.zalan.do  Opaque              2   6m44s
      secret/zalando.my-cluster.credentials.postgresql.acid.zalan.do  Opaque              2   6m44s
      

    Der Operator erstellt die folgenden Ressourcen:

    • Ein Postgres-StatefulSet, das drei Pod-Replikate für Postgres steuert
    • Einen PodDisruptionBudgets, wodurch mindestens ein verfügbares Replikat garantiert wird
    • Den my-cluster-Dienst, der nur auf das Leader-Replikat abzielt
    • Der Dienst my-cluster-repl, der den Postgres-Port für eingehende Verbindungen und für die Replikation zwischen Postgres-Replikaten freigibt
    • Den monitorlosen Dienst my-cluster-config zum Abrufen der Liste der laufenden Postgres-Pod-Replikate
    • Secrets mit Nutzeranmeldedaten für den Zugriff auf die Datenbank und die Replikation zwischen Postgres-Knoten.

    Bei Postgres authentifizieren

    Sie können Postgres-Nutzer erstellen und ihnen Datenbankberechtigungen zuweisen. Das folgende Manifest beschreibt beispielsweise eine benutzerdefinierte Ressource, die Nutzern Rollen zuweist:

    apiVersion: "acid.zalan.do/v1"
    kind: postgresql
    metadata:
      name: my-cluster
    spec:
      ...
      users:
        mydatabaseowner:
        - superuser
        - createdb
        myuser: []
      databases:
        mydatabase: mydatabaseowner
    

    In diesem Manifest:

    • Der mydatabaseowner-Nutzer hat die Rollen SUPERUSER und CREATEDB, die uneingeschränkte Administratorrechte gewähren (Verwaltung der Postgres-Konfiguration, neue Datenbanken, Tabellen und Nutzer erstellen, usw). Sie sollten diesen Nutzer nicht mit Kunden teilen. In Cloud SQL können Kunden beispielsweise nicht auf Nutzer mit der Rolle SUPERUSER zugreifen.
    • Dem Nutzer myuser sind keine Rollen zugewiesen. Dies entspricht der Best Practice, mit der SUPERUSER Nutzer mit den geringsten Berechtigungen zu erstellen. Detaillierte Rechte werden myuser von mydatabaseowner gewährt. Aus Sicherheitsgründen sollten Sie myuser-Anmeldedaten nur für Clientanwendungen freigeben.

    Passwörter speichern

    Sie sollten die scram-sha-256 empfohlene Methode zum Speichern von Passwörtern verwenden. Das folgende Manifest beschreibt beispielsweise eine benutzerdefinierte Ressource, die die scram-sha-256-Verschlüsselung mithilfe des Felds postgresql.parameters.password_encryption angibt:

    apiVersion: "acid.zalan.do/v1"
    kind: postgresql
    metadata:
      name: my-cluster
    spec:
      ...
      postgresql:
        parameters:
          password_encryption: scram-sha-256
    

    Nutzeranmeldedaten rotieren

    Sie können Nutzer-Anmeldedaten rotieren, die in Kubernetes-Secrets mit Zalando gespeichert sind. Das folgende Manifest beschreibt beispielsweise eine benutzerdefinierte Ressource, die die Rotation der Nutzeranmeldedaten mithilfe des Felds usersWithSecretRotation definiert:

    apiVersion: "acid.zalan.do/v1"
    kind: postgresql
    metadata:
      name: my-cluster
    spec:
      ...
      usersWithSecretRotation:
      - myuser
      - myanotheruser
      - ...
    

    Beispiel für die Authentifizierung: Mit Postgres verbinden

    In diesem Abschnitt erfahren Sie, wie Sie einen Postgres-Beispielclient bereitstellen und mit dem Passwort aus einem Kubernetes-Secret eine Verbindung zur Datenbank herstellen.

    1. Führen Sie den Client-Pod aus, um mit Ihrem Postgres-Cluster zu interagieren:

      kubectl apply -n postgres -f manifests/02-auth/client-pod.yaml
      

      Die Anmeldedaten der Nutzer myuser und mydatabaseowner werden aus den zugehörigen Secrets übernommen und als Umgebungsvariablen im Pod bereitgestellt.

    2. Stellen Sie eine Verbindung zum Pod her, wenn er bereit ist:

      kubectl wait pod postgres-client --for=condition=Ready --timeout=300s -n postgres
      kubectl exec -it postgres-client -n postgres -- /bin/bash
      
    3. Stellen Sie eine Verbindung zu Postgres her und versuchen Sie, mit myuser-Anmeldedaten eine neue Tabelle zu erstellen:

      PGPASSWORD=$CLIENTPASSWORD psql \
        -h my-cluster \
        -U $CLIENTUSERNAME \
        -d mydatabase \
        -c "CREATE TABLE test (id serial PRIMARY KEY, randomdata VARCHAR ( 50 ) NOT NULL);"
      

      Der Befehl sollte mit einem Fehler wie dem folgenden fehlschlagen:

      ERROR:  permission denied for schema public
      LINE 1: CREATE TABLE test (id serial PRIMARY KEY, randomdata VARCHAR...
      

      Der Befehl schlägt fehl, weil Nutzer ohne zugewiesene Berechtigungen sich standardmäßig nur in Postgres anmelden und Datenbanken auflisten können.

    4. Erstellen Sie eine Tabelle mit den Anmeldedaten mydatabaseowner und gewähren Sie myuser alle Berechtigungen für die Tabelle:

      PGPASSWORD=$OWNERPASSWORD psql \
        -h my-cluster \
        -U $OWNERUSERNAME \
        -d mydatabase \
        -c "CREATE TABLE test (id serial PRIMARY KEY, randomdata VARCHAR ( 50 ) NOT NULL);GRANT ALL ON test TO myuser;GRANT ALL ON SEQUENCE test_id_seq TO myuser;"
      

      Die Ausgabe sieht in etwa so aus:

      CREATE TABLE
      GRANT
      GRANT
      
    5. Fügen Sie mithilfe von myuser-Anmeldedaten zufällige Daten in die Tabelle ein:

      for i in {1..10}; do
        DATA=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 13)
        PGPASSWORD=$CLIENTPASSWORD psql \
        -h my-cluster \
        -U $CLIENTUSERNAME \
        -d mydatabase \
        -c "INSERT INTO test(randomdata) VALUES ('$DATA');"
      done
      

      Die Ausgabe sieht in etwa so aus:

      INSERT 0 1
      INSERT 0 1
      INSERT 0 1
      INSERT 0 1
      INSERT 0 1
      INSERT 0 1
      INSERT 0 1
      INSERT 0 1
      INSERT 0 1
      INSERT 0 1
      
    6. Rufen Sie die von Ihnen eingefügten Werte ab:

      PGPASSWORD=$CLIENTPASSWORD psql \
        -h my-cluster \
        -U $CLIENTUSERNAME \
        -d mydatabase \
        -c "SELECT * FROM test;"
      

      Die Ausgabe sieht in etwa so aus:

      id |  randomdata
      ----+---------------
        1 | jup9HYsAjwtW4
        2 | 9rLAyBlcpLgNT
        3 | wcXSqxb5Yz75g
        4 | KoDRSrx3muD6T
        5 | b9atC7RPai7En
        6 | 20d7kC8E6Vt1V
        7 | GmgNxaWbkevGq
        8 | BkTwFWH6hWC7r
        9 | nkLXHclkaqkqy
       10 | HEebZ9Lp71Nm3
      (10 rows)
      
    7. Beenden Sie die Pod-Shell:

      exit
      

    Informationen zum Erfassen von Messwerten für den Postgres-Cluster durch Prometheus

    Das folgende Diagramm zeigt, wie die Erfassung von Prometheus-Messwerten funktioniert:

    Im Diagramm enthält ein privater GKE-Cluster Folgendes:

    • Einen Postgres-Pod, der Messwerte für den Pfad / und den Port 9187 erfasst.
    • Prometheus-basierte Collectors, die die Messwerte aus dem Postgres-Pod verarbeiten.
    • Eine PodMonitoring-Ressource, die Messwerte an Cloud Monitoring sendet

    Google Cloud Managed Service for Prometheus unterstützt die Messwerterfassung im Prometheus-Format. Cloud Monitoring verwendet ein integriertes Dashboard für Postgres-Messwerte.

    Zalando stellt Clustermesswerte im Prometheus-Format bereit. Dabei wird die postgres_exporter-Komponente als Sidecar-Container verwendet.

    1. Erstellen Sie die PodMonitoring-Ressource, um Messwerte nach labelSelector zu extrahieren:

      kubectl apply -n postgres -f manifests/03-prometheus-metrics/pod-monitoring.yaml
      
    2. Rufen Sie in der Google Cloud Console die Seite GKE-Cluster auf.

      Zum GKE-Cluster-Dashboard

      Im Dashboard wird eine Datenaufnahmerate ungleich null angezeigt.

    3. Rufen Sie in der Google Cloud Console die Seite Dashboards auf.

      Dashboards aufrufen

    4. Öffnen Sie das PostgreSQL Prometheus-Übersichts-Dashboard. Im Dashboard wird die Anzahl der abgerufenen Zeilen angezeigt. Es kann einige Minuten dauern, bis das Dashboard automatisch bereitgestellt wird.

    5. Stellen Sie eine Verbindung zum Client-Pod her:

      kubectl exec -it postgres-client -n postgres -- /bin/bash
      
    6. Zufällige Daten einfügen:

      for i in {1..100}; do
        DATA=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 13)
        PGPASSWORD=$CLIENTPASSWORD psql \
        -h my-cluster \
        -U $CLIENTUSERNAME \
        -d mydatabase \
        -c "INSERT INTO test(randomdata) VALUES ('$DATA');"
      done
      
    7. Aktualisieren Sie die Seite. Die Diagramme Zeilen und Blöcke werden aktualisiert, um den tatsächlichen Datenbankstatus anzuzeigen.

    8. Beenden Sie die Pod-Shell:

      exit
      

    Bereinigen

    Projekt löschen

      Delete a Google Cloud project:

      gcloud projects delete PROJECT_ID

    Einzelne Ressourcen löschen

    1. Umgebungsvariablen festlegen

      export PROJECT_ID=${PROJECT_ID}
      export KUBERNETES_CLUSTER_PREFIX=postgres
      export REGION=us-central1
      
    2. Führen Sie den Befehl terraform destroy aus:

      export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token)
      terraform  -chdir=terraform/FOLDER destroy \
        -var project_id=${PROJECT_ID} \
        -var region=${REGION} \
        -var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}
      

      Ersetzen Sie FOLDER durch gke-autopilot oder gke-standard.

      Geben Sie bei Aufforderung yes ein.

    3. Alle nicht angehängten Laufwerke suchen:

      export disk_list=$(gcloud compute disks list --filter="-users:* AND labels.name=${KUBERNETES_CLUSTER_PREFIX}-cluster" --format "value[separator=|](name,zone)")
      
    4. Laufwerke löschen:

      for i in $disk_list; do
        disk_name=$(echo $i| cut -d'|' -f1)
        disk_zone=$(echo $i| cut -d'|' -f2|sed 's|.*/||')
        echo "Deleting $disk_name"
        gcloud compute disks delete $disk_name --zone $disk_zone --quiet
      done
      
    5. GitHub-Repository löschen:

      rm -r ~/kubernetes-engine-samples/
      

    Nächste Schritte

    • Referenzarchitekturen, Diagramme und Best Practices zu Google Cloud kennenlernen. Weitere Informationen zu Cloud Architecture Center