La guida mostra come eseguire il deployment dei cluster PostgreSQL su Google Kubernetes Engine (GKE) utilizzando l'operatore CloudNativePG.
PostgreSQL è un database relazionale open source relazionale a oggetti con diversi decenni di sviluppo attivo, che garantisce prestazioni stabili del client. Offre una gamma di funzionalità, tra cui replica, recupero point-in-time, funzionalità di sicurezza ed estendebilità. PostgreSQL è compatibile con i principali sistemi operativi ed è pienamente conforme agli standard ACID (Atomicità, Coerenza, Isolamento, Durabilità).
Questa guida è rivolta agli amministratori di piattaforma, ai Cloud Architect e ai professionisti operativi interessati al deployment di cluster Postgres su GKE. L'esecuzione di Postgres in GKE anziché utilizzare Cloud SQL può offrire maggiore flessibilità e controllo della configurazione ad amministratori di database esperti.
Vantaggi
Cloud NativePG è un operatore open source sviluppato da EBD con licenza Apache 2. Offre le seguenti funzionalità al deployment di PostgreSQL:
- un modo dichiarativo e nativo di Kubernetes per gestire e configurare cluster PostgreSQL
- Gestione dei backup mediante snapshot di volumi o Cloud Storage
- Connessione TLS criptata in transito, la possibilità di utilizzare la tua autorità di certificazione e l'integrazione con Gestore certificati per l'emissione e la rotazione automatizzate dei certificati TLS.
- Aggiornamenti in sequenza per release di PostgreSQL minori
- Uso del server API Kubernetes per mantenere lo stato di un cluster PostgreSQL e failover per l'alta disponibilità senza bisogno di strumenti aggiuntivi
- Una configurazione di esportazione Prometheus integrata 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 di Cloud NativePG con Helm
- Esegui il deployment di un cluster PostgreSQL
- Configura l'autenticazione e l'osservabilità di PostgreSQL
Architettura di deployment
PostgreSQL offre varie opzioni di deployment, da un server di database autonomo a un cluster replicato ad alta disponibilità. Questo tutorial è incentrato sul deployment del cluster ad alta disponibilità in 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, garantendo disponibilità elevata e ridondanza. Per maggiori informazioni, consulta la pagina relativa ai cluster a livello di regione.
Il seguente diagramma mostra un cluster Postgres in esecuzione su più nodi e zone in un cluster GKE:
La configurazione predefinita include un server PostgreSQL principale e due server di backup pronti a prendere il controllo in caso di errore del server principale, garantendo una disponibilità continua del database.
Le risorse dell'operatore Cloud NativePG utilizzano uno spazio dei nomi separato del cluster GKE per migliorare l'isolamento delle risorse e l'approccio consigliato per i microservizi di un solo database per cluster PostgreSQL. Il database e l'utente corrispondente (utente dell'app) sono definiti nella risorsa personalizzata Kubernetes che rappresenta il cluster.
L'archiviazione è un componente fondamentale quando si parla di database. L'archiviazione deve funzionare in modo efficiente, garantire una disponibilità continua e garantire la coerenza dei dati. Per questi motivi, consigliamo la classe di archiviazione
premium-rwo
, che si basa sui dischi SSD. L'operatore Cloud NativePG crea automaticamentePersistentVolumeClaims
in base alle esigenze durante la configurazione dei pod per il cluster PostgreSQL.
Costi
In questo documento vengono utilizzati i seguenti componenti fatturabili di Google Cloud:
Per generare una stima dei costi in base all'utilizzo previsto,
utilizza il Calcolatore prezzi.
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 per questo tutorial, tra cui kubectl
, gcloud CLI, Helm e Terraform. Se non usi Cloud Shell, devi installare gcloud CLI.
- 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.
- Installa Google Cloud CLI.
-
Per initialize gcloud CLI, esegui questo comando:
gcloud init
-
Crea o seleziona un progetto Google Cloud.
-
Crea un progetto Google Cloud:
gcloud projects create PROJECT_ID
Sostituisci
PROJECT_ID
con un nome per il progetto Google Cloud che stai creando. -
Seleziona il progetto Google Cloud che hai creato:
gcloud config set project PROJECT_ID
Sostituisci
PROJECT_ID
con il nome del tuo progetto Google Cloud.
-
-
Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.
-
Abilita le API Compute Engine, IAM, GKE, Resource Manager.
gcloud services enable compute.googleapis.com
iam.googleapis.com container.googleapis.com cloudresourcemanager.googleapis.com - Installa Google Cloud CLI.
-
Per initialize gcloud CLI, esegui questo comando:
gcloud init
-
Crea o seleziona un progetto Google Cloud.
-
Crea un progetto Google Cloud:
gcloud projects create PROJECT_ID
Sostituisci
PROJECT_ID
con un nome per il progetto Google Cloud che stai creando. -
Seleziona il progetto Google Cloud che hai creato:
gcloud config set project PROJECT_ID
Sostituisci
PROJECT_ID
con il nome del tuo progetto Google Cloud.
-
-
Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.
-
Abilita le API Compute Engine, IAM, GKE, Resource Manager.
gcloud services enable compute.googleapis.com
iam.googleapis.com container.googleapis.com cloudresourcemanager.googleapis.com -
Concedi i ruoli al tuo Account Google. Esegui questo comando una volta per ciascuno dei seguenti ruoli IAM:
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:EMAIL_ADDRESS" --role=ROLE
- Sostituisci
PROJECT_ID
con l'ID progetto. - Sostituisci
EMAIL_ADDRESS
con il tuo indirizzo email. - Sostituisci
ROLE
con ogni singolo ruolo.
- Sostituisci
Configura l'ambiente
Per configurare l'ambiente:
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 ID progetto Google Cloud.Clona il repository GitHub:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
Passa alla directory di lavoro:
cd kubernetes-engine-samples/databases/postgresql-cloudnativepg
Crea l'infrastruttura del cluster
In questa sezione, eseguirai uno script Terraform per creare un cluster GKE privato a livello di regione e ad alta disponibilità.
Puoi installare l'operatore utilizzando un cluster Standard o Autopilot.
Standard
Il seguente diagramma mostra un cluster GKE Standard regionale privato di cui è stato eseguito il deployment 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
. Il completamento di questo comando potrebbe richiedere diversi minuti
e il cluster mostri lo stato Pronto.
Terraform crea le risorse seguenti:
- 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
- Pool di nodi con scalabilità automatica abilitata (da uno a due nodi per zona, uno minimo per zona)
L'output è simile al seguente:
...
Apply complete! Resources: 14 added, 0 changed, 0 destroyed.
...
Autopilot
Il seguente diagramma mostra un cluster GKE Autopilot a livello di regione privato:
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
. Il completamento di questo comando potrebbe richiedere diversi minuti
e il cluster mostri lo stato Pronto.
Terraform crea le risorse seguenti:
- 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 del 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:
Aggiungi il repository dei grafici Helm per l'operatore Cloud NativePG:
helm repo add cnpg https://cloudnative-pg.github.io/charts
Esegui il deployment dell'operatore Cloud NativePG utilizzando lo strumento a riga di comando di 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 ...
Deployment di Postgres
Il manifest seguente descrive un cluster PostgreSQL come definito dalla risorsa personalizzata dell'operatore Cloud NativePG:
Il file manifest include i seguenti campi:
spec.instances
: il numero di pod del clusterspec.primaryUpdateStrategy
: strategia di aggiornamento in sequenza:Unsupervised
: aggiorna autonomamente il nodo del cluster primario dopo i nodi di replicaSupervised
: il passaggio manuale è obbligatorio per il nodo del cluster primario
spec.postgresql
: gli override dei parametri del filepostgres.conf
, come le regole pg-hba, il protocollo LDAP e i requisiti per il rispetto delle repliche di sincronizzazione.spec.storage
: impostazioni relative allo spazio di archiviazione, come le impostazioni della classe di archiviazione, della dimensione del volume e del log write-ahead.spec.bootstrap
: parametri del database iniziale creato nel cluster, credenziali utente e opzioni di ripristino del databasespec.resources
: richieste e limiti per i pod del clusterspec.affinity
: regole di affinità e anti-affinità dei carichi di lavoro del cluster
Creare un cluster Postgres di base
Crea uno spazio dei nomi:
kubectl create ns pg-ns
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.
Controlla lo stato del cluster:
kubectl get cluster -n pg-ns --watch
Attendi che l'output mostri lo stato
Cluster in healthy state
prima di andare al passaggio successivo.NAME AGE INSTANCES READY STATUS PRIMARY gke-pg-cluster 2m53s 3 3 Cluster in healthy state gke-pg-cluster-1
esamina 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 nodi Postgres.
- Tre servizi di endpoint di database:
<name>-rw
,<name>-ro
e<name>-r
per la connessione al cluster. Per ulteriori informazioni, consulta la pagina dedicata all'architettura di PostgreSQL.
Autenticazione in Postgres
Puoi connetterti al database PostgreSQL e controllare l'accesso tramite diversi endpoint di servizio creati dall'operatore. A questo scopo, utilizza un pod aggiuntivo con un client PostgreSQL e le credenziali utente dell'applicazione sincronizzate montate come variabili di ambiente.
Esegui il pod del client per interagire con il cluster Postgres:
kubectl apply -n pg-ns -f manifests/02-auth/pg-client.yaml
Esegui un comando
exec
sul podpg-client
e accedi al serviziogke-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
Accedi al database utilizzando il servizio
gke-pg-cluster-rw
per stabilire una connessione con privilegi di lettura-scrittura:psql postgresql://$CLIENTUSERNAME:$CLIENTPASSWORD@gke-pg-cluster-rw.pg-ns/app
Il terminale inizia con il nome del tuo database:
app=>
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);
Inserisci i dati nella tabella:
INSERT INTO travel_agency_clients(client, address, phone) VALUES ('Tom', 'Warsaw', '+55555') RETURNING *;
Visualizza i dati che hai creato:
SELECT * FROM travel_agency_clients ;
L'output è simile al seguente:
client | address | phone --------+---------+--------- Tom | Warsaw | +55555 (1 row)
Esci dalla sessione di database corrente:
exit
Accedi al database utilizzando il servizio
gke-pg-cluster-ro
per verificare l'accesso di sola lettura. Questo Servizio consente di eseguire query sui dati, ma limita qualsiasi operazione di scrittura:psql postgresql://$CLIENTUSERNAME:$CLIENTPASSWORD@gke-pg-cluster-ro.pg-ns/app
Tentativo di 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
Tentativo di lettura dei dati:
SELECT * FROM travel_agency_clients ;
L'output è simile al seguente:
client | address | phone --------+---------+--------- Tom | Warsaw | +55555 (1 row)
Esci dalla sessione di database corrente:
exit
Esci dalla shell del pod:
exit
Scopri in che modo Prometheus raccoglie le metriche per il tuo 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 metriche sul percorso
/
e sulla porta9187
- Raccoglitori 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:
Crea la risorsa
PodMonitoring
:kubectl apply -f manifests/03-observability/pod-monitoring.yaml -n pg-ns
Nella console Google Cloud, vai alla pagina Metrics Explorer:
La dashboard mostra una frequenza di importazione di metriche diversa da zero.
In Seleziona una metrica, inserisci Target Prometheus.
Nella sezione Categorie di metriche attive, seleziona Cnpg.
Creare una dashboard delle metriche
Per visualizzare le metriche esportate, crea una dashboard delle metriche.
Esegui il deployment di una dashboard:
gcloud --project "${PROJECT_ID}" monitoring dashboards create --config-from-file manifests/03-observability/gcp-pg.json
Nella console Google Cloud, vai alla pagina Dashboard.
Seleziona la dashboard PostgresQL Prometheus Overview.
Per esaminare il modo in cui le dashboard monitorano le funzioni, puoi riutilizzare le azioni della sezione Autenticazione database, applicare richieste di lettura e scrittura al database, quindi esaminare la visualizzazione delle metriche raccolte in una dashboard.
Connettiti al pod del client:
kubectl exec -n pg-ns -i -t pg-client -- /bin/sh
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));"
Aggiorna la dashboard. I grafici si aggiornano con le metriche attualizzate.
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
Imposta le variabili di ambiente.
export PROJECT_ID=${PROJECT_ID} export KUBERNETES_CLUSTER_PREFIX=postgres export REGION=us-central1
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
congke-autopilot
ogke-standard
.Quando richiesto, digita
yes
.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)")
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. Visita il nostro Cloud Architecture Center.