Implemente uma base de dados PostgreSQL de elevada disponibilidade no GKE

O PostgreSQL é uma base de dados relacional de objetos de código aberto conhecida pela fiabilidade e integridade dos dados. É compatível com ACID e suporta chaves estrangeiras, junções, vistas, acionadores e procedimentos armazenados.

Este documento destina-se a administradores de bases de dados, arquitetos da nuvem e profissionais de operações interessados na implementação de uma topologia do PostgreSQL de elevada disponibilidade no Google Kubernetes Engine (GKE).

Objetivos

Neste tutorial, vai aprender a:

  • Use o Terraform para criar um cluster do GKE regional.
  • Implemente uma base de dados PostgreSQL de elevada disponibilidade.
  • Configure a monitorização para a aplicação PostgreSQL.
  • Realize atualizações da base de dados PostgreSQL e do cluster do GKE.
  • Simule a interrupção do cluster e a comutação por falha da réplica do PostgreSQL.
  • Faça uma cópia de segurança e restaure a base de dados PostgreSQL.

Arquitetura

Esta secção descreve a arquitetura da solução que vai criar neste tutorial.

Vai aprovisionar dois clusters do GKE em regiões diferentes: um cluster principal e um cluster de yedekleme. Para este tutorial, o cluster principal está na região us-central1 e o cluster de cópia de segurança está na região us-west1. Esta arquitetura permite-lhe aprovisionar uma base de dados PostgreSQL de alta disponibilidade e testar a recuperação de desastres, conforme descrito mais adiante neste tutorial.

Para o cluster de origem, vai usar um gráfico do Helm (bitnami/postgresql-ha) para configurar um cluster do PostgreSQL de alta disponibilidade.

O diagrama mostra um exemplo de arquitetura de um cluster PostgreSQL de alta disponibilidade.
Figura 1: exemplo de arquitetura de um cluster PostgreSQL de alta disponibilidade.

Custos

Neste documento, usa os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custos com base na sua utilização prevista, use a calculadora de preços.

Os novos Google Cloud utilizadores podem ser elegíveis para uma avaliação sem custo financeiro.

Quando terminar as tarefas descritas neste documento, pode evitar a faturação contínua eliminando os recursos que criou. Para mais informações, consulte o artigo Limpe.

Antes de começar

Configure o seu projeto

  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.

    Roles required to 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.

    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.

    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.

    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.

    Roles required to 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.

    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.

    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.

    Enable the APIs

  8. Configure funções

    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.

        Aceder ao IAM
      2. Selecione o projeto.
      3. Clique em Conceder acesso.
      4. No campo Novos responsáveis, introduza o identificador do utilizador. Normalmente, este é o endereço de email de uma Conta Google.

      5. Clique em Selecionar uma função e, de seguida, pesquise a função.
      6. Para conceder funções adicionais, clique em Adicionar outra função e adicione cada função adicional.
      7. Clique em Guardar.

      Configure o seu ambiente

      Neste tutorial, vai usar o Cloud Shell para gerir recursos alojados no Google Cloud. O Cloud Shell é pré-instalado com o software de que precisa para este tutorial, incluindo o Docker, o kubectl, a CLI gcloud, o Helm e o Terraform.

      Para usar o Cloud Shell para configurar o seu ambiente:

      1. Inicie uma sessão do Cloud Shell a partir da Google Cloud consolaÍcone de ativação do Cloud Shell clicando em Ícone de ativação do Cloud Shell Ativar Cloud Shell na Google Cloud consola. Esta ação inicia uma sessão no painel inferior da consola Google Cloud .

      2. Defina variáveis de ambiente.

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

        Substitua os seguintes valores:

      3. Defina as variáveis de ambiente predefinidas.

        gcloud config set project PROJECT_ID
        
      4. Clone o repositório de código.

        git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
        
      5. Mude para o diretório de trabalho.

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

      Crie a infraestrutura do cluster

      Nesta secção, vai executar um script do Terraform para criar uma nuvem virtual privada (VPC) personalizada, um repositório do Artifact Registry para armazenar imagens do PostgreSQL e dois clusters regionais do GKE. Um cluster vai ser implementado em us-central1 e o segundo cluster para cópia de segurança vai ser implementado em us-west1.

      Para criar o cluster, siga estes passos:

      Piloto automático

      No Cloud Shell, execute os seguintes comandos:

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

      Quando lhe for pedido, escreva yes.

      Compreenda a configuração do Terraform

      Os ficheiros de configuração do Terraform criam os seguintes recursos para implementar a sua infraestrutura:

      • Crie um repositório do Artifact Registry para armazenar as imagens Docker.
        resource "google_artifact_registry_repository" "main" {
          location      = "us"
          repository_id = "main"
          format        = "DOCKER"
          project       = var.project_id
        }
      • Crie a rede VPC e a sub-rede para a interface de rede da 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]
        }
      • Crie um cluster do GKE principal.

        O Terraform cria um cluster privado na região us-central1 e ativa a cópia de segurança do GKE para recuperação de desastres e o serviço gerido para Prometheus para monitorização de clusters.

        O Managed Service for Prometheus só é suportado em clusters do Autopilot com a versão 1.25 ou posterior do GKE.

        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
        }

      • Crie um cluster de cópia de segurança na região us-west1 para recuperação de desastres.

        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

      No Cloud Shell, execute os seguintes comandos:

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

      Quando lhe for pedido, escreva yes.

      Compreenda a configuração do Terraform

      Os ficheiros de configuração do Terraform criam os seguintes recursos para implementar a sua infraestrutura:

      • Crie um repositório do Artifact Registry para armazenar as imagens 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}",
          ]
        }
      • Crie a rede VPC e a sub-rede para a interface de rede da 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]
        }
      • Crie um cluster do GKE principal.

        O Terraform cria um cluster privado na região us-central1 e ativa a cópia de segurança do GKE para recuperação de desastres e o serviço gerido para Prometheus para monitorização de clusters.

        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
        }

      • Crie um cluster de cópia de segurança na região us-west1 para recuperação de desastres.

        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
        }

      Implemente o PostgreSQL no seu cluster

      Nesta secção, vai implementar uma instância da base de dados PostgreSQL para ser executada no GKE através de um gráfico Helm.

      Instale o PostgreSQL

      Para instalar o PostgreSQL no seu cluster, siga estes passos.

      1. Configure o acesso ao Docker.

        gcloud auth configure-docker us-docker.pkg.dev
        
      2. Preencha o Artifact Registry com as imagens Docker do PostgreSQL necessárias.

        ./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
        

        O script envia as seguintes imagens do Bitnami para o Artifact Registry para o Helm instalar:

        • postgresql-repmgr: Esta solução de cluster do PostgreSQL inclui o gestor de replicação do PostgreSQL (repmgr), uma ferramenta de código aberto para gerir a replicação e a comutação por falha em clusters do PostgreSQL.
        • postgres-exporter: O PostgreSQL Exporter recolhe métricas do PostgreSQL para consumo do Prometheus.
        • pgpool: o Pgpool-II é o proxy do PostgreSQL. Oferece agrupamento de ligações e balanceamento de carga.
      3. Verifique se as imagens corretas estão armazenadas no repositório.

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

        O resultado é semelhante ao seguinte:

        ---
        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. Configure o acesso à linha de comandos kubectl ao cluster principal.

        gcloud container clusters get-credentials $SOURCE_CLUSTER \
        --location=$REGION --project=$PROJECT_ID
        
      5. Crie um espaço de nomes.

        export NAMESPACE=postgresql
        kubectl create namespace $NAMESPACE
        
      6. Se estiver a implementar num cluster do Autopilot, configure o aprovisionamento de nós em três zonas. Pode ignorar este passo se estiver a implementar num cluster padrão.

        Por predefinição, o Autopilot aprovisiona recursos apenas em duas zonas. A implementação definida em prepareforha.yaml garante que o Autopilot aprovisiona nós em três zonas no seu cluster, definindo os seguintes valores:

        • replicas:3
        • podAntiAffinity com 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. Atualize a dependência do Helm.

        cd helm/postgresql-bootstrap
        helm dependency update
        
      8. Inspeccione e valide os gráficos que o Helm vai instalar.

        helm -n postgresql template postgresql . \
          --set global.imageRegistry="us-docker.pkg.dev/$PROJECT_ID/main"
        
      9. Instale o gráfico Helm.

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

        O resultado é semelhante ao seguinte:

        NAMESPACE: postgresql
        STATUS: deployed
        REVISION: 1
        TEST SUITE: None
        
      10. Verifique se as réplicas do PostgreSQL estão em execução.

        kubectl get all -n $NAMESPACE
        

        O resultado é semelhante ao seguinte:

        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
        

      Crie um conjunto de dados de teste

      Nesta secção, vai criar uma base de dados e uma tabela com valores de exemplo. A base de dados serve como um conjunto de dados de teste para o processo de comutação por falha que vai testar mais tarde neste tutorial.

      1. Estabeleça ligação à sua instância do PostgreSQL.

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

        O resultado é semelhante ao seguinte:

        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. Inicie uma sessão de shell.

        kubectl exec -it pg-client -n postgresql -- /bin/bash
        
      3. Crie uma base de dados e uma tabela e, em seguida, insira algumas linhas de teste.

        psql -h $HOST_PGPOOL -U postgres -a -q -f /tmp/scripts/generate-db.sql
        
      4. Verifique o número de linhas de cada tabela.

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

        O resultado é semelhante ao seguinte:

        select COUNT(*) from tb01;
         count
        --------
         300000
        (1 row)
        
        select COUNT(*) from tb02;
         count
        --------
         300000
        (1 row)
        
      5. Gere dados de teste.

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

        O resultado é semelhante ao seguinte:

        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. Saia do pod do cliente postgres.

        exit
        

      Monitorize o PostgreSQL

      Nesta secção, vai ver métricas e configurar alertas para a sua instância do PostgreSQL. Vai usar o serviço gerido do Google Cloud para Prometheus para realizar a monitorização e os alertas.

      Ver métricas

      A sua implementação do PostgreSQL inclui um contentor secundário postgresql-exporter. Este contentor expõe um ponto final /metrics. O Google Cloud Managed Service for Prometheus está configurado para monitorizar os pods do PostgreSQL neste ponto final. Pode ver estas métricas através dos Google Cloud painéis de controlo da consola.

      A Google Cloud consola oferece algumas formas de criar e guardar a configuração do painel de controlo:

      • Criação e exportação: pode criar painéis de controlo diretamente na Google Cloud consola, e, em seguida, exportá-los e armazená-los num repositório de código. Para o fazer, na barra de ferramentas do painel de controlo, abra o editor JSON e transfira o ficheiro JSON do painel de controlo.
      • Armazenamento e importação: pode importar um painel de controlo a partir de um ficheiro JSON clicando em +Criar painel de controlo e carregando o conteúdo JSON do painel de controlo através do menu Editor JSON.

      Para visualizar dados da sua aplicação PostgreSQL e cluster do GKE, siga estes passos:

      1. Crie os seguintes painéis de controlo.

        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. Na Google Cloud consola, navegue para o painel de controlo do Cloud Monitoring. Aceda ao painel de controlo do Cloud Monitoring

      3. Selecione Personalizado na lista do painel de controlo. São apresentados os seguintes painéis de controlo:

        • Vista geral do PostgreSQL: apresenta métricas da aplicação PostgreSQL, incluindo o tempo de atividade da base de dados, o tamanho da base de dados e a latência das transações.
        • Cluster do PostgreSQL do GKE: apresenta métricas do cluster do GKE no qual o PostgreSQL está a ser executado, incluindo a utilização da CPU, a utilização da memória e a utilização do volume.
      4. Clique em cada link para examinar os painéis de controlo gerados.

      Configure alertas

      Os alertas permitem-lhe ter conhecimento atempado dos problemas nas suas aplicações para que possa resolvê-los rapidamente. Pode criar uma política de alertas para especificar as circunstâncias em que quer receber alertas e como quer ser notificado. Também pode criar canais de notificação que lhe permitem selecionar onde os alertas são enviados.

      Nesta secção, vai usar o Terraform para configurar os seguintes alertas de exemplo:

      • db_max_transaction: monitoriza o atraso máximo das transações em segundos; é acionado um alerta se o valor for superior a 10.
      • db_node_up: monitoriza o estado dos agrupamentos da base de dados; 0 significa que um agrupamento está inativo e aciona um alerta.

      Para configurar alertas, siga estes passos:

      1. Configure alertas com o 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
        

        Substitua os seguintes valores:

        • YOUR_EMAIL: o seu endereço de email.

        O resultado é semelhante ao seguinte :

        Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
        
      2. Estabeleça ligação ao pod do cliente.

        cd ../../../
        kubectl exec -it --namespace postgresql pg-client -- /bin/bash
        
      3. Gere um teste de carga para testar o alerta db_max_transaction.

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

        O resultado é semelhante ao seguinte:

        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).
        

        O alerta é acionado e envia um email para YOUR_EMAIL com uma linha de assunto que começa por "[ALERTA] Atraso máximo da transação".

      4. Na Google Cloud consola, navegue para a página Política de alertas.

        Aceder à política de alertas

      5. Selecione db_max_transaction nas políticas apresentadas. No gráfico, deve ver um pico do teste de carga que excede o limite de 10 para a métrica do Prometheus pg_stat_activity_max_tx_duration/gauge.

      6. Saia do pod do cliente postgres.

        exit
        

      Faça a gestão das atualizações do PostgreSQL e do GKE

      As atualizações de versões do PostgreSQL e do Kubernetes são lançadas regularmente. Siga as práticas recomendadas operacionais para atualizar regularmente o seu ambiente de software. Por predefinição, o GKE gere as atualizações do cluster e do conjunto de nós por si.

      Atualize o PostgreSQL

      Esta secção mostra como pode fazer uma atualização de versão do PostgreSQL. Para este tutorial, vai usar uma estratégia de atualização contínua para atualizar os seus pods, de modo que, em nenhum momento, todos os pods fiquem inativos.

      Para fazer uma atualização de versão, siga estes passos:

      1. Envie uma versão atualizada da imagem postgresql-repmgr para o Artifact Registry. Defina a nova versão (por exemplo, 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. Acione uma atualização contínua através de 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
        

        O StatefulSet conclui uma atualização contínua, começando pela réplica ordinal mais alta e terminando na mais baixa.

        O resultado é semelhante ao seguinte:

        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...
        

      Planeie atualizações do GKE em clusters Standard

      Esta secção é aplicável se estiver a executar clusters padrão. Pode tomar medidas proativas e definir configurações para mitigar o risco e facilitar uma atualização mais suave do cluster quando estiver a executar serviços com estado, incluindo:

      • Siga as práticas recomendadas do GKE para atualizar clusters. Escolha uma estratégia de atualização adequada para garantir que as atualizações ocorrem durante o período de manutenção:

        • Escolha atualizações de picos se a otimização de custos for importante e se as suas cargas de trabalho puderem tolerar um encerramento normal em menos de 60 minutos.
        • Escolha atualizações azul-verde se as suas cargas de trabalho forem menos tolerantes a interrupções e um aumento temporário do custo devido a uma maior utilização de recursos for aceitável.

        Para saber mais, consulte o artigo Atualize um cluster que execute uma carga de trabalho com estado.

      • Use o serviço Recommender para verificar se existem estatísticas de descontinuação e recomendações para evitar interrupções do serviço.

      • Use janelas de manutenção para garantir que as atualizações ocorrem quando pretende. Antes da janela de manutenção, certifique-se de que as cópias de segurança da base de dados são bem-sucedidas.

      • Antes de permitir o tráfego para os nós atualizados, use sondas de prontidão e de atividade para garantir que estão prontas para o tráfego.

      • Crie sondagens que avaliem se a replicação está sincronizada antes de aceitar tráfego. Isto pode ser feito através de scripts personalizados, consoante a complexidade e a escala da sua base de dados.

      Valide a disponibilidade da base de dados durante as atualizações de clusters padrão

      Esta secção é aplicável se estiver a executar clusters padrão. Para verificar a disponibilidade do PostgreSQL durante as atualizações, o processo geral consiste em gerar tráfego na base de dados do PostgreSQL durante o processo de atualização. Em seguida, use pgbench para verificar se a base de dados consegue processar um nível base de tráfego durante uma atualização, em comparação com quando a base de dados está totalmente disponível.

      1. Estabeleça ligação à sua instância do PostgreSQL.

        ./scripts/launch-client.sh
        

        O resultado é semelhante ao seguinte:

        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. No Cloud Shell, aceda ao shell do pod do cliente.

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

        pgbench -i -h $HOST_PGPOOL -U postgres postgres
        
      4. Use o seguinte comando para obter resultados de base para confirmar que a sua aplicação PostgreSQL permanece altamente disponível durante o período para uma atualização. Para obter um resultado de base, teste com várias ligações através de várias tarefas (threads) durante 30 segundos.

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

        O resultado tem um aspeto semelhante ao seguinte:

        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. Para garantir a disponibilidade durante as atualizações, pode gerar alguma carga na sua base de dados e garantir que a aplicação PostgreSQL oferece uma taxa de resposta consistente durante a atualização. Para realizar este teste, gere algum tráfego em relação à base de dados através do comando pgbench. O seguinte comando é executado pgbench durante uma hora, segmentando 200 TPS (transações por segundo) e apresentando a taxa de pedidos a cada 2 segundos.

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

        Onde:

        • --client: número de clientes simulados, ou seja, número de sessões de base de dados em simultâneo.
        • --jobs: número de threads de trabalho no pgbench. A utilização de mais do que uma discussão pode ser útil em computadores com várias CPUs. Os clientes são distribuídos o mais uniformemente possível entre as threads disponíveis. A predefinição é 1.
        • --rate: a taxa é apresentada em transações por segundo
        • --progress: mostra o relatório de progresso a cada sec segundos.

        O resultado é semelhante ao seguinte:

        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. Na Google Cloud consola, navegue novamente para o painel de controlo Vista geral do PostgreSQL no Cloud Monitoring. Repare no pico nos gráficos Ligação por BD e Ligação por pod.

      7. Saia do pod do cliente.

        exit
        
      8. Elimine o pod do cliente.

        kubectl delete pod -n postgresql pg-client
        

      Simule uma interrupção do serviço PostgreSQL

      Nesta secção, vai simular uma interrupção do serviço numa das réplicas do PostgreSQL parando o serviço do gestor de replicação. Isto impede que o pod publique tráfego para as respetivas réplicas de pares e que as respetivas sondas de atividade falhem.

      1. Abra uma nova sessão do Cloud Shell e configure o acesso à linha de comandos kubectl ao cluster principal.

        gcloud container clusters get-credentials $SOURCE_CLUSTER \
        --location=$REGION --project=$PROJECT_ID
        
      2. Veja os eventos do PostgreSQL emitidos no Kubernetes.

        kubectl get events -n postgresql --field-selector=involvedObject.name=postgresql-postgresql-ha-postgresql-0 --watch
        
      3. Na sessão anterior do Cloud Shell, simule uma falha de serviço parando o PostgreSQL repmgr.

        1. Anexe a sua sessão ao contentor da base de dados.

          kubectl exec -it -n $NAMESPACE postgresql-postgresql-ha-postgresql-0 -c postgresql -- /bin/bash
          
        2. Pare o serviço através de repmgr e remova o ponto de verificação e o argumento 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
          

      A sondagem de atividade configurada para o contentor PostgreSQL começa a falhar dentro de cinco segundos. Isto repete-se a cada dez segundos até ser atingido o limite de falhas de seis falhas. Quando o valor de failureThreshold é atingido, o contentor é reiniciado. Pode configurar estes parâmetros para diminuir a tolerância da sondagem de atividade para ajustar os requisitos de SLO da sua implementação.

      Na stream de eventos, vê que as sondas de atividade e prontidão do pod falham e uma mensagem a indicar que o contentor tem de ser reiniciado. O resultado é semelhante ao seguinte:

      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
      

      Prepare-se para a recuperação de desastres

      Para garantir que as suas cargas de trabalho de produção permanecem disponíveis em caso de um evento que interrompa o serviço, deve preparar um plano de recuperação de desastres (RD). Para saber mais sobre o planeamento de recuperação de desastres, consulte o Guia de planeamento de recuperação de desastres.

      A recuperação de desastres para o Kubernetes pode ser implementada em duas fases:

      • A cópia de segurança envolve a criação de um instantâneo do seu estado ou dados num determinado momento antes da ocorrência de um evento que interrompa o serviço.
      • A recuperação envolve a restauração do seu estado ou dados a partir de uma cópia de segurança após a ocorrência de um desastre.

      Para fazer uma cópia de segurança e restaurar as suas cargas de trabalho em clusters do GKE, pode usar a cópia de segurança do GKE. Pode ativar este serviço em clusters novos e existentes. Isto implementa um agente de cópia de segurança para o GKE que é executado nos seus clusters. O agente é responsável por capturar dados de configuração e de cópia de segurança de volumes, bem como por orquestrar a recuperação.

      As cópias de segurança e os restauros podem estar no âmbito de um cluster completo, um espaço de nomes ou uma aplicação (definida por seletores como matchLabels).

      Exemplo de cenário de cópia de segurança e restauro do PostgreSQL

      O exemplo nesta secção mostra como pode realizar uma operação de cópia de segurança e restauro ao nível da aplicação, usando o recurso personalizado ProtectedApplication.

      O diagrama seguinte mostra os recursos de componentes na ProtectedApplication, nomeadamente um StatefulSet que representa a aplicação postgresql-ha e uma implementação de pgpool, que usam a mesma etiqueta (app.kubernetes.io/name: postgresql-ha).

      O diagrama mostra um exemplo de solução de cópia de segurança e recuperação para um cluster PostgreSQL de alta disponibilidade.
      Figura 2: exemplo de solução de cópia de segurança e recuperação para um cluster PostgreSQL de elevada disponibilidade.

      Para se preparar para fazer uma cópia de segurança e restaurar a sua carga de trabalho do PostgreSQL, siga estes passos:

      1. Configure as variáveis de ambiente. Neste exemplo, vai usar uma ProtectedApplication para restaurar a carga de trabalho do PostgreSQL e os respetivos volumes a partir do cluster do GKE de origem (us-central1) e, em seguida, restaurá-los para outro cluster do GKE numa região diferente (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. Verifique se a cópia de segurança do GKE está ativada nos seus clusters. Já deve estar ativado como parte da configuração do Terraform que fez anteriormente.

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

        Se a cópia de segurança do GKE estiver ativada, o resultado do comando mostra enabled=True.

      Configure um plano de cópia de segurança e faça um restauro

      A Cópia de segurança do GKE permite-lhe criar um plano de cópia de segurança como uma tarefa cron. Um plano de cópia de segurança contém uma configuração de cópia de segurança que inclui o cluster de origem, a seleção das cargas de trabalho das quais fazer uma cópia de segurança e a região na qual os artefactos de cópia de segurança produzidos ao abrigo deste plano são armazenados.

      Para fazer uma cópia de segurança e um restauro, siga estes passos:

      1. Valide o estado de ProtectedApplication em cluster-db1.

        kubectl get ProtectedApplication -A
        

        O resultado tem um aspeto semelhante ao seguinte:

        NAMESPACE    NAME            READY TO BACKUP
        postgresql   postgresql-ha   true
        
      2. Crie um plano de cópia de segurança para a 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. Crie manualmente uma cópia de segurança.

        gcloud beta container backup-restore backups create $BACKUP_NAME \
        --project=$PROJECT_ID \
        --location=$DR_REGION \
        --backup-plan=$BACKUP_PLAN_NAME \
        --wait-for-completion
        
      4. Configure um plano de restauro.

        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. Restaure a partir da cópia de segurança.

        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
        

      Verifique se o cluster foi restaurado

      Para verificar se o cluster restaurado tem todos os recursos de Pods, PersistentVolume e StorageClass esperados, siga estes passos:

      1. Configure o kubectl acesso à linha de comandos ao cluster de cópia de segurança cluster-db2.

        gcloud container clusters get-credentials $TARGET_CLUSTER --location $DR_REGION --project $PROJECT_ID
        
      2. Verifique se o StatefulSet está pronto com 3/3 pods.

        kubectl get all -n $NAMESPACE
        

        O resultado é semelhante ao seguinte:

        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. Verifique se todos os pods no espaço de nomes postgres estão em execução.

        kubectl get pods -n $NAMESPACE
        

        O resultado é semelhante ao seguinte:

        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. Valide os PersistentVolumes e a StorageClass. Durante o processo de restauro, o Backup for GKE cria uma classe de proxy na carga de trabalho de destino para substituir a classe de armazenamento aprovisionada na carga de trabalho de origem (gce-pd-gkebackup-dn no exemplo de saída).

        kubectl get pvc -n $NAMESPACE
        

        O resultado é semelhante ao seguinte:

        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
        

      Valide se os dados esperados foram restaurados

      Para validar se os dados esperados foram restaurados, siga estes passos:

      1. Estabeleça ligação à sua instância do PostgreSQL.

        ./scripts/launch-client.sh
        kubectl exec -it pg-client -n postgresql -- /bin/bash
        
      2. Verifique o número de linhas de cada tabela.

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

        Deve ver um resultado semelhante aos dados que escreveu anteriormente em Criar um conjunto de dados de teste. O resultado é semelhante ao seguinte:

        300000
        (1 row)
        
      3. Saia do pod do cliente.

        exit
        

      Limpar

      Para evitar incorrer em custos na sua conta do Google Cloud pelos recursos usados neste tutorial, elimine o projeto que contém os recursos ou mantenha o projeto e elimine os recursos individuais.

      Elimine o projeto

      A forma mais fácil de evitar a faturação é eliminar o projeto que criou para o 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. O que se segue?