Ce guide vous explique comment déployer des clusters PostgreSQL sur Google Kubernetes Engine (GKE) à l'aide de l'opérateur CloudNativePG.
PostgreSQL est une base de données Open Source de type objet-relationnel avec plusieurs décennies de développement actif, garantissant la stabilité des performances du client. Elle offre un large éventail de fonctionnalités, y compris la réplication, la récupération à un moment précis, ainsi que des fonctionnalités de sécurité et d'extension. PostgreSQL est compatible avec les principaux systèmes d'exploitation et répond parfaitement aux normes ACID (atomicité, cohérence, isolation, durabilité).
Ce guide est destiné aux administrateurs de plate-forme, aux architectes cloud et aux professionnels des opérations qui souhaitent déployer des clusters Postgres sur GKE. L'exécution de Postgres dans GKE au lieu d'utiliser Cloud SQL peut offrir plus de flexibilité et de contrôle de configuration aux administrateurs de base de données expérimentés.
Avantages
CloudNativePG est un opérateur Open Source développé par EDB sous une licence Apache 2. Il apporte les fonctionnalités suivantes au déploiement de PostgreSQL :
- Moyen déclaratif et Kubernetes natif de gérer et de configurer les clusters PostgreSQL
- Gestion des sauvegardes à l'aide d'instantanés de volume ou de Cloud Storage
- Connexion TLS chiffrée en transit, possibilité d'utiliser votre propre autorité de certification et votre intégration au gestionnaire de certificats pour l'émission et la rotation automatisées des certificats TLS
- Mises à jour progressives pour les versions mineures de PostgreSQL
- Utilisation du serveur d'API Kubernetes pour gérer l'état d'un cluster PostgreSQL et les basculements pour une haute disponibilité, sans avoir besoin d'outils supplémentaires
- Une configuration d'exportateur Prometheus intégrée via des métriques définies par l'utilisateur écrites en SQL
Objectifs
- Planifier et déployer l'infrastructure GKE pour Postgres
- Déployer et configurer l'opérateur CloudNativePG Postgres avec Helm
- Déployer un cluster PostgreSQL
- Configurer l'authentification et l'observabilité PostgreSQL
Architecture de déploiement
PostgreSQL offre différentes options de déploiement, allant d'un serveur de base de données autonome à un cluster répliqué à disponibilité élevée. Ce tutoriel porte sur le déploiement d'un cluster à disponibilité élevée sur GKE.
Dans ce déploiement, les charges de travail du cluster PostgreSQL sont réparties sur plusieurs zones de disponibilité au sein du cluster GKE régional, assurant ainsi une haute disponibilité et une redondance. Pour en savoir plus, consultez la page clusters régionaux.
Le schéma suivant montre un cluster Postgres s'exécutant sur plusieurs nœuds et zones dans un cluster GKE :
La configuration par défaut comprend un serveur PostgreSQL principal et deux serveurs de sauvegarde prêts à prendre le relais en cas de défaillance du serveur principal, garantissant ainsi la disponibilité continue de la base de données.
Les ressources de l'opérateur CloudNativePG utilisent un espace de noms distinct du cluster GKE pour une meilleure isolation des ressources, ainsi que l'approche de microservices recommandée consistant en une base de données par cluster PostgreSQL. La base de données et l'utilisateur correspondant (utilisateur de l'application) sont définis dans la ressource personnalisée Kubernetes représentant le cluster.
La question du stockage est cruciale lorsque l'on parle de bases de données. Le stockage doit être efficace, assurer une disponibilité continue et garantir la cohérence des données. Pour ces raisons, nous vous recommandons la classe de stockage
premium-rwo
, qui est basée sur des disques SSD. L'opérateur CloudNativePG crée automatiquementPersistentVolumeClaims
si nécessaire lors de la configuration des pods pour le cluster PostgreSQL.
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.
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
Les logiciels dont vous avez besoin pour ce tutoriel sont préinstallés sur Cloud Shell, y compris kubectl
, gcloud CLI, Helm et Terraform. Si vous n'utilisez pas Cloud Shell, vous devez installer gcloud CLI.
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
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.
-
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Compute Engine, IAM, GKE, Resource Manager APIs:
gcloud services enable compute.googleapis.com
iam.googleapis.com container.googleapis.com cloudresourcemanager.googleapis.com - Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
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.
-
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Compute Engine, IAM, GKE, Resource Manager APIs:
gcloud services enable compute.googleapis.com
iam.googleapis.com container.googleapis.com cloudresourcemanager.googleapis.com -
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: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.
- Replace
Configurer votre environnement
Pour configurer votre environnement, procédez comme suit :
Définissez les variables d'environnement :
export PROJECT_ID=PROJECT_ID export KUBERNETES_CLUSTER_PREFIX=postgres export REGION=us-central1
Remplacez
PROJECT_ID
par l'ID de votre projet Google Cloud.Clonez le dépôt GitHub.
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
Accédez au répertoire de travail :
cd kubernetes-engine-samples/databases/postgresql-cloudnativepg
Créer l'infrastructure de votre cluster
Dans cette section, vous allez exécuter un script Terraform pour créer un cluster GKE régional, privé et à disponibilité élevée.
Vous pouvez installer l'opérateur à l'aide d'un cluster Standard ou Autopilot.
Standard
Le schéma suivant présente un cluster GKE standard régional privé déployé sur trois zones différentes :
Pour déployer cette infrastructure, exécutez les commandes suivantes :
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}
Lorsque vous y êtes invité, saisissez yes
. L'exécution de cette commande et le passage du cluster à l'état prêt peuvent prendre plusieurs minutes.
Terraform crée les ressources suivantes :
- Un réseau VPC et un sous-réseau privé pour les nœuds Kubernetes.
- Un routeur pour accéder à Internet via NAT.
- Un cluster GKE privé dans la région
us-central1
. - Un pool de nœuds avec autoscaling activé (un à deux nœuds par zone, un nœud par zone au minimum).
Le résultat ressemble à ce qui suit :
...
Apply complete! Resources: 14 added, 0 changed, 0 destroyed.
...
Autopilot
Le schéma suivant présente un cluster GKE Autopilot régional privé :
Pour déployer l'infrastructure, exécutez les commandes suivantes :
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}
Lorsque vous y êtes invité, saisissez yes
. L'exécution de cette commande et le passage du cluster à l'état prêt peuvent prendre plusieurs minutes.
Terraform crée les ressources suivantes :
- Un réseau VPC et un sous-réseau privé pour les nœuds Kubernetes.
- Un routeur pour accéder à Internet via NAT.
- Un cluster GKE privé dans la région
us-central1
. - Un objet
ServiceAccount
avec une autorisation de journalisation et de surveillance. - Google Cloud Managed Service pour Prometheus pour la surveillance du cluster.
Le résultat ressemble à ce qui suit :
...
Apply complete! Resources: 12 added, 0 changed, 0 destroyed.
...
Se connecter au cluster
Configurez kubectl
pour communiquer avec le cluster :
gcloud container clusters get-credentials ${KUBERNETES_CLUSTER_PREFIX}-cluster --region ${REGION}
Déployer l'opérateur CloudNativePG
Déployez CloudNativePG sur votre cluster Kubernetes à l'aide d'un chart Helm :
Ajoutez le dépôt du chart Helm de l'opérateur CloudNativePG :
helm repo add cnpg https://cloudnative-pg.github.io/charts
Déployez l'opérateur CloudNativePG à l'aide de l'outil de ligne de commande Helm :
helm upgrade --install cnpg \ --namespace cnpg-system \ --create-namespace \ cnpg/cloudnative-pg
Le résultat ressemble à ce qui suit :
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 ...
Déployer Postgres
Le fichier manifeste suivant décrit un cluster PostgreSQL tel que défini par la ressource personnalisée de l'opérateur CloudNativePG :
Ce fichier manifeste contient les champs suivants :
spec.instances
: nombre de pods du cluster.spec.primaryUpdateStrategy
: stratégie de mise à jour progressive :Unsupervised
: met à jour de manière autonome le nœud de cluster principal après les nœuds réplicas.Supervised
: le basculement manuel est requis pour le nœud de cluster principal.
spec.postgresql
: remplacements de paramètres du fichierpostgres.conf
, tels que les règles pg-hba, LDAP et les exigences pour la synchronisation des instances dupliquées.spec.storage
: paramètres liés au stockage, tels que la classe de stockage, la taille du volume et les paramètres des journaux WAL (Write-Ahead Logging).spec.bootstrap
: paramètres de la base de données initiale créée dans le cluster, identifiants utilisateur et options de restauration de la base de données.spec.resources
: requêtes et limites pour les pods de clusterspec.affinity
: règles d'affinité et d'anti-affinité des charges de travail du cluster.
Créer un cluster Postgres de base
Créez un espace de noms :
kubectl create ns pg-ns
Créez le cluster PostgreSQL à l'aide de la ressource personnalisée :
kubectl apply -n pg-ns -f manifests/01-basic-cluster/postgreSQL_cluster.yaml
Cette commande peut prendre plusieurs minutes.
Vérifiez l'état du cluster :
kubectl get cluster -n pg-ns --watch
Attendez que le résultat affiche l'état
Cluster in healthy state
avant de passer à l'étape suivante.NAME AGE INSTANCES READY STATUS PRIMARY gke-pg-cluster 2m53s 3 3 Cluster in healthy state gke-pg-cluster-1
Inspecter les ressources
Vérifiez que GKE a créé les ressources pour le cluster:
kubectl get cluster,pod,svc,pvc,pdb,secret,cm -n pg-ns
Le résultat ressemble à ce qui suit :
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'opérateur crée les ressources suivantes :
- Une ressource personnalisée de cluster représentant le cluster PostgreSQL contrôlé par l'opérateur
- Ressources PersistentVolumeClaim avec les volumes persistants correspondants
- Des secrets avec des identifiants utilisateur pour accéder à la base de données et effectuer la réplication entre les nœuds Postgres.
- Trois services de point de terminaison de base de données :
<name>-rw
,<name>-ro
et<name>-r
pour se connecter au cluster. Pour en savoir plus, consultez la section Architecture PostgreSQL.
S'authentifier auprès de Postgres
Vous pouvez vous connecter à la base de données PostgreSQL et vérifier l'accès via différents points de terminaison de service créés par l'opérateur. Pour ce faire, vous utilisez un pod supplémentaire avec un client PostgreSQL et les identifiants de l'utilisateur de l'application synchronisé installés en tant que variables d'environnement.
Exécutez le pod client pour interagir avec votre cluster Postgres :
kubectl apply -n pg-ns -f manifests/02-auth/pg-client.yaml
Exécutez une commande
exec
sur le podpg-client
et connectez-vous au servicegke-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
Connectez-vous à la base de données à l'aide du service
gke-pg-cluster-rw
pour établir une connexion avec des droits de lecture/écriture :psql postgresql://$CLIENTUSERNAME:$CLIENTPASSWORD@gke-pg-cluster-rw.pg-ns/app
Le terminal commence par le nom de votre base de données :
app=>
Créez une table :
CREATE TABLE travel_agency_clients ( client VARCHAR ( 50 ) UNIQUE NOT NULL, address VARCHAR ( 50 ) UNIQUE NOT NULL, phone VARCHAR ( 50 ) UNIQUE NOT NULL);
Insérez des données dans la table.
INSERT INTO travel_agency_clients(client, address, phone) VALUES ('Tom', 'Warsaw', '+55555') RETURNING *;
Affichez les données que vous avez créées :
SELECT * FROM travel_agency_clients ;
Le résultat ressemble à ce qui suit :
client | address | phone --------+---------+--------- Tom | Warsaw | +55555 (1 row)
Déconnectez-vous de la session de base de données en cours:
exit
Connectez-vous à la base de données à l'aide du service
gke-pg-cluster-ro
pour vérifier l'accès en lecture seule. Ce service permet d'interroger des données, mais limite les opérations d'écriture :psql postgresql://$CLIENTUSERNAME:$CLIENTPASSWORD@gke-pg-cluster-ro.pg-ns/app
Essayez d'insérer de nouvelles données :
INSERT INTO travel_agency_clients(client, address, phone) VALUES ('John', 'Paris', '+55555') RETURNING *;
Le résultat ressemble à ce qui suit :
ERROR: cannot execute INSERT in a read-only transaction
Tentative de lecture des données:
SELECT * FROM travel_agency_clients ;
Le résultat ressemble à ce qui suit :
client | address | phone --------+---------+--------- Tom | Warsaw | +55555 (1 row)
Déconnectez-vous de la session de base de données en cours:
exit
Quittez le shell du pod :
exit
Comprendre comment Prometheus collecte les métriques pour votre cluster Postgres
Le schéma suivant illustre le fonctionnement de la collecte de métriques Prometheus :
Dans le schéma, un cluster privé GKE contient :
- Un pod Postgres qui collecte des métriques sur le chemin
/
et le port9187
- Collecteurs basés sur Prometheus qui traitent les métriques à partir du pod Postgres
- Une ressource
PodMonitoring
qui envoie des métriques à Cloud Monitoring
Pour activer la collecte de métriques à partir de vos pods, procédez comme suit :
Créez la ressource
PodMonitoring
:kubectl apply -f manifests/03-observability/pod-monitoring.yaml -n pg-ns
Dans la console Google Cloud, accédez à la page Explorateur de métriques :
Accéder à l'explorateur de métriques
Le tableau de bord affiche un taux d'ingestion de métriques différent de zéro.
Dans Sélectionner une métrique, saisissez Cible Prometheus.
Dans la section Catégories de métriques actives, sélectionnez Cnpg.
Créer un tableau de bord des métriques
Pour visualiser les métriques exportées, créez un tableau de bord des métriques.
Déployez un tableau de bord :
gcloud --project "${PROJECT_ID}" monitoring dashboards create --config-from-file manifests/03-observability/gcp-pg.json
Dans la console Google Cloud, accédez à la page Tableaux de bord.
Sélectionnez le tableau de bord Présentation de PostgresQL-Prometheus.
Pour examiner les fonctions de surveillance des tableaux de bord, vous pouvez réutiliser les actions de la section Authentification de la base de données, appliquer des requêtes de lecture et d'écriture à la base de données, puis examiner la visualisation des métriques collectées dans un tableau de bord.
Connectez-vous au pod client :
kubectl exec -n pg-ns -i -t pg-client -- /bin/sh
Insérer des données aléatoires :
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));"
Actualisez le tableau de bord. Les graphiques sont mis à jour avec les métriques actualisées.
Quittez le shell du pod :
exit
Effectuer un nettoyage
Supprimer le projet
Delete a Google Cloud project:
gcloud projects delete PROJECT_ID
Supprimer des ressources individuelles
Définissez les variables d'environnement.
export PROJECT_ID=${PROJECT_ID} export KUBERNETES_CLUSTER_PREFIX=postgres export REGION=us-central1
Exécutez la commande
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}
Remplacez
FOLDER
pargke-autopilot
ougke-standard
.Lorsque vous y êtes invité, saisissez
yes
.Recherchez tous les disques non associés :
export disk_list=$(gcloud compute disks list --filter="-users:* AND labels.name=${KUBERNETES_CLUSTER_PREFIX}-cluster" --format "value[separator=|](name,zone)")
Supprimez les disques :
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
Étapes suivantes
- Découvrez des architectures de référence, des schémas et des bonnes pratiques concernant Google Cloud. Consultez notre Centre d'architecture cloud.