Lyon, le 3 janvier 2025

CloudNativePG ou comment embarquer un éléphant sur un porte-conteneurs ! Voici le premier article d’une série pour découvrir l’opérateur CloudNativePG, ses fonctionnalités, comprendre comment il vous permet de déployer PostgreSQL mais également voir quels sont les changements à appréhender en embarquant un éléphant sur un porte-conteneurs !

moteur

Au programme de ce premier article : l’installation de l’opérateur et le déploiement d’une instance PostgreSQL avec un secondaire !

Un opérateur ? Quésaco ?

Un opérateur est un outil logiciel qui élargit les fonctionnalités de Kubernetes afin de gérer spécifiquement un type de ressource ou d’application. Plusieurs centaines d’opérateurs existent. Une dizaine existe pour PostgreSQL, et la plupart sont référencés sur operatorhub.io.

Il y en a pour tous les goûts : logging, stockage, networking, big data, … et en l’occurrence, CloudNativePG est un opérateur qui permet de gérer

(petit indice : vous êtes sur le blog de Dalibo)

des instances PostgreSQL 🐘! Incroyable !

Cet opérateur s’est fait connaître au grand jour en 2022, lorsque EnterpriseDB a décidé de libérer le projet.

Logo du projet CloudNativePG

Grâce à lui, il nous est possible de déployer facilement une instance PostgreSQL dans notre cluster Kubernetes. D’ailleurs comment fait-on cela ?

Déployer une instance

Pas si vite ! Avant de déployer une instance, il est nécessaire d’installer l’opérateur CloudNativePG mais il nous faut surtout un cluster Kubernetes. Sentez-vous libres de choisir la distribution et le fournisseur Kubernetes de votre choix. Pour cette série d’articles, j’utiliserai principalement l’outil minikube qui me permet de déployer un cluster Kubernetes en local sur ma machine.

minikube start

Maintenant que j’ai un cluster Kubernetes, je vais pouvoir déployer l’opérateur. Différentes méthodes d’installation existent. Il est possible par exemple de l’installer via helm ou avec kubectl. Je me contenterai de déployer l’opérateur en appliquant les différents fichiers yaml (fournis par le projet CloudNativePG) avec l’outil kubectl. L’idée est de ne pas vous égarer avec l’utilisation de multiples outils (moi-même, je serai capable de me perdre 😅). kubectl, à l’instar de pg_ctl pour PostgreSQL, permet d’interagir avec un cluster Kubernetes.

$ kubectl apply --server-side -f \
  https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.24/releases/cnpg-1.24.1.yaml

Cette commande permet d’installer CloudNativePG en récupérant un fichier yaml disponible sur internet. Ce fichier contient la définition de différentes ressources. Lorsqu’il est appliqué sur le cluster, Kubernetes comprend ce qu’il doit faire, et va notamment :

  1. créer le Deployment cnpg-controller-manager, qui est en charge de déployer une image de CloudNativePG, l’application qui va bichonner nos instances ;
    kubectl get deployment -n cnpg-system
    NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
    cnpg-controller-manager   1/1     1            1           30s
    

    Notre controller est prêt (READY).

  2. créer un ensemble de nouvelles ressources, étendant ainsi l’API de Kubernetes.
    kubectl api-resources --api-group=postgresql.cnpg.io -o name
    backups.postgresql.cnpg.io
    clusterimagecatalogs.postgresql.cnpg.io
    clusters.postgresql.cnpg.io
    databases.postgresql.cnpg.io
    imagecatalogs.postgresql.cnpg.io
    poolers.postgresql.cnpg.io
    publications.postgresql.cnpg.io
    scheduledbackups.postgresql.cnpg.io
    subscriptions.postgresql.cnpg.io
    

Ce sont ces ressources-là qui vont nous intéresser. Elles correspondent à des ressources PostgreSQL comme Cluster ou encore Subscription que nous allons pouvoir créer.

Déployer une instance (cette fois-ci c’est la bonne)

Nous voici avec un cluster Kubernetes dans lequel fonctionne l’opérateur CloudNativePG. Il me semble que nous avons tout ce qu’il nous faut !

Voici un exemple de fichier yaml qui permet de déployer une instance PostgreSQL en version 17.0 :

$ cat ~/cluster.yaml
---
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: postgresql
spec:
  imageName: ghcr.io/cloudnative-pg/postgresql:17.0
  instances: 1
  storage:
    size: 20Gi

Appliquez ce fichier avec kubectl apply -f ~/cluster.yaml et votre instance PostgreSQL sera déployée. Il se passe beaucoup de choses derrière cette phrase. Cela fera certainement l’objet d’un autre article de blog complet, voire deux 😏. Pour le moment, contentons-nous d’apprécier ce qu’il se passe.

$ kubectl apply -f cluster.yaml
cluster.postgresql.cnpg.io/postgresql created

Quelques temps après, votre cluster PostgreSQL est up & running :

kubectl get cluster
NAME         AGE     INSTANCES   READY   STATUS                     PRIMARY
postgresql   4m49s   1           1       Cluster in healthy state   postgresql-1

Déployer une instance secondaire

Une instance primaire est généralement accompagnée par une deuxième instance répliquée grâce au mécanisme interne de PostgreSQL. C’est une architecture très courante dans les projets où est utilisé PostgreSQL.

L’opérateur CloudNativePG vous permet de déployer un secondaire en modifiant uniquement le nombre d’instances que vous souhaitez avoir. Il suffit donc juste de modifier 1 par 2 dans la définition yaml.

[...]
  instances: 2
[...]

À l’application de ce fichier, l’opérateur comprend la modification et va faire le nécessaire pour nous.

kubectl apply -f cluster.yaml 
cluster.postgresql.cnpg.io/postgresql configured

Nous avons alors un cluster PostgreSQL avec deux instances. Par défaut, la seconde instance est configurée pour fonctionner en réplication asynchrone. Le primaire correspond au Pod postgresql-1 comme l’indique la colonne PRIMARY.

kubectl get cluster
NAME         AGE     INSTANCES   READY   STATUS                     PRIMARY
postgresql   7m46s   2           2       Cluster in healthy state   postgresql-1

Bien évidemment, cette instance a pu être déployée aussi vite car l’instance ne contenait aucune donnée. Dans un cas réel, les données devront être récupérées depuis le primaire et copiées pour le secondaire.

Perte de l’instance primaire

Nos deux instances fonctionnent bien jusqu’au jour où l’instance primaire connaît un problème. Véritable cauchemar du DBA, qui, malgré les différentes protections et outils mis en place, ne veut pas vivre cette situation. Est-ce que l’opérateur CloudNativePG permet au DBA de dormir un peu plus sur ces deux oreilles ?

C’est ce que nous allons voir en détruisant l’instance primaire. Attention, vous êtes ici en présence de professionels, ne reproduisez pas cela à la maison 😂!

kubectl delete pod postgresql-1 
pod "postgresql-1" deleted

Automatiquement, l’opérateur a promu l’instance postgresql-2 comme nouveau primaire :

kubectl get cluster  
NAME         AGE   INSTANCES   READY   STATUS                     PRIMARY
postgresql   44h   2           2       Cluster in healthy state   postgresql-2

Et en parallèle a recréé l’instance postgresql-1 :

kubectl get pod                
NAME           READY   STATUS    RESTARTS   AGE
postgresql-1   1/1     Running   0          3s
postgresql-2   1/1     Running   0          44h

L’opérateur a eu l’information que le primaire connaissait un problème, notamment via le système de Probes. Il a décidé de promouvoir le second en primaire. Un nouveau Pod a été recréé pour remplacer l’ancien et a pu rejoindre le cluster PostgreSQL existant. La bascule s’est donc faite automatiquement. Par un système de labels, les Services qui permettent d’accéder aux instances ont été mis à jour automatiquement et redirigent les connexions vers votre instance .

Cette dernière partie est trop obscure pour vous ? Ne vous en faites pas d’autres articles sont prévus pour expliquer tout cela.

Conclusion

Nous venons de voir comment l’opérateur CloudNativePG nous permet de déployer rapidement une instance PostgreSQL dans un cluster Kubernetes. La mise en place d’un secondaire se fait très facilement et lorsqu’un problème survient sur le primaire, une bascule automatique est initiée. Effet waouh garanti !

L’opérateur CloudNativePG nous permet d’envisager sereinement le déploiement de PostgreSQL dans Kubernetes. Au delà de cet effet et de son côté magique, de nombreux mécanismes de PostgreSQL, de CloudNativePG et de Kubernetes sont mis en place. Leur connaissance est essentielle et c’est bien le but de cette série d’articles.

Des questions, des commentaires ? Écrivez-nous !


DALIBO

DALIBO est le spécialiste français de PostgreSQL®. Nous proposons du support, de la formation et du conseil depuis 2005.