Déployer une base de données PostgreSQL à disponibilité élevée sur GKE


PostgreSQL est une base de données Open Source de type objet-relationnel connue pour la fiabilité et l'intégrité des données. Elle est conforme à la norme ACID et accepte les clés étrangères, les jointures, les vues, les déclencheurs et les procédures stockées.

Ce document est destiné aux administrateurs de bases de données, aux architectes cloud et aux professionnels des opérations qui souhaitent déployer une topologie PostgreSQL à disponibilité élevée sur Google Kubernetes Engine (GKE).

Objectifs

Dans ce tutoriel, vous allez apprendre à effectuer les opérations suivantes :

  • Utiliser Terraform pour créer un cluster GKE régional.
  • Déployer une base de données PostgreSQL à disponibilité élevée.
  • Configurer la surveillance pour l'application PostgreSQL.
  • Effectuer des mises à niveau de la base de données PostgreSQL et du cluster GKE.
  • Simuler une interruption du cluster et un basculement de l'instance répliquée PostgreSQL.
  • Effectuer une sauvegarde et une restauration de la base de données PostgreSQL.

Architecture

Cette section décrit l'architecture de la solution que vous allez créer dans ce tutoriel.

Vous allez provisionner deux clusters GKE dans différentes régions : un cluster principal et un cluster de sauvegarde. Pour ce tutoriel, le cluster principal se trouve dans la région us-central1 et le cluster de sauvegarde se trouve dans la région us-west1. Cette architecture vous permet de provisionner une base de données PostgreSQL à disponibilité élevée et de tester la reprise après sinistre, comme décrit plus loin dans ce tutoriel.

Pour le cluster source, vous allez utiliser un chart Helm (bitnami/postgresql-ha) pour configurer un cluster PostgreSQL à haute disponibilité.

Le schéma montre un exemple d'architecture d'un cluster PostgreSQL à disponibilité élevée.
Figure 1 : Exemple d'architecture d'un cluster PostgreSQL à disponibilité élevée.

Coûts

Dans ce document, vous utilisez les composants facturables suivants de Google Cloud :

Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût. Les nouveaux utilisateurs de Google Cloud peuvent bénéficier d'un essai gratuit.

Une fois que vous avez terminé les tâches décrites dans ce document, vous pouvez éviter de continuer à payer des frais en supprimant les ressources que vous avez créées. Pour en savoir plus, consultez la section Effectuer un nettoyage.

Avant de commencer

Configurer votre projet

  1. Connectez-vous à votre compte Google Cloud. Si vous débutez sur Google Cloud, créez un compte pour évaluer les performances de nos produits en conditions réelles. Les nouveaux clients bénéficient également de 300 $ de crédits gratuits pour exécuter, tester et déployer des charges de travail.
  2. Dans Google Cloud Console, sur la page de sélection du projet, cliquez sur Créer un projet pour commencer à créer un projet Google Cloud.

    Accéder au sélecteur de projet

  3. Vérifiez que la facturation est activée pour votre projet Google Cloud.

  4. Activer les API Google Kubernetes Engine, Backup for GKE, Artifact Registry, Compute Engine, and IAM.

    Activer les API

  5. Dans Google Cloud Console, sur la page de sélection du projet, cliquez sur Créer un projet pour commencer à créer un projet Google Cloud.

    Accéder au sélecteur de projet

  6. Vérifiez que la facturation est activée pour votre projet Google Cloud.

  7. Activer les API Google Kubernetes Engine, Backup for GKE, Artifact Registry, Compute Engine, and IAM.

    Activer les API

Configurer les rôles

  1. Attribuez des rôles à votre compte Google. Exécutez la commande suivante une fois pour chacun des rôles IAM suivants : role/storage.objectViewer, role/logging.logWriter, role/artifactregistry.Admin, roles/container.clusterAdmin, role/container.serviceAgent, roles/serviceusage.serviceUsageAdmin, roles/iam.serviceAccountAdmin

    $ gcloud projects add-iam-policy-binding PROJECT_ID --member="user:EMAIL_ADDRESS" --role=ROLE
    • en remplaçant PROJECT_ID par l'ID de votre projet :
    • Remplacez EMAIL_ADDRESS par votre adresse e-mail.
    • Remplacez ROLE par chaque rôle individuel.

Configurer votre environnement

Dans ce tutoriel, vous utilisez Cloud Shell pour gérer les ressources hébergées sur Google Cloud. Cloud Shell est préinstallé avec les logiciels dont vous avez besoin pour ce tutoriel, y compris Docker, kubectl, gcloud CLI, Helm et Terraform.

Pour utiliser Cloud Shell afin de configurer votre environnement, procédez comme suit :

  1. Lancez une session Cloud Shell depuis la console Google Cloud en cliquant sur Icône d'activation Cloud Shell Activer Cloud Shell dans la console Google Cloud. Une session s'ouvre dans le volet inférieur de la console Google Cloud.

  2. Définissez les variables d'environnement.

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

    Remplacez les valeurs suivantes :

  3. Définissez les variables d'environnement par défaut.

    gcloud config set project PROJECT_ID
    
  4. Clonez le dépôt de code.

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    
  5. Accédez au répertoire de travail.

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

Créer l'infrastructure de votre cluster

Dans cette section, vous allez exécuter un script Terraform afin de créer un cloud privé virtuel (VPC) personnalisé, un dépôt Artifact Registry pour stocker des images PostgreSQL, et deux clusters GKE régionaux. Un cluster sera déployé dans us-central1 et le second cluster pour la sauvegarde sera déployé dans us-west1.

Pour créer le cluster, procédez comme suit :

Autopilot

Dans Cloud Shell, exécutez les commandes suivantes :

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

Lorsque vous y êtes invité, saisissez yes.

Comprendre la configuration Terraform

Les fichiers de configuration Terraform créent les ressources suivantes pour déployer votre infrastructure :

  • Ils créent un dépôt Artifact Registry pour stocker les images Docker.
    resource "google_artifact_registry_repository" "main" {
      location      = "us"
      repository_id = "main"
      format        = "DOCKER"
      project       = var.project_id
    }
  • Ils créent le réseau et le sous-réseau VPC pour l'interface réseau de la 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]
    }
  • Ils créent un cluster GKE principal.

    Terraform crée un cluster privé dans la région us-central1 et active les services Sauvegarde pour GKE pour la reprise après sinistre ainsi que Managed Service pour Prometheus pour la surveillance des clusters.

    Managed Service pour Prometheus n'est compatible qu'avec les clusters Autopilot exécutant la version 1.25 ou ultérieure de 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
    }

  • Ils créent un cluster de sauvegarde dans la région us-west1 pour la reprise après sinistre.

    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

Dans Cloud Shell, exécutez les commandes suivantes :

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

Lorsque vous y êtes invité, saisissez yes.

Comprendre la configuration Terraform

Les fichiers de configuration Terraform créent les ressources suivantes pour déployer votre infrastructure :

  • Ils créent un dépôt Artifact Registry pour stocker les images 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}",
      ]
    }
  • Ils créent le réseau et le sous-réseau VPC pour l'interface réseau de la 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]
    }
  • Ils créent un cluster GKE principal.

    Terraform crée un cluster privé dans la région us-central1 et active les services Sauvegarde pour GKE pour la reprise après sinistre ainsi que Managed Service pour Prometheus pour la surveillance des 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
    }

  • Ils créent un cluster de sauvegarde dans la région us-west1 pour la reprise après sinistre.

    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
    }

Déployer PostgreSQL sur votre cluster

Dans cette section, vous allez déployer une instance de base de données PostgreSQL à exécuter sur GKE à l'aide d'un chart Helm.

Installer PostgreSQL

Pour installer PostgreSQL sur votre cluster, procédez comme suit :

  1. Configurez l'accès à Docker.

    gcloud auth configure-docker us-docker.pkg.dev
    
  2. Renseignez Artifact Registry avec les images Docker PostgreSQL requises.

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

    Le script transfère les images Bitnami suivantes vers Artifact Registry pour que Helm les installe :

    • postgresql-repmgr : cette solution de cluster PostgreSQL inclut le gestionnaire de réplication PostgreSQL (repmgr), un outil Open Source permettant de gérer la réplication et le basculement sur les clusters PostgreSQL.
    • postgres-exporter : PostgreSQL Exporter collecte des métriques PostgreSQL pour la consommation de Prometheus.
    • pgpool : Pgpool-II est le proxy PostgreSQL. Il fournit un regroupement de connexions et un équilibrage de charge.
  3. Vérifiez que les images adéquates sont stockées dans le dépôt.

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

    Le résultat ressemble à ce qui suit :

    ---
    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. Configurez l'accès via la ligne de commande kubectl au cluster principal.

    gcloud container clusters get-credentials $SOURCE_CLUSTER \
    --region=$REGION --project=$PROJECT_ID
    
  5. Créez un espace de noms.

    export NAMESPACE=postgresql
    kubectl create namespace $NAMESPACE
    
  6. Si vous procédez au déploiement sur un cluster Autopilot, configurez le provisionnement des nœuds sur trois zones. Vous pouvez ignorer cette étape si vous effectuez un déploiement sur un cluster Standard.

    Par défaut, Autopilot provisionne des ressources dans deux zones uniquement. Le déploiement défini dans prepareforha.yaml garantit que Autopilot provisionne les nœuds sur trois zones de votre cluster, en définissant les valeurs suivantes :

    • replicas:3
    • podAntiAffinity avec requiredDuringSchedulingIgnoredDuringExecution et 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. Mettez à jour la dépendance Helm.

    cd helm/postgresql-bootstrap
    helm dependency update
    
  8. Inspectez et vérifiez les charts qui seront installés par Helm.

    helm -n postgresql template postgresql . \
      --set global.imageRegistry="us-docker.pkg.dev/$PROJECT_ID/main"
    
  9. Installez le chart Helm.

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

    Le résultat ressemble à ce qui suit :

    NAMESPACE: postgresql
    STATUS: deployed
    REVISION: 1
    TEST SUITE: None
    
  10. Vérifiez que les instances répliquées PostgreSQL sont en cours d'exécution.

    kubectl get all -n $NAMESPACE
    

    Le résultat ressemble à ce qui suit :

    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
    

Créer un ensemble de données de test

Dans cette section, vous allez créer une base de données et une table avec des exemples de valeurs. La base de données sert d'ensemble de données de test pour le processus de basculement que vous testerez plus loin dans ce tutoriel.

  1. Connectez-vous à l'instance PostgreSQL.

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

    Le résultat ressemble à ce qui suit :

    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. Démarrez une session shell.

    kubectl exec -it pg-client -n postgresql -- /bin/bash
    
  3. Créez une base de données et une table, puis insérez des lignes de test.

    psql -h $HOST_PGPOOL -U postgres -a -q -f /tmp/scripts/generate-db.sql
    
  4. Vérifiez le nombre de lignes pour chaque table.

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

    Le résultat ressemble à ce qui suit :

    select COUNT(*) from tb01;
     count
    --------
     300000
    (1 row)
    
    select COUNT(*) from tb02;
     count
    --------
     300000
    (1 row)
    
  5. Générez les données de test.

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

    Le résultat ressemble à ce qui suit :

    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. Quittez le pod client postgres.

    exit
    

Surveiller PostgreSQL

Dans cette section, vous allez afficher les métriques et configurer des alertes pour votre instance PostgreSQL. Vous utiliserez Google Cloud Managed Service pour Prometheus pour effectuer des opérations de surveillance et d'alerte.

Afficher les métriques

Votre déploiement PostgreSQL inclut un conteneur side-car postgresql-exporter. Ce conteneur expose un point de terminaison /metrics. Google Cloud Managed Service pour Prometheus est configuré pour surveiller les pods PostgreSQL sur ce point de terminaison. Vous pouvez afficher ces métriques via les tableaux de bord de la console Google Cloud.

La console Google Cloud propose plusieurs méthodes pour créer et enregistrer la configuration d'un tableau de bord :

  • Création et exportation : vous pouvez créer des tableaux de bord directement dans la console Google Cloud, puis les exporter et les stocker dans un dépôt de code. Pour ce faire, dans la barre d'outils du tableau de bord, ouvrez l'éditeur JSON et téléchargez le fichier JSON du tableau de bord.
  • Stockage et importation : vous pouvez importer un tableau de bord à partir d'un fichier JSON en cliquant sur +Créer un tableau de bord et en important le contenu JSON du tableau de bord à l'aide du menu de l'Éditeur JSON.

Pour visualiser les données de votre application PostgreSQL et de votre cluster GKE, procédez comme suit :

  1. Créez les tableaux de bord suivants.

    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. Dans la console Google Cloud, accédez au tableau de bord Cloud Monitoring. Accéder au tableau de bord Cloud Monitoring

  3. Sélectionnez Personnalisé dans la liste du tableau de bord. Les tableaux de bord suivants s'affichent :

    • Vue d'ensemble PostgreSQL : affiche les métriques de l'application PostgreSQL, y compris le temps d'activité de la base de données, la taille de la base de données et la latence des transactions.
    • Cluster PostgreSQL GKE : affiche les métriques du cluster GKE sur lequel PostgreSQL est exécuté, y compris l'utilisation du processeur, de la mémoire et du volume.
  4. Cliquez sur chaque lien pour examiner les tableaux de bord générés.

Configurer des alertes

Les alertes permettent de détecter et de résoudre rapidement les problèmes qui surviennent dans les applications. Vous pouvez créer une règle d'alerte pour spécifier les circonstances dans lesquelles vous souhaitez être averti et comment vous souhaitez être averti. Vous pouvez également créer des canaux de notification vous permettant de sélectionner la destination des alertes.

Dans cette section, vous allez utiliser Terraform pour configurer les exemples d'alertes suivants :

  • db_max_transaction : surveille le retard maximal des transactions en secondes. Une alerte est déclenchée si la valeur est supérieure à 10.
  • db_node_up : surveille l'état des pods de base de données. "0" signifie qu'un pod est arrêté et déclenche une alerte.

Pour configurer des alertes, procédez comme suit :

  1. Configurez les alertes avec 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
    

    Remplacez les valeurs suivantes :

    • YOUR_EMAIL : votre adresse e-mail.

    Le résultat ressemble à ce qui suit :

    Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
    
  2. Connectez-vous au pod client.

    cd ../../../
    kubectl exec -it --namespace postgresql pg-client -- /bin/bash
    
  3. Générez un test de charge pour tester l'alerte db_max_transaction

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

    Le résultat ressemble à ce qui suit :

    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'alerte se déclenche et envoie un e-mail à YOUR_EMAIL avec un objet commençant par "[ALERTE] Retard maximal de transaction".

  4. Dans la console Google Cloud, accédez à la page Règle d'alerte.

    Accéder à la page Règle d'alerte

  5. Sélectionnez db_max_transaction dans la liste des règles. À partir du graphique, vous devriez constater un pic provenant du test de charge dépassant la valeur de seuil de 10 pour la métrique Prometheus pg_stat_activity_max_tx_duration/gauge.

  6. Quittez le pod client postgres.

    exit
    

Gérer les mises à niveau de PostgreSQL et GKE

Les mises à jour des versions de PostgreSQL et de Kubernetes sont publiées régulièrement. Suivez les bonnes pratiques opérationnelles pour mettre régulièrement à jour votre environnement logiciel. Par défaut, GKE gère automatiquement les mises à niveau des clusters et des pools de nœuds.

Mettre à niveau PostgreSQL

Cette section explique comment effectuer une mise à niveau de version pour PostgreSQL. Dans ce tutoriel, vous allez utiliser une stratégie de mise à jour progressive pour mettre à niveau vos pods, de sorte que tous les pods ne soient jamais hors service en même temps.

Pour mettre à niveau une version, procédez comme suit :

  1. Transférez une version mise à jour de l'image postgresql-repmgr vers Artifact Registry. Définissez la nouvelle version (par exemple, 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. Déclenchez une mise à jour progressive à l'aide 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
    

    Le StatefulSet va effectuer une mise à jour progressive, en commençant par l'instance répliquée ordinale la plus élevée vers la plus basse.

    Le résultat ressemble à ce qui suit :

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

Planifier les mises à niveau de GKE sur les clusters standards

Cette section ne concerne que l'exécution de clusters standards. Vous pouvez prendre des mesures proactives et définir des configurations pour limiter les risques et faciliter la mise à niveau des clusters lorsque vous exécutez des services avec état, y compris les suivants :

  • Suivez les bonnes pratiques de GKE pour la mise à niveau des clusters. Choisissez une stratégie de mise à niveau appropriée pour vous assurer que les mises à niveau se produisent pendant l'intervalle de maintenance :

    • Choisissez les mises à niveau de la surutilisation si l'optimisation des coûts est importante et si vos charges de travail peuvent tolérer un arrêt progressif en moins de 60 minutes.
    • Choisissez des mises à niveau bleu-vert si les charges de travail sont moins tolérantes aux perturbations, et qu'une augmentation temporaire des coûts due à une utilisation plus élevée des ressources est acceptable.

    Pour en savoir plus, consultez la page Mettre à niveau un cluster exécutant une charge de travail avec état.

  • Utilisez l'outil de recommandation pour vérifier la présence d'insights et recommandations d'abandon afin d'éviter toute interruption de service.

  • Utilisez des intervalles de maintenance pour vous assurer que les mises à niveau se produisent lorsque vous le souhaitez. Avant l'intervalle de maintenance, assurez-vous que les sauvegardes de votre base de données ont abouti.

  • Avant d'autoriser le trafic vers les nœuds mis à niveau, utilisez les vérifications d'aptitude et d'activité pour vous assurer qu'ils sont prêts à recevoir le trafic.

  • Créez des vérifications qui évaluent si la réplication est synchronisée avant d'accepter le trafic. Cette opération peut être effectuée via des scripts personnalisés, en fonction de la complexité et de l'échelle de votre base de données.

Vérifier la disponibilité de la base de données lors des mises à niveau des clusters standards

Cette section ne concerne que l'exécution de clusters standards. Pour vérifier la disponibilité de PostgreSQL lors des mises à niveau, le processus général consiste à générer du trafic sur la base de données PostgreSQL pendant le processus de mise à niveau. Utilisez ensuite pgbench pour vérifier que la base de données peut gérer un niveau de trafic de base lors d'une mise à niveau, comparé au moment où la base de données est entièrement disponible.

  1. Connectez-vous à l'instance PostgreSQL.

    ./scripts/launch-client.sh
    

    Le résultat ressemble à ce qui suit :

    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. Dans Cloud Shell, ouvrez une interface système dans le pod client.

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

    pgbench -i -h $HOST_PGPOOL -U postgres postgres
    
  4. Utilisez la commande suivante pour obtenir des résultats de référence afin de confirmer que votre application PostgreSQL reste hautement disponible pendant la période de mise à niveau. Pour obtenir un résultat de référence, effectuez un test avec des connexions multiples via plusieurs jobs (threads) pendant 30 secondes.

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

    La sortie ressemble à ceci :

    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. Pour garantir la disponibilité lors des mises à niveau, vous pouvez générer une certaine charge sur votre base de données et vous assurer que l'application PostgreSQL fournit un taux de réponse cohérent lors de la mise à niveau. Pour effectuer ce test, générez du trafic sur la base de données à l'aide de la commande pgbench. La commande suivante exécute pgbench pendant une heure, en ciblant 200 TPS (transactions par seconde) et en répertoriant le taux de requêtes toutes les deux secondes.

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

    Où :

    • --client : nombre de clients simulés, c'est-à-dire le nombre de sessions de base de données simultanées.
    • --jobs : nombre de threads de calcul dans pgbench. L'utilisation de plusieurs threads peut être utile sur les machines multiprocesseurs. Les clients sont distribués aussi uniformément que possible entre les threads disponibles. La valeur par défaut est 1.
    • --rate : le taux est exprimé en transactions par seconde.
    • --progress : affiche le rapport de progression toutes les secondes.

    Le résultat ressemble à ce qui suit :

    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. Dans la console Google Cloud, revenez au tableau de bord Vue d'ensemble de PostgreSQL dans Cloud Monitoring. Notez les pics dans les graphiques Connexion par base de données et Connexion par pod.

  7. Quittez le pod client.

    exit
    
  8. Supprimez le pod client.

    kubectl delete pod -n postgresql pg-client
    

Simuler une interruption de service PostgreSQL

Dans cette section, vous allez simuler une interruption de service dans l'une des instances répliquées PostgreSQL en arrêtant le service du gestionnaire de réplication. Cette opération empêchera le pod de diffuser du trafic vers ses instances répliquées appairées et empêchera également ses vérifications d'activité d'échouer.

  1. Ouvrez une nouvelle session Cloud Shell et configurez l'accès via la ligne de commande kubectl au cluster principal.

    gcloud container clusters get-credentials $SOURCE_CLUSTER \
    --region=$REGION --project=$PROJECT_ID
    
  2. Affichez les événements PostgreSQL émis dans Kubernetes.

    kubectl get events -n postgresql --field-selector=involvedObject.name=postgresql-postgresql-ha-postgresql-0 --watch
    
  3. Dans la session Cloud Shell précédente, simulez une défaillance de service en arrêtant PostgreSQL repmgr.

    1. Rattachez votre session au conteneur de base de données.

      kubectl exec -it -n $NAMESPACE postgresql-postgresql-ha-postgresql-0 -c postgresql -- /bin/bash
      
    2. Arrêtez le service à l'aide de repmgr, puis supprimez le point de contrôle et l'argument 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
      

La vérification d'activité configurée pour le conteneur PostgreSQL va commencer à échouer dans les cinq secondes. Ce processus se répète toutes les dix secondes, jusqu'à ce que le seuil de six échecs soit atteint. Une fois la valeur de failureThreshold atteinte, le conteneur est redémarré. Vous pouvez configurer ces paramètres pour réduire la tolérance de la vérification d'activité afin d'adapter les exigences de SLO de votre déploiement.

Dans le flux d'événements, vous pourrez voir les vérifications d'activité et d'aptitude du pod échouer, ainsi qu'un message indiquant que le conteneur doit être redémarré. Le résultat ressemble à ce qui suit :

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

Préparer la reprise après sinistre

Pour garantir la disponibilité de vos charges de travail de production en cas d'interruption de service, vous devez préparer un plan de reprise après sinistre. Pour en savoir plus sur la planification de reprise après sinistre, consultez le Guide de planification de reprise après sinistre.

La reprise après sinistre pour Kubernetes peut être implémentée en deux phases :

  • La sauvegarde implique la création d'un instantané de votre état ou de vos données à un moment précis avant qu'une interruption de service ne se produise.
  • La récupération implique la restauration de votre état ou de vos données à partir d'une copie de sauvegarde après un sinistre.

Pour sauvegarder et restaurer vos charges de travail sur des clusters GKE, vous pouvez utiliser le service de Sauvegarde pour GKE. Vous pouvez activer ce service sur des clusters nouveaux et existants. Cette opération déploie un agent Sauvegarde pour GKE qui s'exécute dans vos clusters. L'agent est chargé de capturer les données de configuration et de sauvegarde de volume et d'orchestrer la récupération.

Les sauvegardes et les restaurations peuvent être limitées à un cluster entier, un espace de noms ou une application (défini par des sélecteurs tels que matchLabels).

Exemple de scénario de sauvegarde et de restauration PostgreSQL

L'exemple de cette section montre comment effectuer une sauvegarde et une restauration au niveau de l'application à l'aide de la ressource personnalisée ProtectedApplication.

Le schéma suivant montre les ressources de composant dans l'application protégée (ProtectedApplication), à savoir un StatefulSet représentant l'application postgresql-ha et un déploiement de pgpool, qui utilise la même étiquette (app.kubernetes.io/name: postgresql-ha).

Le schéma montre un exemple de solution de sauvegarde et de récupération pour un cluster PostgreSQL à disponibilité élevée.
Figure 2 : Exemple de solution de sauvegarde et de récupération pour un cluster PostgreSQL à disponibilité élevée.

Pour préparer la sauvegarde et la restauration de votre charge de travail PostgreSQL, procédez comme suit :

  1. Configurez les variables d'environnement. Dans cet exemple, vous allez utiliser une ProtectedApplication pour restaurer la charge de travail PostgreSQL et ses volumes à partir du cluster GKE source (us-central1), puis effectuer une restauration sur un autre cluster GKE situé dans une région différente (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. Vérifiez que Sauvegarde pour GKE est activé sur votre cluster. Ce service devrait déjà être activé par la configuration de Terraform que vous avez effectuée précédemment.

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

    Si Sauvegarde pour GKE est activé, le résultat de la commande affiche enabled=True.

Configurer un plan de sauvegarde et effectuer une restauration

Sauvegarde pour GKE vous permet de créer un plan de sauvegarde en tant que job Cron. Un plan de sauvegarde contient une configuration de sauvegarde comprenant le cluster source, la sélection des charges de travail à sauvegarder et la région de stockage des artefacts de sauvegarde produits dans le cadre de ce plan.

Pour effectuer une sauvegarde et une restauration, procédez comme suit :

  1. Vérifiez l'état de ProtectedApplication sur cluster-db1.

    kubectl get ProtectedApplication -A
    

    La sortie ressemble à ceci :

    NAMESPACE    NAME            READY TO BACKUP
    postgresql   postgresql-ha   true
    
  2. Créez un plan de sauvegarde pour la 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. Créez manuellement une sauvegarde.

    gcloud beta container backup-restore backups create $BACKUP_NAME \
    --project=$PROJECT_ID \
    --location=$DR_REGION \
    --backup-plan=$BACKUP_PLAN_NAME \
    --wait-for-completion
    
  4. Configurez un plan de restauration.

    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. Effectuez la restauration à partir de la sauvegarde.

    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
    

Vérifier que votre cluster est restauré

Pour vérifier que le cluster restauré dispose de toutes les ressources Pods, PersistentVolume et StorageClass attendues, procédez comme suit :

  1. Configurez l'accès via la ligne de commande kubectl au cluster de sauvegarde cluster-db2.

    gcloud container clusters get-credentials $TARGET_CLUSTER --region $DR_REGION --project $PROJECT_ID
    
  2. Vérifiez que le StatefulSet est prêt avec 3/3 pods.

    kubectl get all -n $NAMESPACE
    

    Le résultat ressemble à ce qui suit :

    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. Vérifiez que tous les pods de l'espace de noms postgres sont en cours d'exécution.

    kubectl get pods -n $NAMESPACE
    

    Le résultat ressemble à ce qui suit :

    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. Vérifiez les ressources PersistentVolume et StorageClass. Au cours du processus de restauration, Sauvegarde pour GKE crée une classe de proxy dans la charge de travail cible pour remplacer la StorageClass provisionnée dans la charge de travail source (gce-pd-gkebackup-dn dans l'exemple de résultat).

    kubectl get pvc -n $NAMESPACE
    

    Le résultat ressemble à ce qui suit :

    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
    

Vérifier que les données attendues sont restaurées

Pour vérifier que les données attendues sont restaurées, procédez comme suit :

  1. Connectez-vous à l'instance PostgreSQL.

    ./scripts/launch-client.sh
    kubectl exec -it pg-client -n postgresql -- /bin/bash
    
  2. Vérifiez le nombre de lignes pour chaque table.

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

    Vous devriez voir un résultat semblable aux données que vous avez écrites plus tôt dans la section Créer un ensemble de données de test. Le résultat ressemble à ce qui suit :

    300000
    (1 row)
    
  3. Quittez le pod client.

    exit
    

Effectuer un nettoyage

Pour éviter que les ressources utilisées lors de ce tutoriel soient facturées sur votre compte Google Cloud, supprimez le projet contenant les ressources, ou conservez le projet et supprimez les ressources individuelles.

Supprimer le projet

Le moyen le plus simple d'empêcher la facturation est de supprimer le projet que vous avez créé pour ce tutoriel.

Supprimez un projet Google Cloud :

gcloud projects delete PROJECT_ID

Étapes suivantes