COMMENT DÉPLOYER POSTGRESQL DANS
UN CLUSTER KUBERNETES AVEC HAUTE
DISPONIBILITÉ
Contexte et Objectifs
Dans cet article il est question d’expliquer chacun des composants requis pour déployer un cluster StatefulSet PostgreSQL sur Kubernetes. Nous discuterons également de la configuration du cluster PostgreSQL hautement disponible à l’aide de pgpool et repmgr. Vers la fin de l’article, nous avons ajouté le guide pour effectuer des opérations de base dans le cluster PostgreSQL à l’aide d’un pod client. Voici ce que vous allez apprendre dans ce guide complet de déploiement de PostgreSQL.
Durée de mise en place : 30 à 45 min
Étapes de mise en place du projet
- 1. Manifestes Kubernetes du cluster PostgreSQL
2. Image Docker Bitnami PostgreSQL
3. Architecture de haut niveau
4. Créer un espace de noms et des volumes persistants
5. Création de ConfigMaps du serveur Postgres
6. Déployer les services PostgreSQL
7. Créer des secrets de serveur PostgresSQL
8. StatefulSet PostgreSQL
9. Pourquoi avons-nous besoin du Statefulset PostgreSQL ?
10. Déployer le Statefulset PostgreSQL
11.RepMgr dans les serveurs PostgresSQL
12. Astuce pour utiliser efficacement “le service sans tête”
13. Pg-Pool pour PostgreSQL
14. Création des secrets du pg-pool
15. Création du service pg-pool
16. Création du Deployment de pg-pool
17. Haute disponibilité de PostgreSQL
18.Connectez-vous au cluster PostgreSQL à partir du client
19.Vérification de la réplication PostgreSQL
20.Mesurer les performances de PostgreSQL
Présentation des différents outils et plateformes
- Kubernetes: k8s (pour k, 8 caractères, s) ou encore « kube », est une plateforme Open Source qui automatise l’exploitation des conteneurs Linux. Elle permet d’éliminer de nombreux processus manuels associés au déploiement et à la mise à l’échelle des applications conteneurisées. En d’autres termes, Kubernetes vous aide à gérer facilement et efficacement des clusters au sein desquels vous aurez rassemblé des groupes d’hôtes exécutant des conteneurs Linux. Ces clusters peuvent couvrir des hôtes situés dans des clouds publics, privés ou hybrides. C’est la raison pour laquelle Kubernetes est la plateforme idéale pour héberger les applications cloud-native qui requièrent une mise à l’échelle rapide, comme la diffusion de données en continu et en temps réel via Apache Kafka.
- PostgreSQL: est un système de gestion de bases de données relationnelles (SGBDR) open-source, reconnu pour sa robustesse, sa fiabilité et sa conformité aux standards SQL. Il supporte de nombreuses fonctionnalités avancées comme les transactions ACID (Atomicité, Cohérence, Isolation, Durabilité), le support complet des clés étrangères, des vues, des déclencheurs et des procédures stockées. Il offre également des capacités de réplication, de haute disponibilité et de gestion de grandes bases de données. PostgreSQL est extensible, permettant aux utilisateurs d’ajouter des types de données, des fonctions et des opérateurs personnalisés, et est souvent utilisé pour des applications nécessitant une intégrité des données stricte et une haute performance.
- Linux: Administration et automatisation est un ensemble de pratiques et de techniques visant à gérer et à automatiser les tâches liées au système d’exploitation Linux. Cela implique la configuration, la maintenance et la sécurisation des systèmes Linux, ainsi que l’automatisation des processus répétitifs à l’aide d’outils comme Ansible, Bash scripting et d’autres solutions. L’objectif est d’optimiser l’efficacité opérationnelle et de garantir la cohérence et la fiabilité des systèmes Linux dans les environnements informatiques. Si vous souhaiter en savoir d’avantage sur ces notions, vous pouvez suivre le cours de Linux sur eazytraining.fr Linux: Administration et automatisation – EAZYTraining
Note : Pour en savoir plus, je vous invite à aller regarder notre site web où vous trouverez des cours très intéressants sur ces différentes technologies. EAZYTraining
Environnement
- Linux
- Kubernetes
- PostgreSQL
Manifestes Kubernetes du cluster PostgreSQL
Nous avons classé les manifestes en trois dossiers nommés client, pgpool et postgresql comme indiqué ci-dessous.
Contexte
Si vous souhaitez déployer les composants en une seule fois, rendez-vous dans chaque répertoire et exécutez ce qui suit. Commencez par le répertoire postgresql : kubectl apply -f . -n database
Image Docker Bitnami PostgreSQL
Ce tutoriel a utilisé des images Docker Bitnami, cela a été fait intentionnellement. En tant que débutant, vous pouvez bénéficier de certains avantages en utilisant une image Bitnami.
- Les images Bitnami sont livrées avec les composants nécessaires préinstallés. Cela nous permet de rester concentrés sur la compréhension et de nous familiariser en profondeur avec l’aspect Kubernetes.
- Les images Bitnami sont bien testées et validées avant d’être publiées. Cela nous aide à gagner du temps et à surmonter les problèmes auxquels nous pourrions être confrontés avec des versions ou des
correctifs plus récents. - Les images Bitnami sont très bien documentées, vous trouverez une explication satisfaisante de chaque variable d’environnement utilisée par l’image Bitnami. C’est donc un choix naturel pour les débutants.
Architecture de haut niveau
Créer un espace de noms et des Volumes Persistants
Pour déployer le cluster PostgreSQL, nous allons créer un espace de noms dédié nommé « database ». Enregistrez le manifeste suivant sous un fichier ns-database.yml
kubectl apply -f ns-database.yml
L’espace de noms n’est pas ajouté aux fichiers manifestes. Nous allons donc ajouter l’espace de noms lors du déploiement de chaque composant. Si vous ne spécifiez pas l’espace de noms, le composant est déployé dans l’espace de noms par défaut. Par la suite, il est nécessaire de créer manuellement des volumes persistants afin que ceux-ci soient consommés par Postgresql dans la suite. Enregistrez le manifeste suivant sous un fichier pv-localstorage.yaml
Création de ConfigMaps du serveur Postgres
Un ConfigMaps dans Kubernetes nous permet de monter des fichiers sur des conteneurs sans avoir besoin de modifier le Dockerfile ou de reconstruire l’image du conteneur.
Cette fonctionnalité est extrêmement utile dans le cas où les configurations doivent être modifiées ou créées via des fichiers.
Postgres nécessite qu’un script (pre-stop.sh) soit exécuté chaque fois qu’il est sur le point d’être arrêté. Nous monterons ce script dans le pod à l’aide de ConfigMaps. Enregistrez le manifeste suivant sous un fichier postgresconfigmap.yaml
kubectl apply -f postgres-configmap.yaml -n database
Il est important de comprendre ce que le script essaie de faire.
Voici l’aperçu :
- Le script vérifie d’abord quel type de composant est arrêté, c’est-à-dire primary ou standby
- Dans le cas où le primary est arrêté, le script retarde l’arrêt du pod jusqu’à ce qu’un standby précédent soit promu primary
- Ceci est fait pour garantir une haute disponibilité, c’est-à-dire qu’il doit exister au moins un primary doté de capacités d’écriture.
Pas assez clair ? Pas de panique. Après avoir lu la section sur la haute disponibilité, les points ci-dessus deviendront clairs et prendront beaucoup plus de sens.
Assurez-vous de parcourir le script et de revoir chaque ligne.
Déployer les services PostgreSQL
Les services dans Kubernetes sont les objets que les pods utilisent pour communiquer entre eux. Les services de type ClusterIP sont généralement utilisés pour la communication inter-pods.
Il existe deux types de services ClusterIP :
- Headless Services (Services sans tête)
- Services (Services normaux)
Les services Kubernetes normaux agissent comme des équilibreurs de charge et suivent une logique circulaire pour distribuer les charges. Les ‘’Headless Services’’ n’agissent pas comme des équilibreurs de charge. De plus, les services normaux se voient attribuer des adresses IP par Kubernetes, contrairement aux ‘’Headless Services’’.
Dans le cas des serveurs Postgres, nous avons besoin d’un ‘’Headless Services’’ car c’est une exigence pour le StatefulSet PostgreSQL.
Enregistrez le manifeste suivant sous postgres-headless-svc.yaml.
kubectl apply -f postgres-headless-svc.yaml -n database
Créer des secrets du serveur PostgreSQL
Les secrets dans Kubernetes sont les objets utilisés pour fournir des informations sensibles aux conteneurs. Ils ressemblent à des ConfigMaps, à la différence que les données sont stockées dans un format codé en base 64.
Pour la sécurité de notre cluster PostgreSQL, il est judicieux de restreindre l’accès à la base de données avec un mot de passe. Nous utiliserons des secrets pour monter les mots de passe souhaités sur les conteneurs.
Remarque : Dans les cas d’utilisation en production, une solution de gestion des secrets telle que hashicorp vault devrait être utilisée pour stocker et récupérer les secrets.
Enregistrez le manifeste suivant sous postgres-secrets.yaml. Veuillez modifier le mot de passe avec votre propre mot de passe sécurisé.
Enregistrez le manifeste suivant sous postgres-secrets.yaml. Veuillez modifier le mot de passe avec votre propre mot de passe sécurisé.
kubectl apply -f postgres-secrets.yaml -n database
Lorsque le cluster est initialisé, il crée certains utilisateurs comme postgres & repmgr dans notre cas. Les mots de passe ci-dessus sont destinés à ces utilisateurs.
StatefulSet PostgreSQL
Lors du déploiement de PostgreSQL sur Kubernetes, quel type d’objet doit être utilisé et pourquoi ? Deployment ou StatefulSet ??
La réponse est StatefulSet. Voici pourquoi.
StatefulSet est l’objet Kubernetes utilisé pour gérer les applications avec état. Il est préféré au Deployment pour ce cas d’utilisation car il fournit des garanties sur l’ordre et l’unicité de ces pods, c’est-à-dire que la gestion des volumes est meilleure avec des StatefulSet.
Cette section est essentielle pour mieux comprendre la logique de déploiement. Alors lisez avec attention !
En tant que débutant, il est important de comprendre pourquoi nous souhaitons déployer un Statefulset et non des Deployments. Après tout, notre objectif est de comprendre le « pourquoi » et d’apprendre le «comment ».
Pourquoi avons-nous besoin du Statefulset PostgreSQL ?
PostgreSQL sera une application avec état, c’est-à-dire qu’elle stocke les données (comme les tables, les utilisateurs) dans un volume. Si les données sont stockées dans le stockage éphémère du pod, elles seront effacées une fois le pod redémarré.
En outre, PostgreSQL devra être étendu à plusieurs modules en cas d’augmentation de la charge de travail.
Toutes ces opérations doivent être effectuées de manière à ce que la cohérence des données soit maintenue sur tous les pods comme postgres0, postgres-1, postgres-2.
Comment pouvons-nous y parvenir dans Kubernetes ? Réfléchissez et lisez à l’avance !
PostgreSQL implémente la réplication continue des données sur tous ses pods. Ainsi, lorsque les données sont écrites sur postgres-0, elles sont répliquées dans postgres-1. postgres-2 réplique les données de postgres-1. Et ainsi de suite…
PostgreSQL est capable d’effectuer cette réplication continue à l’aide d’un outil open source appelé RepMgr , intégré à l’image Docker de Postgres.
La chose à comprendre ici est que postgres-1 doit savoir où chercher postgres-0. Sinon, comment se déroulera la réplication ?
- Comment saura-t-il où récupérer les données pour le processus de réplication ?
- Comment postgres-1 saura-t-il où chercher postgres-0 ?
- Comment postgres-2 saura-t-il où chercher postgres-1 ?
Essayons de répondre à ces questions maintenant.
Dans le cas de Deployment et de StatefulSet, les pods se voient toujours attribuer un nom unique qui peut être utilisé pour rechercher les pods.
Dans le cas des Deployment, les pods se voient toujours attribuer un nom unique, mais ce nom unique change une fois les pods supprimés et recréés. il devient donc difficile d’identifier un pod.
Dans le cas des StatefulSet, chaque pod se voit attribuer un nom unique et ce nom unique reste avec lui même si le pod est supprimé et recréé.
C’est pourquoi nous souhaitons utiliser ici un StatefulSet, afin que nous puissions atteindre n’importe quel pod sans aucune divergence.
En outre, cet ordre unique garantit que chaque pod se voit attribuer le même volume sous-jacent, quels que soient les redémarrages des pods.
Ces concepts de Statefulset et de Deployment ne sont pas propres aux Deployments Postgres, si vous les explorez : vous constaterez que de nombreux outils Kubernetes populaires utilisent des Statefulset.
Quelques exemples sont Vault de Hashicorp, Elasticsearch et bien d’autres.
Tous utilisent les StatefulSet et non des déploiements en raison de la même logique.
Déployer le Statefulset PostgreSQL
Tout d’abord, créons le Statefulset. J’ai également ajouté une explication pour Postgres Statefulset vers la fin de cette section.
Enregistrez le manifeste suivant sous postgres-statefulset.yaml
kubectl apply -f postgres-statefulset.yaml -n database
Le Statefulset YAML du serveur PostgreSQL comporte des composants tels que les montages configmap, le contexte de sécurité, les sondes, etc. Revenons sur les configurations clés.
Métadonnées sous forme de variables d’environnement : dans Kubernetes, des informations telles que le nom des pods, l’espace de noms des pods peuvent être utilisées comme variable d’environnement pour le pod.
Ceci est utile dans les cas où les variables d’environnement doivent utiliser des métadonnées de pods ou certains champs définis par Kubernetes pour les pods.
Variables d’environnement injectés via des secrets : Parfois, les conteneurs ont besoin de connaître les données sensibles afin de les utiliser. Par exemple, pour attribuer un mot de passe à la base de données PostgreSQL, le mot de passe requis doit être fourni de manière sécurisée au conteneur PostgreSQL.
Sondes : les ‘’Probes’’ garantissent que le pod ne reste pas bloqué dans une boucle à cause d’un bug et peuvent être redémarré automatiquement en cas d’erreur inattendue.
Principe de base des ‘’Probes’’ de notre StatefulSet
Ici, la commande utilisée va simplement à la base de données « postgres » en utilisant l’utilisateur « postgres » et en exécutant la requête « SELECT 1 ».
Si le processus Postgres s’exécute correctement, la requête aura un code de sortie réussi. Sinon ‘’non’’.
C’est ainsi que nous pouvons être sûrs que les ‘’Probes’’ peuvent nous dire si le processus est en cours d’exécution ou si le conteneur doit être redémarré !
VolumeClaimTemplates : modèle par lequel un StatefulSet peut créer des volumes pour les réplicas.
Passons maintenant en revue les variables d’environnement importantes pour le processus Postgres.
- POSTGRESQL_VOLUME_DIR : Le répertoire dans lequel le processus Postgres doit écrire ses fichiers de configuration et ses données. C’est le répertoire que nous devons monter avec un PVC.
- PGDATA : Le dossier à l’intérieur du répertoire principal Postgres où le répertoire de données doit être créé.
- POSTGRES_USER : L’utilisateur qui doit être créé automatiquement au démarrage du processus Postgres.
- POSTGRES_PASSWORD : Le mot de passe de l’utilisateur créé par défaut.
- POSTGRES_DB : La base de données qui doit être créée au démarrage du processus Postgres.
Parlons maintenant du RepMgr.
RepMgr dans les serveurs PostgreSQL
RepMgr est un outil open source fourni avec Postgres qui sert à deux fins :
la réplication et le basculement.
- Réplication : Il réplique les données du serveur principal vers toutes les répliques. Cela permet de réduire la charge sur les serveurs en distribuant les requêtes de lecture et d’écriture.
- Basculement : il peut gérer les basculements dans le cluster, c’est-à dire qu’il peut promouvoir un serveur en lecture seule en serveur principal lorsque cela est nécessaire.
- REPMGR_PARTNER_NODES : Ceci attend une liste séparée par des virgules de toutes les adresses de serveur Postgres dans le cluster. Y compris l’adresse du serveur principal.
- REPMGR_PRIMARY_HOST : Ceci attend l’adresse du serveur principal Postgres.
- REPMGR_USERNAME : Utilisateur à créer pour les opérations repmgr.
- REPMGR_PASSWORD : Mot de passe à créer pour les opérations
repmgr - REPMGR_DATABASE : Base de données à créer pour les opérations
repmgr. - Équilibrage de charge : le pg-pool prend en charge les demandes de connexion et les requêtes. Il analyse la requête pour décider où la requête doit être envoyée.
- . Les requêtes en lecture seule peuvent être gérées par des réplicas en lecture. Les opérations d’écriture ne peuvent être gérées que par le serveur principal. De cette façon, il équilibre les charges du cluster.
- Limite les requêtes : comme tout autre système, Postgres a une limite sur le nombre de requêtes de connexions simultanées qu’il peut gérer.
- Pg-pool limite le nombre de connexions qu’il récupère et met en file d’attente le reste. Ainsi, on gère efficacement la surcharge.
-
Passons en revue les variables d’environnement importantes pour la configuration du repmgr .
Astuce pour utiliser efficacement “le service sans tête”
Comme vous le savez, le Headless Service ne fonctionne pas comme un équilibreur de charge et est utilisé pour adresser un groupe de pods ensemble. Il existe un autre cas d’utilisation des Headless Service.
Nous pouvons l’utiliser pour obtenir l’adresse de pods individuels. Prenons un exemple pour comprendre cela. Nous avons trois pods fonctionnant dans le cadre de Postgres Statefulset.
Nom du pod Adresse du module
postgres-sts-0 172.17.0.3
postgres-sts-1 172.17.0.8
postgres-sts-2 172.17.0.10
Pods et leurs adresses et un svc sans tête «postgres-headless-svc » est pointé vers ces pods.
Si vous effectuez une opération nslookup à partir d’un pod exécuté dans le même espace de noms de votre cluster, vous pourrez obtenir l’adresse des pods ci-dessus via le Headless Servicenslookup postgres-sts-0.postgres-headless-svc.database.svc.cluster.local
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: postgres-sts-0.postgres-headless-svc.default.svc.cluster.local
Address: 172.17.0.3
Le concept ci-dessus est très couramment utilisé dans Kubernetes, en fait, la variable d’environnement REPMGR_PARTNER_NODES l’utilise.
Pg-Pool pour PostgreSQL
Pg pool est un composant middleware qui se trouve devant les serveurs Postgres et agit comme un gardien du cluster.
Il sert principalement à deux objectifs : équilibrer la charge et limiter les demandes.
Création des secrets du pg-pool
Enregistrez le manifeste suivant sous le fichier pgpool-secret.yaml
Création du service pg-pool
kubectl apply -f pgpool-svc.yaml -n database
Si vous souhaitez accéder au cluster Postgres depuis l’extérieur du cluster Kubernetes , vous devez également déployer un service de type NodePort.
Enregistrez le manifeste suivant sous pgpool-svc-nodeport.yaml
Créer le service
kubectl apply -f pgpool-svc-nodeport.yaml -n database
Si vous souhaitez accéder au cluster Postgres depuis l’extérieur du cluster Kubernetes , vous devez également déployer un service NodePort.
Enregistrez le manifeste suivant sous pgpool-svc-nodeport.yaml
Créer le service
kubectl apply -f pgpool-svc-nodeport.yaml -n database
Création du Deployment de pg-pool
Enregistrez le manifeste suivant sous pgpool-deployment.yaml
Créez le déploiement.
kubectl apply -f pgpool-deployment.yaml -n database
Haute disponibilité de PostgreSQL
Le mécanisme de basculement (failover) fourni par RepMgr et l’équilibrage de charge (load balancing) fourni par Pg-pool garantissent que le cluster Postgres reste opérationnel pendant une longue période.
Les deux mécanismes assurent ensemble la haute disponibilité du cluster PostgreSQL.
Avec les configurations d’anti-affinité de pods, vous pouvez demander à Kubernetes de déployer des pods dans différents nœuds. Cela garantit que vous n’avez pas de point de défaillance unique si un nœud Kubernetes tombe en panne.
L’anti-affinité des pods nécessite que les nœuds Kubernetes soient étiquetés de façon appropriée. Vous pouvez même consacrer quelques nœuds du cluster aux bases de données en les étiquetant. Avec l’affinité de nœud, tous les pods PostgreSQL sont attribués à des nœuds avec des étiquettes spécifiques.
Connectez-vous au cluster PostgreSQL à partir du client
Créons un pod client psql . Nous l’utiliserons pour connecter et vérifier le cluster. Copiez le contenu du manifeste comme psql-client.yaml
Déployons le client.
kubectl apply -f psql-client.yaml -n database
Essayons maintenant de nous connecter au cluster. Copier le mot de passe.
Exécuter et connecter.
PGPASSWORD=WbrTpN3g7q psql -h pgpool-svc -p 5432 -U postgres
Pour se connecter depuis l’extérieur du cluster.
PGPASSWORD=WbrTpN3g7q psql -h -p -U postgres
Par exemple,
PGPASSWORD=WbrTpN3g7q psql -h 34.138.59.54 -p 32000 -U postgres -p -U postgres
Essayez quelques exemples de commandes de base :
create database db1;
\c db1; //to connect to new database
create table test (id int primary key not null, value text not null);
insert into test values (1, 'value1');
insert into test values (2, 'value2');
insert into test values (3, 'value3');
select * from test;
Vérification de la réplication PostgreSQL
Commande pour vérifier si la réplication a lieu.
//after connecting to the cluster using psql client.
select * from pg_stat_replication;
Nombre d’entrées que vous devriez voir = Nombre de répliques de PostgreSQL en cours d’exécution moins 1.
Raison de « moins 1 » : les données sont répliquées du maître vers le suiveur. Il est logiquement impossible que les Données soient répliquées du maître vers lui-même !
Vérifiez le basculement en supprimant les pods de manière aléatoire et en voyant si le cluster ne répond plus ou non.
Mesurer les performances de PostgreSQL
En tant que débutant, discutons des éléments à garder à l’esprit concernant les performances et les métriques de PostgreSQL.
- Configurations de réglage fin : les performances dépendent principalement des configurations qui ont été définies. Par exemple, les performances peuvent en pâtir à certains moments en raison de l’augmentation des charges de travail. Assurez-vous d’avoir suivi toutes les optimisations de performances suggérées.
- Requêtes optimisées : un autre facteur qui a un impact sur les performances est le type de requêtes dominantes. Si de nombreuses opérations d’écriture sont effectuées dans un temps donné, les performances diminueront. Cela dépend aussi de l’optimisation des requêtes. Plus les requêtes sont optimisées, meilleures sont les performances attendues.
- Taille du cluster : les ressources affectent également les performances. Disons que votre cluster est composé de 3 pods. Pour certains cas d’utilisation, cela peut suffire. Pour beaucoup, cela ne suffira pas.
- Surveillez les métriques de votre base de données et analysez les journaux : surveillez les données en fonction des pics de processeur, du nombre de connexions, de l’espace disque, etc. Si vous avez configuré Prometheus , vous pouvez utiliser l’exportateur PostgreSQL Prometheus pour obtenir toutes les métriques.
- Autres facteurs : la charge de travail elle-même dépend de divers facteurs tels que le calendrier de sauvegarde, les pics de trafic, etc.
Les performances dépendent principalement de votre cas d’utilisation et de vos engagements commerciaux. Cela devrait être exploré encore plus en fonction de votre cas d’utilisation !
Conclusion
C’est tout, les amis ! Nous avons couvert le guide détaillé sur le déploiement du statefulset PostgreSQL sur Kubernetes.
Nous avons également discuté de la haute disponibilité et de la réplication à l’aide de pgpool et repmgr.
En matière de production, une attention particulière doit être portée à la gestion des volumes persistants, à la sauvegarde, à la haute disponibilité et aux performances.
Référence
Techniques
Bitnami Postgresql: https://hub.docker.com/r/bitnami/postgresql/
Bitnami Postgresql HA: https://hub.docker.com/r/bitnami/postgresqlrepmgr/
Bitnami PgPool: https://hub.docker.com/r/bitnami/pgpool
Replication Manager: https://repmgr.org/
HeadLess Service : https://kubernetes.io/docs/concepts/servicesnetworking/service/#headless-services
StatefulSet :
https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/
Dépôt de Correction : https://github.com/OlivierKouokam/kubernetespostgresql
Personnelles
OLIVIER KOUOKAM
Cloud and DevOps Consultant
GitHub: https://github.com/OlivierKouokam
LinkedIn: LinKeDin
Tags: #Informatique #Stockage #Base de données #Kubernetes #Haute Disponibilité #Load Balancing #Fail Over