Esegui il deployment di PostgreSQL in GKE utilizzando Cloud NativePG


La guida mostra come eseguire il deployment di cluster PostgreSQL Google Kubernetes Engine (GKE) utilizzando CloudNativePG operatore.

PostgreSQL è un servizio relazionale open source con diversi decenni di sviluppo attivo, per garantire un client stabile delle prestazioni. Offre una serie di funzionalità, tra cui replica, point-in-time funzionalità di sicurezza ed estendebilità. PostgreSQL è compatibile con dei principali sistemi operativi ed è pienamente conforme agli standard ACID (Atomicità, di isolamento e durabilità).

Questa guida è rivolta agli amministratori di piattaforma, ai cloud architect e professionisti delle operazioni interessati al deployment di cluster Postgres su con GKE. Esecuzione di Postgres in GKE anziché utilizzare Cloud SQL può offrire maggiore flessibilità la configurazione del controllo ad amministratori di database esperti.

Vantaggi

Cloud NativePG è un operatore open source sviluppato da EDB con un Apache 2. Viene introdotto quanto segue al deployment PostgreSQL:

  • Un modo dichiarativo e nativo di Kubernetes per gestire, configurare Cluster PostgreSQL
  • Gestione dei backup mediante snapshot di volume o Cloud Storage
  • TLS criptato in transito connessione, la possibilità di utilizzare le proprie autorità di certificazione integrazione con Gestore certificati per TLS automatico emissione e rotazione dei certificati
  • Aggiornamenti in sequenza per release PostgreSQL minori
  • Utilizzo del server API Kubernetes per mantenere lo stato di un cluster PostgreSQL e per un'alta disponibilità senza bisogno di strumenti aggiuntivi
  • Una configurazione integrata dell'esportatore Prometheus tramite metriche definite dall'utente scritte in SQL

Obiettivi

  • Pianifica ed esegui il deployment dell'infrastruttura GKE per Postgres
  • Esegui il deployment e la configurazione dell'operatore Postgres Cloud NativePG con Helm
  • Esegui il deployment di un cluster PostgreSQL
  • Configurare l'autenticazione e l'osservabilità di PostgreSQL

Architettura di deployment

PostgreSQL offre varie opzioni di deployment, da un server di database autonomo a replicato di un cluster a disponibilità elevata. Questo tutorial è incentrato il deployment di cluster ad alta disponibilità su GKE.

In questo deployment, i carichi di lavoro del cluster PostgreSQL sono distribuiti in più zone di disponibilità all'interno del cluster GKE a livello di regione assicurando disponibilità elevata e ridondanza. Per ulteriori informazioni, consulta le relazioni cluster.

Il seguente diagramma mostra un cluster Postgres in esecuzione su più nodi e in un cluster GKE:

Cluster Postgres attivato
GKE

  • La configurazione predefinita include un server PostgreSQL principale e due server di backup pronto a prendere il comando in caso di guasto del server principale, garantendo una continuità la disponibilità del database.

  • Le risorse dell'operatore CloudnativePG utilizzano uno spazio dei nomi separato di cluster GKE per un migliore isolamento delle risorse. di un database per cluster PostgreSQL. Il database e l'utente corrispondente (utente dell'app) è definito nella configurazione risorsa che rappresenta il cluster.

  • L'archiviazione è un componente fondamentale quando si parla di database. Lo spazio di archiviazione deve prestazioni efficienti, garantire disponibilità continua e garantire coerenza. Per questi motivi, ti consigliamo lo spazio di archiviazione di premium-rwo che si basa sui dischi SSD. L'operatore Cloud NativePG crea PersistentVolumeClaims in base alle esigenze durante la configurazione dei pod per PostgreSQL.

Costi

In questo documento vengono utilizzati i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi basata sull'utilizzo previsto, utilizza il Calcolatore prezzi. I nuovi utenti di Google Cloud potrebbero essere idonei per una prova gratuita.

Una volta completate le attività descritte in questo documento, puoi evitare la fatturazione continua eliminando le risorse che hai creato. Per ulteriori informazioni, consulta la pagina Pulizia.

Prima di iniziare

Cloud Shell è preinstallato con il software necessario a questo scopo tutorial, tra cui kubectl, gcloud CLI, Helm e Terraform, Se non utilizzi Cloud Shell, devi installare con gcloud CLI.

  1. Accedi al tuo account Google Cloud. Se non conosci Google Cloud, crea un account per valutare le prestazioni dei nostri prodotti in scenari reali. I nuovi clienti ricevono anche 300 $di crediti gratuiti per l'esecuzione, il test e il deployment dei carichi di lavoro.
  2. Install the Google Cloud CLI.
  3. To initialize the gcloud CLI, run the following command:

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

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

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

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  5. Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.

  6. Abilita le API Compute Engine, IAM, GKE, Resource Manager.

    gcloud services enable compute.googleapis.com iam.googleapis.com container.googleapis.com cloudresourcemanager.googleapis.com
  7. Install the Google Cloud CLI.
  8. To initialize the gcloud CLI, run the following command:

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

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

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

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  10. Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.

  11. Abilita le API Compute Engine, IAM, GKE, Resource Manager.

    gcloud services enable compute.googleapis.com iam.googleapis.com container.googleapis.com cloudresourcemanager.googleapis.com
  12. Grant roles to your user account. Run the following command once for each of the following IAM roles: roles/compute.securityAdmin, roles/compute.viewer, roles/container.clusterAdmin, roles/container.admin, roles/iam.serviceAccountAdmin, roles/iam.serviceAccountUser

    gcloud projects add-iam-policy-binding PROJECT_ID --member="USER_IDENTIFIER" --role=ROLE
    • Replace PROJECT_ID with your project ID.
    • Replace USER_IDENTIFIER with the identifier for your user account. For example, user:myemail@example.com.

    • Replace ROLE with each individual role.

Configura l'ambiente

Per configurare l'ambiente:

  1. Imposta le variabili di ambiente:

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

    Sostituisci PROJECT_ID con il tuo progetto Google Cloud ID.

  2. Clona il repository GitHub:

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

    cd kubernetes-engine-samples/databases/postgresql-cloudnativepg
    

Crea l'infrastruttura del tuo cluster

In questa sezione eseguirai uno script Terraform per creare un'istanza privata, un cluster GKE a livello di regione e alta disponibilità.

Puoi installare l'operatore utilizzando un'interfaccia standard Autopilot in un cluster Kubernetes.

Standard

Il seguente diagramma mostra uno standard regionale privato Deployment di un cluster GKE in tre zone diverse:

Per eseguire il deployment di questa infrastruttura, esegui questi comandi:

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

Quando richiesto, digita yes. Potrebbero essere necessari diversi minuti prima che questo comando completata e affinché il cluster mostri lo stato Pronto.

Terraform crea le seguenti risorse:

  • Una rete VPC e una subnet privata per i nodi Kubernetes
  • Un router per accedere a Internet tramite NAT
  • Un cluster GKE privato nella regione us-central1
  • Un pool di nodi con scalabilità automatica abilitata (da uno a due nodi per zona, uno nodo per zona minimo)

L'output è simile al seguente:

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

Autopilot

Il seguente diagramma mostra un Autopilot a livello di regione privato Cluster GKE:

Per eseguire il deployment dell'infrastruttura, esegui questi comandi:

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

Quando richiesto, digita yes. Potrebbero essere necessari diversi minuti prima che questo comando completata e affinché il cluster mostri lo stato Pronto.

Terraform crea le seguenti risorse:

  • Una rete VPC e una subnet privata per i nodi Kubernetes
  • Un router per accedere a Internet tramite NAT
  • Un cluster GKE privato nella regione us-central1
  • Un ServiceAccount con autorizzazione di logging e monitoraggio
  • Google Cloud Managed Service per Prometheus per il monitoraggio dei cluster

L'output è simile al seguente:

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

Connettiti al cluster

Configura kubectl per comunicare con il cluster:

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

Esegui il deployment dell'operatore Cloud NativePG

Esegui il deployment di Cloud NativePG nel tuo cluster Kubernetes utilizzando un grafico Helm:

  1. Aggiungi il repository Helm Chart dell'operatore Cloud NativePG:

    helm repo add cnpg https://cloudnative-pg.github.io/charts
    
  2. Esegui il deployment dell'operatore Cloud NativePG utilizzando lo strumento a riga di comando Helm:

    helm upgrade --install cnpg \
        --namespace cnpg-system \
        --create-namespace \
        cnpg/cloudnative-pg
    

    L'output è simile al seguente:

    Release "cnpg" does not exist. Installing it now.
    NAME: cnpg
    LAST DEPLOYED: Fri Oct 13 13:52:36 2023
    NAMESPACE: cnpg-system
    STATUS: deployed
    REVISION: 1
    TEST SUITE: None
    ...
    

Esegui il deployment di Postgres

Il manifest seguente descrive un cluster PostgreSQL come definito dal Risorsa personalizzata dell'operatore Cloud NativePG:

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: gke-pg-cluster
spec:
  description: "Standard GKE PostgreSQL cluster"
  imageName: ghcr.io/cloudnative-pg/postgresql:16.2
  enableSuperuserAccess: true
  instances: 3
  startDelay: 300
  primaryUpdateStrategy: unsupervised
  postgresql:
    pg_hba:
      - host all all 10.48.0.0/20 md5
  bootstrap:
    initdb:
      database: app
  storage:
    storageClass: premium-rwo
    size: 2Gi
  resources:
    requests:
      memory: "1Gi"
      cpu: "1000m"
    limits:
      memory: "1Gi"
      cpu: "1000m"
  affinity:
    enablePodAntiAffinity: true
    tolerations:
    - key: cnpg.io/cluster
      effect: NoSchedule
      value: gke-pg-cluster
      operator: Equal
    additionalPodAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: app.component
              operator: In
              values:
              - "pg-cluster"
          topologyKey: topology.kubernetes.io/zone
  monitoring:
    enablePodMonitor: true

Questo manifest contiene i seguenti campi:

  • spec.instances: il numero di pod del cluster
  • spec.primaryUpdateStrategy: la strategia di aggiornamento in sequenza:
    • Unsupervised: aggiorna autonomamente il nodo del cluster principale dopo l'evento nodi di replica
    • Supervised: è necessario il cambio manuale per il nodo del cluster principale
  • spec.postgresql: postgres.conf override dei parametri file, ad esempio pag. hba di Google Cloud, LDAP e i requisiti per le repliche di sincronizzazione da soddisfare.
  • spec.storage: impostazioni relative all'archiviazione, ad esempio classe di archiviazione e volume dimensioni e write-ahead di log.
  • spec.bootstrap: parametri del database iniziale creato nel cluster, credenziali utente e opzioni di ripristino dei database
  • spec.resources: richieste e limiti per i pod del cluster
  • spec.affinity: regole di affinità e anti-affinità dei carichi di lavoro del cluster

Crea un cluster Postgres di base

  1. Crea uno spazio dei nomi:

    kubectl create ns pg-ns
    
  2. Crea il cluster PostgreSQL utilizzando la risorsa personalizzata:

    kubectl apply -n pg-ns -f manifests/01-basic-cluster/postgreSQL_cluster.yaml
    

    Il completamento di questo comando potrebbe richiedere diversi minuti.

  3. Controlla lo stato del cluster:

    kubectl get cluster -n pg-ns --watch
    

    Attendi che l'output mostri lo stato Cluster in healthy state prima vai al passaggio successivo.

    NAME             AGE     INSTANCES   READY   STATUS                     PRIMARY
    gke-pg-cluster   2m53s   3           3       Cluster in healthy state   gke-pg-cluster-1
    

Controlla le risorse

Verifica che GKE abbia creato le risorse per il cluster:

kubectl get cluster,pod,svc,pvc,pdb,secret,cm -n pg-ns

L'output è simile al seguente:

NAME                                        AGE   INSTANCES   READY   STATUS                     PRIMARY
cluster.postgresql.cnpg.io/gke-pg-cluster   32m   3           3       Cluster in healthy state   gke-pg-cluster-1

NAME                   READY   STATUS    RESTARTS   AGE
pod/gke-pg-cluster-1   1/1     Running   0          31m
pod/gke-pg-cluster-2   1/1     Running   0          30m
pod/gke-pg-cluster-3   1/1     Running   0          29m

NAME                        TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
service/gke-pg-cluster-r    ClusterIP   10.52.11.24   <none>        5432/TCP   32m
service/gke-pg-cluster-ro   ClusterIP   10.52.9.233   <none>        5432/TCP   32m
service/gke-pg-cluster-rw   ClusterIP   10.52.1.135   <none>        5432/TCP   32m

NAME                                     STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/gke-pg-cluster-1   Bound    pvc-bbdd1cdd-bdd9-4e7c-8f8c-1a14a87e5329   2Gi        RWO            standard       32m
persistentvolumeclaim/gke-pg-cluster-2   Bound    pvc-e7a8b4df-6a3e-43ce-beb0-b54ec1d24011   2Gi        RWO            standard       31m
persistentvolumeclaim/gke-pg-cluster-3   Bound    pvc-dac7f931-6ac5-425f-ac61-0cfc55aae72f   2Gi        RWO            standard       30m

NAME                                                MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
poddisruptionbudget.policy/gke-pg-cluster           1               N/A               1                     32m
poddisruptionbudget.policy/gke-pg-cluster-primary   1               N/A               0                     32m

NAME                                TYPE                       DATA   AGE
secret/gke-pg-cluster-app           kubernetes.io/basic-auth   3      32m
secret/gke-pg-cluster-ca            Opaque                     2      32m
secret/gke-pg-cluster-replication   kubernetes.io/tls          2      32m
secret/gke-pg-cluster-server        kubernetes.io/tls          2      32m
secret/gke-pg-cluster-superuser     kubernetes.io/basic-auth   3      32m

NAME                                DATA   AGE
configmap/cnpg-default-monitoring   1      32m
configmap/kube-root-ca.crt          1      135m

L'operatore crea le seguenti risorse:

  • Una risorsa personalizzata del cluster che rappresenta il cluster PostgreSQL, controllato dall'operatore
  • Risorse PersistentVolumeClaim con volumi permanenti corrispondenti
  • Secret con credenziali utente per l'accesso al database e la replica tra i nodi Postgres.
  • Tre servizi di endpoint di database: <name>-rw, <name>-ro e <name>-r per la connessione al cluster. Per saperne di più, consulta PostgreSQL dell'architettura.

Autenticazione in Postgres

Puoi connetterti al database PostgreSQL e controllare l'accesso tramite diverse e endpoint di servizio creati dall'operatore. Per farlo, utilizzerai un pod aggiuntivo con un client PostgreSQL e le credenziali utente dell'applicazione sincronizzate montate come variabili di ambiente.

  1. Esegui il pod del client per interagire con il cluster Postgres:

    kubectl apply -n pg-ns -f manifests/02-auth/pg-client.yaml
    
  2. Esegui un comando exec sul pod pg-client e accedi Servizio gke-pg-cluster-rw:

    kubectl wait --for=condition=Ready -n pg-ns pod/pg-client --timeout=300s
    kubectl exec -n pg-ns -i -t pg-client -- /bin/sh
    
  3. Accedi al database utilizzando il servizio gke-pg-cluster-rw per stabilire un connessione con privilegi di lettura e scrittura:

    psql postgresql://$CLIENTUSERNAME:$CLIENTPASSWORD@gke-pg-cluster-rw.pg-ns/app
    

    Il terminale inizia con il nome del tuo database:

    app=>
    
  4. Crea una tabella:

    CREATE TABLE travel_agency_clients (
    client VARCHAR ( 50 ) UNIQUE NOT NULL,
    address VARCHAR ( 50 ) UNIQUE NOT NULL,
    phone VARCHAR ( 50 ) UNIQUE NOT NULL);
    
  5. Inserisci i dati nella tabella:

    INSERT INTO travel_agency_clients(client, address, phone)
    VALUES ('Tom', 'Warsaw', '+55555')
    RETURNING *;
    
  6. Visualizza i dati che hai creato:

    SELECT * FROM travel_agency_clients ;
    

    L'output è simile al seguente:

    client | address |  phone
    --------+---------+---------
    Tom    | Warsaw  | +55555
    (1 row)
    
  7. Esci dalla sessione di database attuale:

    exit
    
  8. Accedi al database utilizzando il servizio gke-pg-cluster-ro per la verifica accesso di sola lettura. Questo servizio consente l'esecuzione di query sui dati, ma limita qualsiasi scrittura operazioni:

    psql postgresql://$CLIENTUSERNAME:$CLIENTPASSWORD@gke-pg-cluster-ro.pg-ns/app
    
  9. Prova a inserire nuovi dati:

    INSERT INTO travel_agency_clients(client, address, phone)
    VALUES ('John', 'Paris', '+55555')
    RETURNING *;
    

    L'output è simile al seguente:

    ERROR:  cannot execute INSERT in a read-only transaction
    
  10. Tentativo di lettura dei dati:

    SELECT * FROM travel_agency_clients ;
    

    L'output è simile al seguente:

    client | address |  phone
    --------+---------+---------
    Tom    | Warsaw  | +55555
    (1 row)
    
  11. Esci dalla sessione di database attuale:

    exit
    
  12. Esci dalla shell del pod:

    exit
    

Scopri come Prometheus raccoglie le metriche per il cluster Postgres

Il seguente diagramma mostra come funziona la raccolta delle metriche di Prometheus:

Nel diagramma, un cluster privato GKE contiene:

  • Un pod Postgres che raccoglie le metriche sul percorso / e sulla porta 9187
  • Collettori basati su Prometheus che elaborano le metriche dal pod Postgres
  • Una risorsa PodMonitoring che invia metriche a Cloud Monitoring

Per abilitare la raccolta delle metriche dai pod, segui questi passaggi:

  1. Crea la PodMonitoring risorsa:

    kubectl apply -f manifests/03-observability/pod-monitoring.yaml -n pg-ns
    
  2. Nella console Google Cloud, vai alla pagina Metrics Explorer:

    Vai a Esplora metriche

    La dashboard mostra una percentuale di importazione di metriche diversa da zero.

  3. In Seleziona una metrica, inserisci Target Prometheus.

  4. Nella sezione Categorie di metriche attive, seleziona Cnpg.

Crea una dashboard delle metriche

Per visualizzare le metriche esportate, crea una dashboard delle metriche.

  1. Esegui il deployment di una dashboard:

    gcloud --project "${PROJECT_ID}" monitoring dashboards create --config-from-file manifests/03-observability/gcp-pg.json
    
  2. Nella console Google Cloud, vai alla pagina Dashboard.

    Accedi a Dashboard

  3. Seleziona la dashboard Panoramica di PostgresQL Prometheus.

    Per rivedere in che modo le dashboard monitorano le funzioni, puoi riutilizzare le azioni dalla Autenticazione database e applicare richieste di lettura e scrittura al al database, quindi rivedi la visualizzazione delle metriche raccolte in una dashboard.

  4. Connettiti al pod del client:

    kubectl exec -n pg-ns -i -t pg-client -- /bin/sh
    
  5. Inserisci dati casuali:

    psql postgresql://$CLIENTUSERNAME:$CLIENTPASSWORD@gke-pg-cluster-rw.pg-ns/app -c "CREATE TABLE test (id serial PRIMARY KEY, randomdata VARCHAR ( 50 ) NOT NULL);INSERT INTO test (randomdata) VALUES (generate_series(1, 1000));"
    
  6. Aggiorna la dashboard. I grafici si aggiornano con le metriche attualizzate.

  7. Esci dalla shell del pod:

    exit
    

Esegui la pulizia

Elimina il progetto

    Elimina un progetto Google Cloud:

    gcloud projects delete PROJECT_ID

Elimina singole risorse

  1. Imposta le variabili di ambiente.

    export PROJECT_ID=${PROJECT_ID}
    export KUBERNETES_CLUSTER_PREFIX=postgres
    export REGION=us-central1
    
  2. Esegui il comando terraform destroy:

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

    Sostituisci FOLDER con gke-autopilot o gke-standard.

    Quando richiesto, digita yes.

  3. Trova tutti i dischi scollegati:

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

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

Passaggi successivi

  • Esplora le architetture di riferimento, i diagrammi e le best practice su Google Cloud. Dai un'occhiata al nostro Centro architetture cloud.