Fiches réflexes¶
Voici quelques fiches réflexes sur différents éléments en lien avec une
instance PostgreSQL déployée via CloudNativePG. On suppose que la configuration
d’accès au cluster a été faite pour l’utilisateur système utilisé
(~/.kube/config
existant et bien configuré).
Le plugin cnpg
de kubectl
doit être installé (voir
https://cloudnative-pg.io/documentation/current/kubectl-plugin/).
curl -sSfL \
https://github.com/cloudnative-pg/cloudnative-pg/raw/main/hack/install-cnpg-plugin.sh | \
sudo sh -s -- -b /usr/local/bin
Opérateur et ressources associées¶
Installation Helm¶
Pour tous les namespaces
du cluster Kubernetes :
helm repo add cnpg https://cloudnative-pg.github.io/charts
helm upgrade --install cnpg \
--namespace cnpg-system \
--create-namespace \
cnpg/cloudnative-pg
Pour un namespace
en particulier :
helm upgrade --install cnpg \
--namespace cnpg-system \
--create-namespace \
--set config.clusterWide=false \
cnpg/cloudnative-pg
!!! Seule la dernière release de l’opérateur peut être installée avec cette méthode.”
Installation en appliquant les fichiers YAML¶
Exemple pour la version 1.25.1 de l’opérateur :
kubectl apply --server-side -f \
https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.25/releases/cnpg-1.25.1.yaml
Création d’un cluster PostgreSQL avec deux nœuds asynchrones¶
L’opérateur doit être installé.
cat <<EOF | kubectl apply -f -
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cluster-postgresql
spec:
imageName: ghcr.io/cloudnative-pg/postgresql:17.0
instances: 2
storage:
size: 1Gi
EOF
Il est également possible de créer un fichier ~/cluster.yaml
avec le même
contenu et d’appeler la commande kubectl apply -f ~/cluster.yaml
.
Le cluster aura un primaire et un secondaire configuré automatiquement en streaming réplication. Si le cluster Kubernetes a plusieurs nœuds, les instances seront réparties sur ceux-ci.
Configuration d’une réplication synchrone¶
Qui se base sur la méthode quorum
. Voir la documentation pour l’autre méthode
(priority
) et les détails https://cloudnative-pg.io/documentation/current/replication/#synchronous-replication
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cluster-postgresql
spec:
imageName: ghcr.io/cloudnative-pg/postgresql:17.0
instances: 2
storage:
size: 1Gi
postgresql:
synchronous:
method: any
number: 1
Exploitation au quotidien¶
Connaître le statut d’un cluster PostgreSQL¶
kubectl cnpg status CLUSTER
Exemple :
kubectl cnpg status prod
Cluster Summary
Name: prod
Namespace: default
System ID: 7442376103040843801
PostgreSQL Image: ghcr.io/cloudnative-pg/postgresql:17.0
Primary instance: prod-1
Primary start time: 2024-11-28 17:00:23 +0000 UTC (uptime 141h6m10s)
Status: Cluster in healthy state
Instances: 2
Ready instances: 2
Current Write LSN: 0/5000060 (Timeline: 1 - WAL File: 000000010000000000000005)
Certificates Status
Certificate Name Expiration Date Days Left Until Expiration
---------------- --------------- --------------------------
prod-ca 2025-02-26 16:55:16 +0000 UTC 84.12
prod-replication 2025-02-26 16:55:16 +0000 UTC 84.12
prod-server 2025-02-26 16:55:16 +0000 UTC 84.12
Continuous Backup status
Not configured
Physical backups
No running physical backups found
Streaming Replication status
Replication Slots Enabled
Name Sent LSN Write LSN Flush LSN Replay LSN Write Lag Flush Lag Replay Lag State Sync State Sync Priority Replication Slot
---- -------- --------- --------- ---------- --------- --------- ---------- ----- ---------- ------------- ----------------
prod-2 0/5000060 0/5000060 0/5000060 0/5000060 00:00:00 00:00:00 00:00:00 streaming async 0 active
Unmanaged Replication Slot Status
No unmanaged replication slots found
Managed roles status
No roles managed
Tablespaces status
No managed tablespaces
Instances status
Name Database Size Current LSN Replication role Status QoS Manager Version Node
---- ------------- ----------- ---------------- ------ --- --------------- ----
prod-1 0/5000060 Primary OK BestEffort 1.24.1 minikube
prod-2 0/5000060 Standby (async) OK BestEffort 1.24.1 minikube
Redémarrer un cluster PostgreSQL¶
kubectl cnpg restart CLUSTER
Toutes les instances seront redémarrées en commençant par les secondaires.
Exemple :
Recharger la configuration d’un cluster PostgreSQL¶
kubectl cnpg restart CLUSTER
Toutes les instances seront rechargées en commençant par les secondaires.
Exemple :
Promouvoir une instance en tant que nouveau primaire¶
kubectl cnpg promote CLUSTER INSTANCE
Exemple :
{"level":"info","ts":"2024-12-04T15:40:31.248067731+01:00","msg":"Cluster is not healthy"}
Node prod-2 in cluster prod will be promoted
Un message d’erreur apparaît si l’instance indiquée est déjà primaire.
Détruire une instance d’un cluster PostgreSQL¶
Le PersistentVolumeClaim
associé sera également supprimé.
kubectl cnpg destroy CLUSTER INSTANCE
Exemple :
Cette commande ne modifie pas la définition du cluster PostgreSQL. Une nouvelle instance sera donc déployée automatiquement pour respecter la définition du cluster PostgreSQL.
Créer un certificat pour un client¶
kubectl cnpg certificate SECRET --cnpg-cluster CLUSTER --cnpg-user USER
Exemple :
Un certificat est créé pour l’utilisateur en question. Il est stocké dans un
Secret
:
kubectl get secret SECRET -o json
Exemple :
{
"apiVersion": "v1",
"data": {
"tls.crt": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJoVENDQVNxZ0F3SUJBZ0lRSlhLR092QkJSQnlpQlZDUlhReGd1ekFLQmdncWhrak9QUVFEQWpBaE1SQXcKRGdZRFZRUUxFd2RrWldaaGRXeDBNUTB3Q3dZRFZRUURFd1J3Y205a01CNFhEVEkwTVRJd05ERTBNVFkwTkZvWApEVEkxTURNd05ERTBNVFkwTkZvd0R6RU5NQXNHQTFVRUF4TUVkWE5sY2pCWk1CTUdCeXFHU000OUFnRUdDQ3FHClNNNDlBd0VIQTBJQUJNbEFrdkR3Ui8rOTZLU0ZXekVTVnFCS1JEVlYwMXdhNXpnSnNkdmxldm4rV2pVTHpIbmkKbHFoVm1TSXRyTkxKSUt1enJzT1FuZlFWaDZNSFpJVUkrZUtqVmpCVU1BNEdBMVVkRHdFQi93UUVBd0lEaURBVApCZ05WSFNVRUREQUtCZ2dyQmdFRkJRY0RBakFNQmdOVkhSTUJBZjhFQWpBQU1COEdBMVVkSXdRWU1CYUFGSlhjCmZFeWpKblRRYXpGV01sOTFBenlycjhqTE1Bb0dDQ3FHU000OUJBTUNBMGtBTUVZQ0lRQ1ZGNTMwQTNpeVBMN3MKVnNpekttditDRUt5R3BWMnFEWllRcVV4MlNhaXVRSWhBSS95L1BDOFNmSEQ3TzZLWEZ1Mm1yTjl6T2h3SVBzUgpJY1E1UUQ3amFIajQKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=",
"tls.key": "LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUUvMUxOaFF5RWxBUVdmVy9hRDRKdGU3ZHlacUVPUXNxVzVWbitmcmIzOXZvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFeVVDUzhQQkgvNzNvcElWYk1SSldvRXBFTlZYVFhCcm5PQW14MitWNitmNWFOUXZNZWVLVwpxRldaSWkyczBza2dxN091dzVDZDlCV0hvd2RraFFqNTRnPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo="
},
"kind": "Secret",
"metadata": {
"creationTimestamp": "2024-12-04T14:21:44Z",
"name": "cert-user",
"namespace": "default",
"resourceVersion": "189277",
"uid": "9c39f608-9d2b-4a6b-8835-a1cbf7009af1"
},
"type": "kubernetes.io/tls"
}
Générer un rapport sur un cluster PostgreSQL¶
kubectl cnpg report cluster CLUSTER
Exemple :
unzip report_cluster_prod_2024-12-04T14:07:00Z.zip
unzip report_cluster_prod_2024-12-04T14:07:00Z.zip
Archive: report_cluster_prod_2024-12-04T14:07:00Z.zip
creating: report_cluster_prod_2024-12-04T14:07:00Z/
creating: report_cluster_prod_2024-12-04T14:07:00Z/manifests/
inflating: report_cluster_prod_2024-12-04T14:07:00Z/manifests/cluster.yaml
inflating: report_cluster_prod_2024-12-04T14:07:00Z/manifests/cluster-pods.yaml
inflating: report_cluster_prod_2024-12-04T14:07:00Z/manifests/cluster-jobs.yaml
inflating: report_cluster_prod_2024-12-04T14:07:00Z/manifests/events.yaml
inflating: report_cluster_prod_2024-12-04T14:07:00Z/manifests/cluster-pvcs.yaml
Récupérer les traces du primaire en temps réel¶
kubectl cnpg logs cluster CLUSTER
Exemple :
{"level":"info","ts":"2024-11-28T17:00:22.461940521Z","msg":"Starting CloudNativePG Instance Manager","logger":"instance-manager","logging_pod":"prod-1","version":"1.24.1","build":{"Version":"1.24.1","Commit":"3f96930d","Date":"2024-10-16"}}
Se connecter à une instance avec kubectl¶
kubectl cnpg psql CLUSTER
Exemple :
Il est également possible de se connecter sans utiliser le plugin cnpg
de
kubectl
.
kubectl exec -it POD -- psql
Demander l’exécution d’une sauvegarde¶
Pré-requis : la définition de l’emplacement de sauvegarde doit être faite dans
la définition de la ressource Cluster
.
kubectl cnpg backup CLUSTER
Exemple :
Fencing¶
Le fencing permet d’arrêter le service postmaster
sans pour autant arrêter
le Pod
. Cela permet de faire un arrêt propre de l’instance pour, par exemple ,
du débogage.
Pour passer toutes les instances en mode “fencing”, vous pouvez utiliser *:
kubectl cnpg fencing on
“*”
Et pour passer toutes une instance particulière en mode “fencing” il faut indiquer le numéro de l’instance :
kubectl cnpg fencing on
Pour revenir à la normale, il suffit de repasser la commande kubectl cnpg fencing
avec l’option off
cette fois-ci.
Hibernation¶
Il est possible d’arrêter complètement un cluster PostgreSQL tout en gardant les
données. Autrement dit, toutes les ressources liées à ce cluster sont supprimées
sauf les PV
/PVC
.
kubectl cnpg hibernate on
Exemple :
kubectl cnpg hibernate on cluster-postgresql
hibernation process starting...
waiting for the cluster to be fenced
cluster is now fenced, storing primary pg_controldata output
primary pg_controldata output fetched
annotating the PVC with the cluster manifest
PVC annotation complete
destroying the primary instance while preserving the pvc
Instance cluster-postgresql-1 of cluster cluster-postgresql has been destroyed and the PVC was kept
primary instance destroy completed
deleting the cluster resource
cluster resource deletion complete
Hibernation completed
Le PVC
est bien conservé.
kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
cluster-postgresql-1 Bound pvc-2c5910e5-cebc-40bd-a023-174d5c9e08c4 1Gi RWO standard <unset> 8m4s
Il n’y a plus de Pod
lié au cluster PostgreSQL.
Pour sortir un cluster du mode hibernation, il suffit d’utiliser off
cette
fois-ci.
kubectl cnpg hibernate off
Exemple :
Sauvegarde¶
Un stockage S3 doit être accessible.
Une clé API doit être créée.
Création du Secret
¶
Récupérer les valeurs de ACCESS_KEY_ID
, ACCESS_SECRET_KEY
et
ACCESS_REGION
de la clé API et de votre stockage S3.
Créer le Secret
compte-s3
.
kubectl create secret generic compte-s3 --from-literal=ACCESS_KEY_ID=xxxxxxxxxxxxxx --from-literal=ACCESS_SECRET_KEY=xxxxxxxxxxxxxx --from-literal=ACCESS_REGION=xxxxxxxxxxxxxx
Configuration du cluster PostgreSQL¶
Ajouter la section backup
à votre objet Cluster
. Les informations du
Secret
précédent sont utilisées dans la partie s3Credentials
.
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cluster-postgresql
spec:
imageName: ghcr.io/cloudnative-pg/postgresql:17.0
instances: 2
storage:
size: 1Gi
backup:
retentionPolicy: "30d"
barmanObjectStore:
destinationPath: "s3://bucket/folder/"
endpointURL: "https://endpoint"
s3Credentials:
accessKeyId:
name: compte-s3
key: ACCESS_KEY_ID
secretAccessKey:
name: compte-s3
key: ACCESS_SECRET_KEY
region:
name: compte-s3
key: ACCESS_REGION
wal:
compression: gzip
data:
compression: gzip
La durée de rétention peut être gérée par le paramètre retentionPolicy
(par
défaut à 60 jours).
Les données et les journaux de transaction peuvent être compressés (paramètre
compression
).
Faire une sauvegarde¶
Avec le plugin cnpg
de kubectl
:
Ou avec un fichier yaml
qui fait référence au cluster à sauvegarder.
apiVersion: postgresql.cnpg.io/v1
kind: Backup
metadata:
name: backup
spec:
cluster:
name: cluster-postgresql
Kubernetes¶
Connaître les ressources allouées à un Pod¶
kubectl get pod <pod> -o jsonpath='{range .spec.containers[*]}{"Container Name: "}{.name}{"\n"}{"Requests:"}{.resources.requests}{"\n"}{"Limits:"}{.resources.limits}{"\n"}{end}'
Container Name: manager
Requests:{"cpu":"100m","memory":"100Mi"}
Limits:{"cpu":"100m","memory":"200Mi"}
Si le Pod appartient à un namespace particulier, utiliser l’option -n :
kubectl get pod <pod> -n <namespace> -o jsonpath='{range .spec.containers[*]}{"Container Name: "}{.name}{"\n"}{"Requests:"}{.resources.requests}{"\n"}{"Limits:"}{.resources.limits}{"\n"}{end}'
Connaître les ressources utilisées par un Pod¶
L’API Metrics doit être activée sur le cluster (souvent le cas).
Dans le cas contraire, un message d’erreur apparaitra error: Metrics API not available
.
kubectl top pods
Les informations de consommation CPU (millicpu) et mémoire (Mi) des pods actifs apparaissent.
Connaître les ressources utilisées sur un Node¶
L’API Metrics doit être activée sur le cluster (souvent le cas).
Dans le cas contraire, un message d’erreur apparaîtra error: Metrics API not available
.
kubectl top nodes
La consommation CPU (millicpu) et mémoire (Mi) du nœud apparait.
Collecter les informations relatives au système¶
Le détail des spécifications d’un cluster peut être dumpé depuis Kubernetes :
kubectl cluster-info dump
La sortie est très verbeuse et contient les informations relatives au cluster.