Esegui il deployment di un database PostgreSQL a disponibilità elevata su GKE


PostgreSQL è un database relazionale a oggetti open source noto per la sua affidabilità e integrità dei dati. È conforme ad ACID e supporta chiavi esterne, join, viste, trigger e stored procedure.

Questo documento è destinato ad amministratori di database, architetti cloud e professionisti delle operazioni interessati al deployment di una topologia PostgreSQL a disponibilità elevata su Google Kubernetes Engine (GKE).

Obiettivi

In questo tutorial imparerai a:

  • Utilizza Terraform per creare un cluster GKE regionale.
  • Esegui il deployment di un database PostgreSQL a disponibilità elevata.
  • Configura il monitoraggio per l'applicazione PostgreSQL.
  • Esegui gli upgrade del database PostgreSQL e del cluster GKE.
  • Simula l'interruzione del cluster e il failover della replica PostgreSQL.
  • Esegui il backup e il ripristino del database PostgreSQL.

Architettura

Questa sezione descrive l'architettura della soluzione che creerai in questo tutorial.

Provisionerete due cluster GKE in regioni diverse: un cluster primario e un cluster di backup. Per questo tutorial, il cluster primario si trova nella regione us-central1 e il cluster di backup si trova nella regione us-west1. Questa architettura ti consente di eseguire il provisioning di un database PostgreSQL a disponibilità elevata e testare il ripristino di emergenza, come descritto più avanti in questo tutorial.

Per il cluster di origine, utilizzerai un grafico Helm (bitnami/postgresql-ha) per configurare un cluster PostgreSQL ad alta disponibilità.

Il diagramma mostra un'architettura di esempio di un cluster PostgreSQL a disponibilità elevata.
Figura 1: architettura di esempio di un cluster PostgreSQL a disponibilità elevata.

Costi

In questo documento utilizzi i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi in base all'utilizzo previsto, utilizza il calcolatore prezzi.

I nuovi utenti di Google Cloud potrebbero avere diritto a una prova gratuita.

Al termine delle attività descritte in questo documento, puoi evitare l'addebito di ulteriori costi eliminando le risorse che hai creato. Per ulteriori informazioni, vedi Pulizia.

Prima di iniziare

Configura il progetto

  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. In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.

    Go to project selector

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

  4. Enable the Google Kubernetes Engine, Backup for GKE, Artifact Registry, Compute Engine, and IAM APIs.

    Enable the APIs

  5. In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.

    Go to project selector

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

  7. Enable the Google Kubernetes Engine, Backup for GKE, Artifact Registry, Compute Engine, and IAM APIs.

    Enable the APIs

  8. Configurare i ruoli

    1. Make sure that you have the following role or roles on the project: roles/storage.objectViewer, roles/logging.logWriter, roles/artifactregistry.Admin, roles/container.clusterAdmin, roles/container.serviceAgent, roles/serviceusage.serviceUsageAdmin, roles/iam.serviceAccountAdmin

      Check for the roles

      1. In the Google Cloud console, go to the IAM page.

        Go to IAM
      2. Select the project.
      3. In the Principal column, find all rows that identify you or a group that you're included in. To learn which groups you're included in, contact your administrator.

      4. For all rows that specify or include you, check the Role column to see whether the list of roles includes the required roles.

      Grant the roles

      1. In the Google Cloud console, go to the IAM page.

        Vai a IAM
      2. Seleziona il progetto.
      3. Fai clic su Concedi l'accesso.
      4. Nel campo Nuove entità, inserisci il tuo identificatore utente. In genere si tratta dell'indirizzo email di un Account Google.

      5. Nell'elenco Seleziona un ruolo, seleziona un ruolo.
      6. Per concedere altri ruoli, fai clic su Aggiungi un altro ruolo e aggiungi ogni ruolo aggiuntivo.
      7. Fai clic su Salva.

      Configura l'ambiente

      In questo tutorial utilizzerai Cloud Shell per gestire le risorse ospitate su Google Cloud. Cloud Shell è preinstallato con il software necessario per questo tutorial, tra cui Docker, kubectl, gcloud CLI, Helm e Terraform.

      Per utilizzare Cloud Shell per configurare l'ambiente:

      1. Avvia una sessione di Cloud Shell dalla console Google Cloud facendo clic su Icona di attivazione di Cloud Shell Attiva Cloud Shell nella Google Cloud console. Viene avviata una sessione nel riquadro inferiore della console Google Cloud .

      2. Imposta le variabili di ambiente.

        export PROJECT_ID=PROJECT_ID
        export SOURCE_CLUSTER=cluster-db1
        export REGION=us-central1
        

        Sostituisci i seguenti valori:

      3. Imposta le variabili di ambiente predefinite.

        gcloud config set project PROJECT_ID
        
      4. Clona il repository di codice.

        git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
        
      5. Passa alla directory di lavoro.

        cd kubernetes-engine-samples/databases/gke-stateful-postgres
        

      Crea l'infrastruttura del cluster

      In questa sezione, eseguirai uno script Terraform per creare un VPC (Virtual Private Cloud) personalizzato, un repository Artifact Registry per archiviare le immagini PostgreSQL e due cluster GKE regionali. Un cluster verrà implementato in us-central1 e il secondo cluster per il backup verrà implementato in us-west1.

      Per creare il cluster:

      Autopilot

      In Cloud Shell, esegui questi comandi:

      terraform -chdir=terraform/gke-autopilot init
      terraform -chdir=terraform/gke-autopilot apply -var project_id=$PROJECT_ID
      

      Quando richiesto, digita yes.

      Informazioni sulla configurazione Terraform

      I file di configurazione Terraform creano le seguenti risorse per eseguire il deployment dell'infrastruttura:

      • Crea un repository Artifact Registry per archiviare le immagini Docker.
        resource "google_artifact_registry_repository" "main" {
          location      = "us"
          repository_id = "main"
          format        = "DOCKER"
          project       = var.project_id
        }
      • Crea la rete VPC e la subnet per l'interfaccia di rete della VM.
        module "gcp-network" {
          source  = "terraform-google-modules/network/google"
          version = "< 8.0.0"
        
          project_id   = var.project_id
          network_name = "vpc-gke-postgresql"
        
          subnets = [
            {
              subnet_name           = "snet-gke-postgresql-us-central1"
              subnet_ip             = "10.0.0.0/17"
              subnet_region         = "us-central1"
              subnet_private_access = true
            },
            {
              subnet_name           = "snet-gke-postgresql-us-west1"
              subnet_ip             = "10.0.128.0/17"
              subnet_region         = "us-west1"
              subnet_private_access = true
            },
          ]
        
          secondary_ranges = {
            ("snet-gke-postgresql-us-central1") = [
              {
                range_name    = "ip-range-pods-db1"
                ip_cidr_range = "192.168.0.0/18"
              },
              {
                range_name    = "ip-range-svc-db1"
                ip_cidr_range = "192.168.64.0/18"
              },
            ],
            ("snet-gke-postgresql-us-west1") = [
              {
                range_name    = "ip-range-pods-db2"
                ip_cidr_range = "192.168.128.0/18"
              },
              {
                range_name    = "ip-range-svc-db2"
                ip_cidr_range = "192.168.192.0/18"
              },
            ]
          }
        }
        
        output "network_name" {
          value = module.gcp-network.network_name
        }
        
        output "primary_subnet_name" {
          value = module.gcp-network.subnets_names[0]
        }
        
        output "secondary_subnet_name" {
          value = module.gcp-network.subnets_names[1]
        }
      • Crea un cluster GKE principale.

        Terraform crea un cluster privato nella regione us-central1 e abilita Backup per GKE per il ripristino di emergenza e Managed Service per Prometheus per il monitoraggio del cluster.

        Managed Service per Prometheus è supportato solo sui cluster Autopilot che eseguono GKE versione 1.25 o successive.

        module "gke-db1-autopilot" {
          source                          = "../modules/beta-autopilot-private-cluster"
          project_id                      = var.project_id
          name                            = "cluster-db1"
          kubernetes_version              = "1.25" # Will be ignored if use "REGULAR" release_channel
          region                          = "us-central1"
          regional                        = true
          zones                           = ["us-central1-a", "us-central1-b", "us-central1-c"]
          network                         = module.network.network_name
          subnetwork                      = module.network.primary_subnet_name
          ip_range_pods                   = "ip-range-pods-db1"
          ip_range_services               = "ip-range-svc-db1"
          horizontal_pod_autoscaling      = true
          release_channel                 = "RAPID" # Default version is 1.22 in REGULAR. GMP on Autopilot requires V1.25 via var.kubernetes_version
          enable_vertical_pod_autoscaling = true
          enable_private_endpoint         = false
          enable_private_nodes            = true
          master_ipv4_cidr_block          = "172.16.0.0/28"
          create_service_account          = false
        }

      • Crea un cluster di backup nella regione us-west1 per il ripristino di emergenza.

        module "gke-db2-autopilot" {
          source                          = "../modules/beta-autopilot-private-cluster"
          project_id                      = var.project_id
          name                            = "cluster-db2"
          kubernetes_version              = "1.25" # Will be ignored if use "REGULAR" release_channel
          region                          = "us-west1"
          regional                        = true
          zones                           = ["us-west1-a", "us-west1-b", "us-west1-c"]
          network                         = module.network.network_name
          subnetwork                      = module.network.secondary_subnet_name
          ip_range_pods                   = "ip-range-pods-db2"
          ip_range_services               = "ip-range-svc-db2"
          horizontal_pod_autoscaling      = true
          release_channel                 = "RAPID" # Default version is 1.22 in REGULAR. GMP on Autopilot requires V1.25 via var.kubernetes_version
          enable_vertical_pod_autoscaling = true
          enable_private_endpoint         = false
          enable_private_nodes            = true
          master_ipv4_cidr_block          = "172.16.0.16/28"
          create_service_account          = false
        }

      Standard

      In Cloud Shell, esegui questi comandi:

      terraform -chdir=terraform/gke-standard init
      terraform -chdir=terraform/gke-standard apply -var project_id=$PROJECT_ID
      

      Quando richiesto, digita yes.

      Informazioni sulla configurazione Terraform

      I file di configurazione Terraform creano le seguenti risorse per il deployment dell'infrastruttura:

      • Crea un repository Artifact Registry per archiviare le immagini Docker.
        resource "google_artifact_registry_repository" "main" {
          location      = "us"
          repository_id = "main"
          format        = "DOCKER"
          project       = var.project_id
        }
        resource "google_artifact_registry_repository_iam_binding" "binding" {
          provider   = google-beta
          project    = google_artifact_registry_repository.main.project
          location   = google_artifact_registry_repository.main.location
          repository = google_artifact_registry_repository.main.name
          role       = "roles/artifactregistry.reader"
          members = [
            "serviceAccount:${module.gke-db1.service_account}",
          ]
        }
      • Crea la rete VPC e la subnet per l'interfaccia di rete della VM.
        module "gcp-network" {
          source  = "terraform-google-modules/network/google"
          version = "< 8.0.0"
        
          project_id   = var.project_id
          network_name = "vpc-gke-postgresql"
        
          subnets = [
            {
              subnet_name           = "snet-gke-postgresql-us-central1"
              subnet_ip             = "10.0.0.0/17"
              subnet_region         = "us-central1"
              subnet_private_access = true
            },
            {
              subnet_name           = "snet-gke-postgresql-us-west1"
              subnet_ip             = "10.0.128.0/17"
              subnet_region         = "us-west1"
              subnet_private_access = true
            },
          ]
        
          secondary_ranges = {
            ("snet-gke-postgresql-us-central1") = [
              {
                range_name    = "ip-range-pods-db1"
                ip_cidr_range = "192.168.0.0/18"
              },
              {
                range_name    = "ip-range-svc-db1"
                ip_cidr_range = "192.168.64.0/18"
              },
            ],
            ("snet-gke-postgresql-us-west1") = [
              {
                range_name    = "ip-range-pods-db2"
                ip_cidr_range = "192.168.128.0/18"
              },
              {
                range_name    = "ip-range-svc-db2"
                ip_cidr_range = "192.168.192.0/18"
              },
            ]
          }
        }
        
        output "network_name" {
          value = module.gcp-network.network_name
        }
        
        output "primary_subnet_name" {
          value = module.gcp-network.subnets_names[0]
        }
        
        output "secondary_subnet_name" {
          value = module.gcp-network.subnets_names[1]
        }
      • Crea un cluster GKE principale.

        Terraform crea un cluster privato nella regione us-central1 e abilita Backup per GKE per il ripristino di emergenza e Managed Service per Prometheus per il monitoraggio del cluster.

        module "gke-db1" {
          source                   = "../modules/beta-private-cluster"
          project_id               = var.project_id
          name                     = "cluster-db1"
          regional                 = true
          region                   = "us-central1"
          network                  = module.network.network_name
          subnetwork               = module.network.primary_subnet_name
          ip_range_pods            = "ip-range-pods-db1"
          ip_range_services        = "ip-range-svc-db1"
          create_service_account   = true
          enable_private_endpoint  = false
          enable_private_nodes     = true
          master_ipv4_cidr_block   = "172.16.0.0/28"
          network_policy           = true
          cluster_autoscaling = {
            "autoscaling_profile": "OPTIMIZE_UTILIZATION",
            "enabled" : true,
            "gpu_resources" : [],
            "min_cpu_cores" : 36,
            "min_memory_gb" : 144,
            "max_cpu_cores" : 48,
            "max_memory_gb" : 192,
          }
          monitoring_enable_managed_prometheus = true
          gke_backup_agent_config = true
        
          node_pools = [
            {
              name            = "pool-sys"
              autoscaling     = true
              min_count       = 1
              max_count       = 3
              max_surge       = 1
              max_unavailable = 0
              machine_type    = "e2-standard-4"
              node_locations  = "us-central1-a,us-central1-b,us-central1-c"
              auto_repair     = true
            },
            {
              name            = "pool-db"
              autoscaling     = true
              max_surge       = 1
              max_unavailable = 0
              machine_type    = "e2-standard-8"
              node_locations  = "us-central1-a,us-central1-b,us-central1-c"
              auto_repair     = true
            },
          ]
          node_pools_labels = {
            all = {}
            pool-db = {
              "app.stateful/component" = "postgresql"
            }
            pool-sys = {
              "app.stateful/component" = "postgresql-pgpool"
            }
          }
          node_pools_taints = {
            all = []
            pool-db = [
              {
                key    = "app.stateful/component"
                value  = "postgresql"
                effect = "NO_SCHEDULE"
              },
            ],
            pool-sys = [
              {
                key    = "app.stateful/component"
                value  = "postgresql-pgpool"
                effect = "NO_SCHEDULE"
              },
            ],
          }
          gce_pd_csi_driver = true
        }

      • Crea un cluster di backup nella regione us-west1 per il ripristino di emergenza.

        module "gke-db2" {
          source                   = "../modules/beta-private-cluster"
          project_id               = var.project_id
          name                     = "cluster-db2"
          regional                 = true
          region                   = "us-west1"
          network                  = module.network.network_name
          subnetwork               = module.network.secondary_subnet_name
          ip_range_pods            = "ip-range-pods-db2"
          ip_range_services        = "ip-range-svc-db2"
          create_service_account   = false
          service_account          = module.gke-db1.service_account
          enable_private_endpoint  = false
          enable_private_nodes     = true
          master_ipv4_cidr_block   = "172.16.0.16/28"
          network_policy           = true
          cluster_autoscaling = {
            "autoscaling_profile": "OPTIMIZE_UTILIZATION",
            "enabled" : true,
            "gpu_resources" : [],
            "min_cpu_cores" : 10,
            "min_memory_gb" : 144,
            "max_cpu_cores" : 48,
            "max_memory_gb" : 192,
          }
          monitoring_enable_managed_prometheus = true
          gke_backup_agent_config = true
          node_pools = [
            {
              name            = "pool-sys"
              autoscaling     = true
              min_count       = 1
              max_count       = 3
              max_surge       = 1
              max_unavailable = 0
              machine_type    = "e2-standard-4"
              node_locations  = "us-west1-a,us-west1-b,us-west1-c"
              auto_repair     = true
            },
            {
              name            = "pool-db"
              autoscaling     = true
              max_surge       = 1
              max_unavailable = 0
              machine_type    = "e2-standard-8"
              node_locations  = "us-west1-a,us-west1-b,us-west1-c"
              auto_repair     = true
            },
          ]
          node_pools_labels = {
            all = {}
            pool-db = {
              "app.stateful/component" = "postgresql"
            }
            pool-sys = {
              "app.stateful/component" = "postgresql-pgpool"
            }
          }
          node_pools_taints = {
            all = []
            pool-db = [
              {
                key    = "app.stateful/component"
                value  = "postgresql"
                effect = "NO_SCHEDULE"
              },
            ],
            pool-sys = [
              {
                key    = "app.stateful/component"
                value  = "postgresql-pgpool"
                effect = "NO_SCHEDULE"
              },
            ],
          }
          gce_pd_csi_driver = true
        }

      Esegui il deployment di PostgreSQL sul cluster

      In questa sezione, eseguirai il deployment di un'istanza di database PostgreSQL da eseguire su GKE utilizzando un grafico Helm.

      Installa PostgreSQL

      Per installare PostgreSQL sul cluster:

      1. Configura l'accesso a Docker.

        gcloud auth configure-docker us-docker.pkg.dev
        
      2. Popola Artifact Registry con le immagini Docker PostgreSQL richieste.

        ./scripts/gcr.sh bitnami/postgresql-repmgr 15.1.0-debian-11-r0
        ./scripts/gcr.sh bitnami/postgres-exporter 0.11.1-debian-11-r27
        ./scripts/gcr.sh bitnami/pgpool 4.3.3-debian-11-r28
        

        Lo script esegue il push delle seguenti immagini Bitnami in Artifact Registry per l'installazione di Helm:

        • postgresql-repmgr: Questa soluzione di cluster PostgreSQL include PostgreSQL Replication Manager (repmgr), uno strumento open source per la gestione della replica e del failover nei cluster PostgreSQL.
        • postgres-exporter: PostgreSQL Exporter raccoglie le metriche PostgreSQL per l'utilizzo di Prometheus.
        • pgpool: Pgpool-II è il proxy PostgreSQL. Fornisce il pool di connessioni e il bilanciamento del carico.
      3. Verifica che nel repository siano archiviate le immagini corrette.

        gcloud artifacts docker images list us-docker.pkg.dev/$PROJECT_ID/main \
            --format="flattened(package)"
        

        L'output è simile al seguente:

        ---
        image: us-docker.pkg.dev/[PROJECT_ID]/main/bitnami/pgpool
        ---
        image: us-docker.pkg.dev/[PROJECT_ID]/main/bitnami/postgres-exporter
        ---
        image: us-docker.pkg.dev/h[PROJECT_ID]/main/bitnami/postgresql-repmgr
        
      4. Configura l'accesso alla riga di comando kubectl al cluster primario.

        gcloud container clusters get-credentials $SOURCE_CLUSTER \
        --location=$REGION --project=$PROJECT_ID
        
      5. Crea uno spazio dei nomi.

        export NAMESPACE=postgresql
        kubectl create namespace $NAMESPACE
        
      6. Se esegui il deployment in un cluster Autopilot, configura il provisioning dei nodi in tre zone. Puoi saltare questo passaggio se esegui il deployment in un cluster Standard.

        Per impostazione predefinita, Autopilot esegue il provisioning delle risorse solo in due zone. Il deployment definito in prepareforha.yaml garantisce che Autopilot esegua il provisioning dei nodi in tre zone del tuo cluster impostando questi valori:

        • replicas:3
        • podAntiAffinity con requiredDuringSchedulingIgnoredDuringExecution e topologyKey: "topology.kubernetes.io/zone"
        kubectl -n $NAMESPACE apply -f scripts/prepareforha.yaml
        
        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: prepare-three-zone-ha
          labels:
            app: prepare-three-zone-ha
            app.kubernetes.io/name: postgresql-ha
        spec:
          replicas: 3
          selector:
            matchLabels:
              app: prepare-three-zone-ha
              app.kubernetes.io/name: postgresql-ha
          template:
            metadata:
              labels:
                app: prepare-three-zone-ha
                app.kubernetes.io/name: postgresql-ha
            spec:
              affinity:
                podAntiAffinity:
                  requiredDuringSchedulingIgnoredDuringExecution:
                  - labelSelector:
                      matchExpressions:
                      - key: app
                        operator: In
                        values:
                        - prepare-three-zone-ha
                    topologyKey: "topology.kubernetes.io/zone"
                nodeAffinity:
                  preferredDuringSchedulingIgnoredDuringExecution:
                  - preference:
                      matchExpressions:
                      - key: cloud.google.com/compute-class
                        operator: In
                        values:
                        - "Scale-Out"
                    weight: 1
              nodeSelector:
                app.stateful/component: postgresql
              tolerations:
              - effect: NoSchedule
                key: app.stateful/component
                operator: Equal
                value: postgresql
              containers:
              - name: prepare-three-zone-ha
                image: busybox:latest
                command:
                    - "/bin/sh"
                    - "-c"
                    - "while true; do sleep 3600; done"
                resources:
                  limits:
                    cpu: "500m"
                    ephemeral-storage: "10Mi"
                    memory: "0.5Gi"
                  requests:
                    cpu: "500m"
                    ephemeral-storage: "10Mi"
                    memory: "0.5Gi"
        
      7. Aggiorna la dipendenza Helm.

        cd helm/postgresql-bootstrap
        helm dependency update
        
      8. Ispeziona e verifica i grafici che Helm installerà.

        helm -n postgresql template postgresql . \
          --set global.imageRegistry="us-docker.pkg.dev/$PROJECT_ID/main"
        
      9. Installa il grafico Helm.

        helm -n postgresql upgrade --install postgresql . \
            --set global.imageRegistry="us-docker.pkg.dev/$PROJECT_ID/main"
        

        L'output è simile al seguente:

        NAMESPACE: postgresql
        STATUS: deployed
        REVISION: 1
        TEST SUITE: None
        
      10. Verifica che le repliche PostgreSQL siano in esecuzione.

        kubectl get all -n $NAMESPACE
        

        L'output è simile al seguente:

        NAME                                                          READY   STATUS    RESTARTS   AGE
        pod/postgresql-postgresql-bootstrap-pgpool-75664444cb-dkl24   1/1     Running   0          8m39s
        pod/postgresql-postgresql-ha-pgpool-6d86bf9b58-ff2bg          1/1     Running   0          8m39s
        pod/postgresql-postgresql-ha-postgresql-0                     2/2     Running   0          8m39s
        pod/postgresql-postgresql-ha-postgresql-1                     2/2     Running   0          8m39s
        pod/postgresql-postgresql-ha-postgresql-2                     2/2     Running   0          8m38s
        
        NAME                                                   TYPE        CLUSTER-IP        EXTERNAL-IP   PORT(S)    AGE
        service/postgresql-postgresql-ha-pgpool                ClusterIP   192.168.99.236    <none>        5432/TCP   8m39s
        service/postgresql-postgresql-ha-postgresql            ClusterIP   192.168.90.20     <none>        5432/TCP   8m39s
        service/postgresql-postgresql-ha-postgresql-headless   ClusterIP   None              <none>        5432/TCP   8m39s
        service/postgresql-postgresql-ha-postgresql-metrics    ClusterIP   192.168.127.198   <none>        9187/TCP   8m39s
        
        NAME                                                     READY   UP-TO-DATE   AVAILABLE   AGE
        deployment.apps/postgresql-postgresql-bootstrap-pgpool   1/1     1            1           8m39s
        deployment.apps/postgresql-postgresql-ha-pgpool          1/1     1            1           8m39s
        
        NAME                                                                DESIRED   CURRENT   READY   AGE
        replicaset.apps/postgresql-postgresql-bootstrap-pgpool-75664444cb   1         1         1       8m39s
        replicaset.apps/postgresql-postgresql-ha-pgpool-6d86bf9b58          1         1         1       8m39s
        
        NAME                                                   READY   AGE
        statefulset.apps/postgresql-postgresql-ha-postgresql   3/3     8m39s
        

      Creare un set di dati di test

      In questa sezione creerai un database e una tabella con valori di esempio. Il database funge da set di dati di test per la procedura di failover che testerai più avanti in questo tutorial.

      1. Connetterti all'istanza PostgreSQL.

        cd ../../
        ./scripts/launch-client.sh
        

        L'output è simile al seguente:

        Launching Pod pg-client in the namespace postgresql ...
        pod/pg-client created
        waiting for the Pod to be ready
        Copying script files to the target Pod pg-client ...
        Pod: pg-client is healthy
        
      2. Avvia una sessione shell.

        kubectl exec -it pg-client -n postgresql -- /bin/bash
        
      3. Crea un database e una tabella, quindi inserisci alcune righe di test.

        psql -h $HOST_PGPOOL -U postgres -a -q -f /tmp/scripts/generate-db.sql
        
      4. Verifica il numero di righe per ogni tabella.

        psql -h $HOST_PGPOOL -U postgres -a -q -f /tmp/scripts/count-rows.sql
        

        L'output è simile al seguente:

        select COUNT(*) from tb01;
         count
        --------
         300000
        (1 row)
        
        select COUNT(*) from tb02;
         count
        --------
         300000
        (1 row)
        
      5. Genera dati di test.

        export DB=postgres
        pgbench -i -h $HOST_PGPOOL -U postgres $DB -s 50
        

        L'output è simile al seguente:

        dropping old tables...
        creating tables...
        generating data (client-side)...
        5000000 of 5000000 tuples (100%) done (elapsed 29.85 s, remaining 0.00 s)
        vacuuming...
        creating primary keys...
        done in 36.86 s (drop tables 0.00 s, create tables 0.01 s, client-side generate 31.10 s, vacuum 1.88 s, primary keys 3.86 s).
        
      6. Esci dal pod client postgres.

        exit
        

      Monitorare PostgreSQL

      In questa sezione, visualizzerai le metriche e configurerai gli avvisi per l'istanza PostgreSQL. Utilizzerai Google Cloud Managed Service per Prometheus per eseguire il monitoraggio e la creazione di avvisi.

      Visualizza metriche

      Il deployment PostgreSQL include un container sidecar postgresql-exporter. Questo contenitore espone un endpoint /metrics. Google Cloud Managed Service per Prometheus è configurato per monitorare i pod PostgreSQL su questo endpoint. Puoi visualizzare queste metriche tramite le dashboard della console Google Cloud .

      La console Google Cloud offre alcuni modi per creare e salvare la configurazione della dashboard:

      • Creazione ed esportazione: puoi creare dashboard direttamente nella console Google Cloud , quindi esportarle e archiviarle in un repository di codice. Per farlo, nella barra degli strumenti della dashboard, apri l'editor JSON e scarica il file JSON della dashboard.
      • Archiviazione e importazione: puoi importare una dashboard da un file JSON facendo clic su +Crea dashboard e caricando i contenuti JSON della dashboard utilizzando il menu Editor JSON.

      Per visualizzare i dati dell'applicazione PostgreSQL e del cluster GKE, segui questi passaggi:

      1. Crea le seguenti dashboard.

        cd monitoring
        gcloud monitoring dashboards create \
                --config-from-file=dashboard/postgresql-overview.json \
                --project=$PROJECT_ID
        gcloud monitoring dashboards create \
                --config-from-file dashboard/gke-postgresql.json \
                --project $PROJECT_ID
        
      2. Nella console Google Cloud , vai alla dashboard di Cloud Monitoring. Vai alla dashboard di Cloud Monitoring

      3. Seleziona Personalizzato dall'elenco dei dashboard. Vengono visualizzate le seguenti dashboard:

        • Panoramica di PostgreSQL: mostra le metriche dell'applicazione PostgreSQL, tra cui uptime del database, dimensioni del database e latenza delle transazioni.
        • Cluster GKE PostgreSQL: mostra le metriche del cluster GKE su cui è in esecuzione PostgreSQL, tra cui utilizzo della CPU, utilizzo della memoria e utilizzo del volume.
      4. Fai clic su ogni link per esaminare le dashboard generate.

      Configurazione degli avvisi

      Gli avvisi ti consentono di rilevare tempestivamente i problemi nelle tue applicazioni, in modo da poterli risolvere rapidamente. Puoi creare un criterio di avviso per specificare le circostanze in cui vuoi ricevere un avviso e come vuoi ricevere le notifiche. Puoi anche creare canali di notifica che ti consentono di selezionare dove vengono inviati gli avvisi.

      In questa sezione utilizzerai Terraform per configurare i seguenti avvisi di esempio:

      • db_max_transaction: monitora il ritardo massimo delle transazioni in secondi; viene attivato un avviso se il valore è maggiore di 10.
      • db_node_up: monitora lo stato dei pod del database; 0 indica che un pod non è attivo e attiva un avviso.

      Per configurare gli avvisi:

      1. Configura gli avvisi con Terraform.

        EMAIL=YOUR_EMAIL
        cd alerting/terraform
        terraform init
        terraform plan -var project_id=$PROJECT_ID -var email_address=$EMAIL
        terraform apply -var project_id=$PROJECT_ID -var email_address=$EMAIL
        

        Sostituisci i seguenti valori:

        • YOUR_EMAIL: il tuo indirizzo email.

        L'output è simile al seguente :

        Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
        
      2. Connettiti al pod client.

        cd ../../../
        kubectl exec -it --namespace postgresql pg-client -- /bin/bash
        
      3. Genera un test di carico per testare l'avviso db_max_transaction.

        pgbench -i -h $HOST_PGPOOL -U postgres -s 200 postgres
        

        L'output è simile al seguente:

        dropping old tables...
        creating tables...
        generating data (client-side)...
        20000000 of 20000000 tuples (100%) done (elapsed 163.22 s, remaining 0.00 s)
        vacuuming...
        creating primary keys...
        done in 191.30 s (drop tables 0.14 s, create tables 0.01 s, client-side generate 165.62 s, vacuum 4.52 s, primary keys 21.00 s).
        

        L'avviso viene attivato e invia un'email a YOUR_EMAIL con un oggetto che inizia con "[AVVISO] Ritardo massimo della transazione".

      4. Nella console Google Cloud , vai alla pagina Policy di avviso.

        Vai a Norme di avviso

      5. Seleziona db_max_transaction dai criteri elencati. Dal grafico dovresti vedere un picco del test di carico che supera la soglia di 10 per la metrica Prometheus pg_stat_activity_max_tx_duration/gauge.

      6. Esci dal pod client postgres.

        exit
        

      Gestire gli upgrade di PostgreSQL e GKE

      Gli aggiornamenti delle versioni sia di PostgreSQL che di Kubernetes vengono rilasciati regolarmente. Segui le best practice operative per aggiornare regolarmente l'ambiente software. Per impostazione predefinita, GKE gestisce gli upgrade del cluster e del pool di nodi.

      Upgrade di PostgreSQL

      Questa sezione mostra come eseguire l'upgrade della versione di PostgreSQL. Per questo tutorial, utilizzerai una strategia di aggiornamento in sequenza per l'upgrade dei pod, in modo che in nessun momento tutti i pod siano inattivi.

      Per eseguire l'upgrade di una versione:

      1. Esegui il push di una versione aggiornata dell'immagine postgresql-repmgr in Artifact Registry. Definisci la nuova versione (ad esempio, postgresql-repmgr 15.1.0-debian-11-r1).

        NEW_IMAGE=us-docker.pkg.dev/$PROJECT_ID/main/bitnami/postgresql-repmgr:15.1.0-debian-11-r1
        ./scripts/gcr.sh bitnami/postgresql-repmgr 15.1.0-debian-11-r1
        
      2. Attiva un aggiornamento in sequenza utilizzando kubectl.

        kubectl set image statefulset -n postgresql postgresql-postgresql-ha-postgresql postgresql=$NEW_IMAGE
        kubectl rollout restart statefulsets -n postgresql postgresql-postgresql-ha-postgresql
        kubectl rollout status statefulset -n postgresql postgresql-postgresql-ha-postgresql
        

        Vedrai lo StatefulSet completare un aggiornamento in sequenza, a partire dalla replica con numero ordinale più alto fino a quella con numero ordinale più basso.

        L'output è simile al seguente:

        Waiting for 1 pods to be ready...
        waiting for statefulset rolling update to complete 1 pods at revision postgresql-postgresql-ha-postgresql-5c566ccf49...
        Waiting for 1 pods to be ready...
        Waiting for 1 pods to be ready...
        waiting for statefulset rolling update to complete 2 pods at revision postgresql-postgresql-ha-postgresql-5c566ccf49...
        Waiting for 1 pods to be ready...
        Waiting for 1 pods to be ready...
        statefulset rolling update complete 3 pods at revision postgresql-postgresql-ha-postgresql-5c566ccf49...
        

      Pianifica gli upgrade di GKE sui cluster Standard

      Questa sezione è applicabile se esegui cluster Standard. Puoi adottare misure proattive e impostare configurazioni per ridurre i rischi e facilitare un upgrade del cluster più fluido quando esegui servizi stateful, tra cui:

      • Segui le best practice di GKE per l'upgrade dei cluster. Scegli una strategia di upgrade appropriata per assicurarti che gli upgrade vengano eseguiti durante il periodo di manutenzione:

        • Scegli upgrade improvvisi se l'ottimizzazione dei costi è importante e se i tuoi workload possono tollerare un arresto controllato in meno di 60 minuti.
        • Scegli gli upgrade blu/verde se i tuoi workload sono meno tolleranti alle interruzioni e un aumento temporaneo dei costi dovuto a un maggiore utilizzo delle risorse è accettabile.

        Per saperne di più, vedi Eseguire l'upgrade di un cluster che esegue un carico di lavoro stateful.

      • Utilizza il servizio Recommender per verificare insight e suggerimenti sul ritiro per evitare interruzioni del servizio.

      • Utilizza i periodi di manutenzione per assicurarti che gli upgrade vengano eseguiti quando vuoi. Prima della periodo di manutenzione, assicurati che i backup del database siano riusciti.

      • Prima di consentire il traffico ai nodi sottoposti ad upgrade, utilizza i probe di idoneità e attività per assicurarti che siano pronti per il traffico.

      • Crea probe che valutino se la replica è sincronizzata prima di accettare il traffico. Questa operazione può essere eseguita tramite script personalizzati, a seconda della complessità e delle dimensioni del database.

      Verificare la disponibilità del database durante gli upgrade dei cluster Standard

      Questa sezione è applicabile se esegui cluster Standard. Per verificare la disponibilità di PostgreSQL durante gli upgrade, la procedura generale consiste nel generare traffico sul database PostgreSQL durante la procedura di upgrade. Poi, utilizza pgbench per verificare che il database possa gestire un livello di base di traffico durante un upgrade, rispetto a quando il database è completamente disponibile.

      1. Connetterti all'istanza PostgreSQL.

        ./scripts/launch-client.sh
        

        L'output è simile al seguente:

        Launching Pod pg-client in the namespace postgresql ...
        pod/pg-client created
        waiting for the Pod to be ready
        Copying script files to the target Pod pg-client ...
        Pod: pg-client is healthy
        
      2. In Cloud Shell, accedi al pod client.

        kubectl exec -it -n postgresql pg-client -- /bin/bash
        
      3. Inizializza pgbench .

        pgbench -i -h $HOST_PGPOOL -U postgres postgres
        
      4. Utilizza il seguente comando per ottenere i risultati di base per verificare che la tua applicazione PostgreSQL rimanga a disponibilità elevata durante l'intervallo di tempo per un upgrade. Per ottenere un risultato di base, esegui il test con più connessioni tramite più job (thread) per 30 secondi.

        pgbench -h $HOST_PGPOOL -U postgres postgres -c10 -j4 -T 30 -R 200
        

        L'output è simile al seguente:

        pgbench (14.5)
        starting vacuum...end.
        transaction type: <builtin: TPC-B (sort of)>
        scaling factor: 1
        query mode: simple
        number of clients: 10
        number of threads: 4
        duration: 30 s
        number of transactions actually processed: 5980
        latency average = 7.613 ms
        latency stddev = 2.898 ms
        rate limit schedule lag: avg 0.256 (max 36.613) ms
        initial connection time = 397.804 ms
        tps = 201.955497 (without initial connection time)
        
      5. Per garantire la disponibilità durante gli upgrade, puoi generare un carico sul database e assicurarti che l'applicazione PostgreSQL fornisca una velocità di risposta coerente durante l'upgrade. Per eseguire questo test, genera un po' di traffico sul database utilizzando il comando pgbench. Il seguente comando eseguirà pgbench per un'ora, con un target di 200 TPS (transazioni al secondo) ed elencando la tasso di richieste ogni 2 secondi.

        pgbench -h $HOST_PGPOOL -U postgres postgres --client=10 --jobs=4 --rate=200 --time=3600 --progress=2 --select-only
        

        Dove:

        • --client: numero di client simulati, ovvero numero di sessioni di database simultanee.
        • --jobs: Numero di thread di lavoro all'interno di pgbench. L'utilizzo di più thread può essere utile su macchine con più CPU. I client vengono distribuiti nel modo più uniforme possibile tra i thread disponibili. Il valore predefinito è 1.
        • --rate: Il tasso è indicato in transazioni al secondo
        • --progress: mostra il report sullo stato di avanzamento ogni sec secondi.

        L'output è simile al seguente:

        pgbench (14.5)
        starting vacuum...end.
        progress: 5.0 s, 354.8 tps, lat 25.222 ms stddev 15.038
        progress: 10.0 s, 393.8 tps, lat 25.396 ms stddev 16.459
        progress: 15.0 s, 412.8 tps, lat 24.216 ms stddev 14.548
        progress: 20.0 s, 405.0 tps, lat 24.656 ms stddev 14.066
        
      6. Nella console Google Cloud , torna alla dashboard Panoramica di PostgreSQL in Cloud Monitoring. Nota il picco nei grafici Connessione per DB e Connessione per pod.

      7. Esci dal pod client.

        exit
        
      8. Elimina il pod client.

        kubectl delete pod -n postgresql pg-client
        

      Simula un'interruzione del servizio PostgreSQL

      In questa sezione, simulerai un'interruzione del servizio in una delle repliche PostgreSQL arrestando il servizio di gestione della replica. In questo modo, il pod non gestirà il traffico verso le repliche peer e i probe di attività non andranno a buon fine.

      1. Apri una nuova sessione Cloud Shell e configura l'accesso alla riga di comando kubectl al cluster primario.

        gcloud container clusters get-credentials $SOURCE_CLUSTER \
        --location=$REGION --project=$PROJECT_ID
        
      2. Visualizza gli eventi PostgreSQL emessi in Kubernetes.

        kubectl get events -n postgresql --field-selector=involvedObject.name=postgresql-postgresql-ha-postgresql-0 --watch
        
      3. Nella sessione precedente di Cloud Shell, simula un errore del servizio arrestando PostgreSQL repmgr.

        1. Collega la sessione al contenitore del database.

          kubectl exec -it -n $NAMESPACE postgresql-postgresql-ha-postgresql-0 -c postgresql -- /bin/bash
          
        2. Interrompi il servizio utilizzando repmgr e rimuovi il checkpoint e l'argomento dry-run.

          export ENTRY='/opt/bitnami/scripts/postgresql-repmgr/entrypoint.sh'
          export RCONF='/opt/bitnami/repmgr/conf/repmgr.conf'
          $ENTRY repmgr -f $RCONF node service --action=stop --checkpoint
          

      Il probe di attività configurato per il container PostgreSQL inizierà a non funzionare entro cinque secondi. Questa operazione viene ripetuta ogni 10 secondi finché non viene raggiunto il limite di sei errori. Una volta raggiunto il valore di failureThreshold, il container viene riavviato. Puoi configurare questi parametri per diminuire la tolleranza del probe di attività e ottimizzare i requisiti SLO del deployment.

      Nel flusso di eventi, vedrai che i probe di attività e di idoneità del pod non riescono e un messaggio che indica che il container deve essere riavviato. L'output è simile al seguente:

      0s          Normal    Killing                pod/postgresql-postgresql-ha-postgresql-0   Container postgresql failed liveness probe, will be restarted
      0s          Warning   Unhealthy              pod/postgresql-postgresql-ha-postgresql-0   Readiness probe failed: psql: error: connection to server at "127.0.0.1", port 5432 failed: Connection refused...
      0s          Normal    Pulled                 pod/postgresql-postgresql-ha-postgresql-0   Container image "us-docker.pkg.dev/psch-gke-dev/main/bitnami/postgresql-repmgr:14.5.0-debian-11-r10" already present on machine
      0s          Normal    Created                pod/postgresql-postgresql-ha-postgresql-0   Created container postgresql
      0s          Normal    Started                pod/postgresql-postgresql-ha-postgresql-0   Started container postgresql
      

      Prepararsi per il ripristino di emergenza

      Per garantire che i tuoi carichi di lavoro di produzione rimangano disponibili in caso di interruzione del servizio, devi preparare un piano di ripristino di emergenza. Per saperne di più sulla pianificazione RE, consulta la Guida alla pianificazione del disaster recovery.

      Il disaster recovery per Kubernetes può essere implementato in due fasi:

      • Il backup prevede la creazione di uno snapshot point-in-time del tuo stato o dei tuoi dati prima che si verifichi un evento che interrompe il servizio.
      • Il recupero prevede il ripristino dello stato o dei dati da una copia di backup dopo il verificarsi di un disastro.

      Per eseguire il backup e il ripristino dei workload sui cluster GKE, puoi utilizzare Backup per GKE. Puoi abilitare questo servizio sui cluster nuovi ed esistenti. Viene eseguito il deployment di un agente Backup per GKE che viene eseguito nei cluster. L'agente è responsabile dell'acquisizione della configurazione e dei dati di backup dei volumi e dell'orchestrazione del ripristino.

      I backup e i ripristini possono essere limitati a un intero cluster, a uno spazio dei nomi o a un'applicazione (definiti da selettori come matchLabels).

      Scenario di backup e ripristino PostgreSQL di esempio

      L'esempio in questa sezione mostra come eseguire un'operazione di backup e ripristino nell'ambito dell'applicazione, utilizzando la risorsa personalizzata ProtectedApplication.

      Il seguente diagramma mostra le risorse dei componenti in ProtectedApplication, ovvero un oggetto StatefulSet che rappresenta l'applicazione postgresql-ha e un deployment di pgpool, che utilizzano la stessa etichetta (app.kubernetes.io/name: postgresql-ha).

      Il diagramma mostra una soluzione di backup e ripristino di esempio per un cluster PostgreSQL ad alta disponibilità.
      Figura 2: soluzione di backup e ripristino di esempio per un cluster PostgreSQL a disponibilità elevata.

      Per prepararti a eseguire il backup e il ripristino del carico di lavoro PostgreSQL:

      1. Configura le variabili di ambiente. In questo esempio utilizzerai un ProtectedApplication per ripristinare il workload PostgreSQL e i relativi volumi dal cluster GKE di origine (us-central1), quindi ripristinarli in un altro cluster GKE in una regione diversa (us-west1).

        export SOURCE_CLUSTER=cluster-db1
        export TARGET_CLUSTER=cluster-db2
        export REGION=us-central1
        export DR_REGION=us-west1
        export NAME_PREFIX=g-db-protected-app
        export BACKUP_PLAN_NAME=$NAME_PREFIX-bkp-plan-01
        export BACKUP_NAME=bkp-$BACKUP_PLAN_NAME
        export RESTORE_PLAN_NAME=$NAME_PREFIX-rest-plan-01
        export RESTORE_NAME=rest-$RESTORE_PLAN_NAME
        
      2. Verifica che Backup per GKE sia abilitato sui tuoi cluster. Dovrebbe essere già abilitata nell'ambito della configurazione Terraform eseguita in precedenza.

        gcloud container clusters describe $SOURCE_CLUSTER \
            --project=$PROJECT_ID  \
            --location=$REGION \
            --format='value(addonsConfig.gkeBackupAgentConfig)'
        

        Se Backup per GKE è abilitato, l'output del comando mostra enabled=True.

      Configurare un piano di backup ed eseguire un ripristino

      Backup per GKE consente di creare un piano di backup come cron job. Un piano di backup contiene una configurazione di backup che include il cluster di origine, la selezione dei carichi di lavoro di cui eseguire il backup e la regione in cui vengono archiviati gli artefatti di backup prodotti nell'ambito di questo piano.

      Per eseguire un backup e un ripristino:

      1. Verifica lo stato di ProtectedApplication su cluster-db1.

        kubectl get ProtectedApplication -A
        

        L'output è simile al seguente:

        NAMESPACE    NAME            READY TO BACKUP
        postgresql   postgresql-ha   true
        
      2. Crea un piano di backup per ProtectedApplication.

        export NAMESPACE=postgresql
        export PROTECTED_APP=$(kubectl get ProtectedApplication -n $NAMESPACE | grep -v 'NAME' | awk '{ print $1 }')
        
        gcloud beta container backup-restore backup-plans create $BACKUP_PLAN_NAME \
        --project=$PROJECT_ID \
        --location=$DR_REGION \
        --cluster=projects/$PROJECT_ID/locations/$REGION/clusters/$SOURCE_CLUSTER \
        --selected-applications=$NAMESPACE/$PROTECTED_APP \
        --include-secrets \
        --include-volume-data \
        --cron-schedule="0 3 * * *" \
        --backup-retain-days=7 \
        --backup-delete-lock-days=0
        
      3. Crea manualmente un backup.

        gcloud beta container backup-restore backups create $BACKUP_NAME \
        --project=$PROJECT_ID \
        --location=$DR_REGION \
        --backup-plan=$BACKUP_PLAN_NAME \
        --wait-for-completion
        
      4. Configura un piano di ripristino.

        gcloud beta container backup-restore restore-plans create $RESTORE_PLAN_NAME \
          --project=$PROJECT_ID \
          --location=$DR_REGION \
          --backup-plan=projects/$PROJECT_ID/locations/$DR_REGION/backupPlans/$BACKUP_PLAN_NAME \
          --cluster=projects/$PROJECT_ID/locations/$DR_REGION/clusters/$TARGET_CLUSTER \
          --cluster-resource-conflict-policy=use-existing-version \
          --namespaced-resource-restore-mode=delete-and-restore \
          --volume-data-restore-policy=restore-volume-data-from-backup \
          --selected-applications=$NAMESPACE/$PROTECTED_APP \
          --cluster-resource-scope-selected-group-kinds="storage.k8s.io/StorageClass","scheduling.k8s.io/PriorityClass"
        
      5. Ripristina dal backup.

        gcloud beta container backup-restore restores create $RESTORE_NAME \
          --project=$PROJECT_ID \
          --location=$DR_REGION \
          --restore-plan=$RESTORE_PLAN_NAME \
          --backup=projects/$PROJECT_ID/locations/$DR_REGION/backupPlans/$BACKUP_PLAN_NAME/backups/$BACKUP_NAME \
          --wait-for-completion
        

      Verifica che il cluster sia stato ripristinato

      Per verificare che il cluster ripristinato contenga tutte le risorse pod, PersistentVolume e StorageClass previste, segui questi passaggi:

      1. Configura l'accesso alla riga di comando kubectl al cluster di backup cluster-db2.

        gcloud container clusters get-credentials $TARGET_CLUSTER --location $DR_REGION --project $PROJECT_ID
        
      2. Verifica che StatefulSet sia pronto con 3/3 pod.

        kubectl get all -n $NAMESPACE
        

        L'output è simile al seguente:

        NAME                                                   READY   STATUS    RESTARTS        AGE
        pod/postgresql-postgresql-ha-pgpool-778798b5bd-k2q4b   1/1     Running   0               4m49s
        pod/postgresql-postgresql-ha-postgresql-0              2/2     Running   2 (4m13s ago)   4m49s
        pod/postgresql-postgresql-ha-postgresql-1              2/2     Running   0               4m49s
        pod/postgresql-postgresql-ha-postgresql-2              2/2     Running   0               4m49s
        
        NAME                                                   TYPE        CLUSTER-IP        EXTERNAL-IP   PORT(S)    AGE
        service/postgresql-postgresql-ha-pgpool                ClusterIP   192.168.241.46    <none>        5432/TCP   4m49s
        service/postgresql-postgresql-ha-postgresql            ClusterIP   192.168.220.20    <none>        5432/TCP   4m49s
        service/postgresql-postgresql-ha-postgresql-headless   ClusterIP   None              <none>        5432/TCP   4m49s
        service/postgresql-postgresql-ha-postgresql-metrics    ClusterIP   192.168.226.235   <none>        9187/TCP   4m49s
        
        NAME                                              READY   UP-TO-DATE   AVAILABLE   AGE
        deployment.apps/postgresql-postgresql-ha-pgpool   1/1     1            1           4m49s
        
        NAME                                                         DESIRED   CURRENT   READY   AGE
        replicaset.apps/postgresql-postgresql-ha-pgpool-778798b5bd   1         1         1       4m49s
        
        NAME                                                   READY   AGE
        statefulset.apps/postgresql-postgresql-ha-postgresql   3/3     4m49s
        
      3. Verifica che tutti i pod nello spazio dei nomi postgres siano in esecuzione.

        kubectl get pods -n $NAMESPACE
        

        L'output è simile al seguente:

        postgresql-postgresql-ha-pgpool-569d7b8dfc-2f9zx   1/1     Running   0          7m56s
        postgresql-postgresql-ha-postgresql-0              2/2     Running   0          7m56s
        postgresql-postgresql-ha-postgresql-1              2/2     Running   0          7m56s
        postgresql-postgresql-ha-postgresql-2              2/2     Running   0          7m56s
        
      4. Verifica PersistentVolumes e StorageClass. Durante il processo di ripristino, Backup per GKE crea una classe proxy nel workload di destinazione per sostituire la StorageClass di cui è stato eseguito il provisioning nel workload di origine (gce-pd-gkebackup-dn nell'output di esempio).

        kubectl get pvc -n $NAMESPACE
        

        L'output è simile al seguente:

        NAME                                         STATUS   VOLUME                 CAPACITY   ACCESS MODES   STORAGECLASS          AGE
        data-postgresql-postgresql-ha-postgresql-0   Bound    pvc-be91c361e9303f96   8Gi        RWO            gce-pd-gkebackup-dn   10m
        data-postgresql-postgresql-ha-postgresql-1   Bound    pvc-6523044f8ce927d3   8Gi        RWO            gce-pd-gkebackup-dn   10m
        data-postgresql-postgresql-ha-postgresql-2   Bound    pvc-c9e71a99ccb99a4c   8Gi        RWO            gce-pd-gkebackup-dn   10m
        

      Verificare che i dati previsti siano stati ripristinati

      Per verificare che i dati previsti siano stati ripristinati:

      1. Connetterti all'istanza PostgreSQL.

        ./scripts/launch-client.sh
        kubectl exec -it pg-client -n postgresql -- /bin/bash
        
      2. Verifica il numero di righe per ogni tabella.

        psql -h $HOST_PGPOOL -U postgres -a -q -f /tmp/scripts/count-rows.sql
        select COUNT(*) from tb01;
        

        Dovresti visualizzare un risultato simile ai dati che hai scritto in precedenza nella sezione Crea un set di dati di test. L'output è simile al seguente:

        300000
        (1 row)
        
      3. Esci dal pod client.

        exit
        

      Esegui la pulizia

      Per evitare che al tuo Account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo tutorial, elimina il progetto che contiene le risorse oppure mantieni il progetto ed elimina le singole risorse.

      Elimina il progetto

      Il modo più semplice per evitare la fatturazione è eliminare il progetto creato per il tutorial.

    2. In the Google Cloud console, go to the Manage resources page.

      Go to Manage resources

    3. In the project list, select the project that you want to delete, and then click Delete.
    4. In the dialog, type the project ID, and then click Shut down to delete the project.
    5. Passaggi successivi