Aperçu des opérateurs PostgreSQL pour Kubernetes, notre sélection et notre expérience

Aperçu des opérateurs PostgreSQL pour Kubernetes, notre sélection et notre expérience

De plus en plus de clients demandent : « Nous voulons quelque chose comme Amazon RDS, mais moins cher » ; « Nous voulons quelque chose comme RDS, mais partout, dans n'importe quelle infrastructure ». Pour réaliser une telle solution gérée sur Kubernetes, nous avons examiné l'état actuel des opérateurs les plus populaires pour PostgreSQL (Stolon, opérateurs de Crunchy Data et Zalando) et avons fait notre choix.

Cet article est le fruit de notre expĂ©rience, Ă  la fois d'un point de vue thĂ©orique (aperçu des solutions) et pratique (ce qui a Ă©tĂ© choisi et ce qui en est rĂ©sultĂ©). Mais d'abord, dĂ©terminons quelles sont les exigences qui s'appliquent Ă  un Ă©ventuel remplacement de RDS


Qu'est-ce que RDS ?

Lorsque les gens parlent de RDS, de notre expérience, ils font référence à un service géré (managed) de SGBD qui :

  1. est facilement configurable ;
  2. permet le travail avec des snapshots et de se restaurer Ă  partir d'eux (idĂ©alement — avec le support de PITR);
  3. permet de créer des topologies master-esclaves ;
  4. dispose d'une riche liste d'extensions ;
  5. offre des fonctionnalités d'audit et de gestion des utilisateurs / des accÚs.

En gĂ©nĂ©ral, les approches pour rĂ©aliser la tĂąche formulĂ©e peuvent ĂȘtre trĂšs variĂ©es, cependant, la voie de l'Ansible conditionnel ne nous convient pas. (Les collĂšgues de 2GIS ont Ă©galement abouti Ă  une conclusion similaire Ă  la suite de leur tentative de crĂ©er un « outil pour le dĂ©ploiement rapide d'un cluster Ă  tolĂ©rance de pannes basĂ© sur Postgres ».) Les opĂ©rateurs — sont l'approche gĂ©nĂ©ralement acceptĂ©e pour rĂ©soudre de telles tĂąches dans l'Ă©cosystĂšme Kubernetes. Plus de dĂ©tails sur ceux-ci concernant les bases de donnĂ©es exĂ©cutĂ©es Ă  l'intĂ©rieur de Kubernetes ont dĂ©jĂ  Ă©tĂ© abordĂ©s par le directeur technique de Flant,

dans l'une de ses prĂ©sentations distol, sur : Pour crĂ©er rapidement des opĂ©rateurs simples, nous recommandons de prĂȘter attention Ă  notre outil Open Source.

NB. En l'utilisant, cela peut ĂȘtre fait sans connaissances en Go, mais de maniĂšre plus familiĂšre pour les administrateurs systĂšmes : en Bash, Python, etc. shell-operatorIl existe plusieurs opĂ©rateurs K8s populaires pour PostgreSQL :

Stolon ;

  • OpĂ©rateur PostgreSQL de Crunchy Data ;
  • OpĂ©rateur Postgres de Zalando.
  • Regardons-les de plus prĂšs.

Choix de l'opérateur

Au-delĂ  des importantes capacitĂ©s dĂ©jĂ  mentionnĂ©es ci-dessus, nous — en tant qu'ingĂ©nieurs d'exploitation de l'infrastructure dans Kubernetes — attendions Ă©galement des opĂ©rateurs les Ă©lĂ©ments suivants :

déploiement depuis Git et avec

  • ressources personnalisĂ©es ; support de l'anti-affinitĂ© des pods ;;
  • installation de l'affinitĂ© ou du sĂ©lecteur de nƓuds ;
  • installation des tolerations ;
  • possibilitĂ© de tuning ;
  • technologies comprĂ©hensibles et mĂȘme commandes.
  • des technologies comprĂ©hensibles et mĂȘme des Ă©quipes.

Sans entrer dans les dĂ©tails de chaque point (n'hĂ©sitez pas Ă  poser des questions dans les commentaires si vous en avez aprĂšs avoir lu l'article complet), je souhaite souligner que ces paramĂštres sont nĂ©cessaires pour dĂ©crire plus prĂ©cisĂ©ment la spĂ©cialisation des nƓuds du cluster afin de les commander pour des applications spĂ©cifiques. Cela nous permet d'obtenir un Ă©quilibre optimal entre performance et coĂ»t.

Passons maintenant aux opérateurs PostgreSQL.

1. Stolon

Stolon de l'entreprise italienne Sorint.lab dans le rapport déjà mentionné était considéré comme un certain standard parmi les opérateurs pour SGBD. C'est un projet assez ancien : sa premiÚre version publique a été publiée en novembre 2015 (!), et le dépÎt GitHub peut se vanter de prÚs de 3000 étoiles et de plus de 40 contributeurs.

Et en effet, Stolon est un excellent exemple d'une architecture bien pensée :

Aperçu des opérateurs PostgreSQL pour Kubernetes, notre sélection et notre expérience
Les dĂ©tails de la mise en Ɠuvre de cet opĂ©rateur peuvent ĂȘtre consultĂ©s dans le rapport ou documentation du projet. D'une maniĂšre gĂ©nĂ©rale, il suffit de dire qu'il fait tout ce qui a Ă©tĂ© dĂ©crit : basculement, proxy pour l'accĂšs transparent des clients, sauvegardes... De plus, les proxies fournissent un accĂšs via un seul point de service — contrairement aux deux autres solutions examinĂ©es plus loin (qui ont deux services pour accĂ©der Ă  la base).

Cependant, Stolon n'a pas de ressources personnalisĂ©es, ce qui empĂȘche de le dĂ©ployer simplement et rapidement — «comme des petits pains» — pour crĂ©er des instances de SGBD dans Kubernetes. La gestion se fait via l'outil stolonctl, le dĂ©ploiement via un chart Helm, et les personnalisations sont dĂ©finies dans ConfigMap.

D'une part, on pourrait dire que l'opérateur n'est pas vraiment un opérateur (puisqu'il n'utilise pas de CRD). Mais d'autre part, c'est un systÚme flexible qui permet de configurer les ressources dans K8s comme cela vous convient.

Pour résumer, il ne nous a pas semblé optimal de créer un chart séparé pour chaque base de données. Nous avons donc commencé à chercher des alternatives.

2. Crunchy Data PostgreSQL Operator

L'opĂ©rateur de Crunchy Data, une jeune startup amĂ©ricaine, semblait ĂȘtre une alternative logique. Son histoire publique commence avec la premiĂšre version en mars 2017 ; depuis lors, le dĂ©pĂŽt GitHub a reçu un peu moins de 1300 Ă©toiles et plus de 50 contributeurs. La derniĂšre version de septembre a Ă©tĂ© testĂ©e pour fonctionner avec Kubernetes 1.15—1.18, OpenShift 3.11+ et 4.4+, GKE et VMware Enterprise PKS 1.3+.

L'architecture de Crunchy Data PostgreSQL Operator répond également aux exigences déclarées :

Aperçu des opérateurs PostgreSQL pour Kubernetes, notre sélection et notre expérience

La gestion se fait via l'outil pgo, cependant, il génÚre des ressources personnalisées pour Kubernetes. Ainsi, nous, en tant qu'utilisateurs potentiels, avons été ravis par l'opérateur :

  • la gestion via CRD ;
  • une gestion pratique des utilisateurs (Ă©galement via CRD) ;
  • intĂ©gration avec d'autres composants Crunchy Data Container Suite — une collection spĂ©cialisĂ©e d'images de conteneurs pour PostgreSQL et les utilitaires associĂ©s (y compris pgBackRest, pgAudit, des extensions de contrib, etc.).

Cependant, les tentatives d'utilisation de l'opérateur de Crunchy Data ont révélé quelques problÚmes :

  • Il n'y avait pas de possibilitĂ© de tolerations — seul nodeSelector Ă©tait prĂ©vu.
  • Les pods créés faisaient partie d'un dĂ©ploiement, mĂȘme si nous dĂ©ployions une application stateful. Contrairement Ă  StatefulSet, les dĂ©ploiements ne permettent pas de crĂ©er des disques.

Ce dernier inconvénient a conduit à des moments amusants : dans l'environnement de test, il a été possible de lancer 3 répliques avec un seul disque stockage local, ce qui a conduit l'opérateur à indiquer que 3 répliques fonctionnaient (bien que ce ne fût pas le cas).

Une autre caractĂ©ristique de cet opĂ©rateur est son intĂ©gration prĂȘte Ă  l'emploi avec divers systĂšmes auxiliaires. Par exemple, il est facile d'installer pgAdmin et pgBounce, et documentation des Grafana et Prometheus prĂ©configurĂ©s sont Ă©galement envisagĂ©s. Dans la rĂ©cente version 4.5.0-beta1 une meilleure intĂ©gration avec le projet pgMonitor, grĂące Ă  laquelle l'opĂ©rateur propose une visualisation claire des mĂ©triques PgSQL « prĂȘtes Ă  l'emploi ».

Néanmoins, le choix étrange des ressources Kubernetes générées nous a conduits à devoir trouver une autre solution.

3. Zalando Postgres Operator

Nous connaissons les produits Zalando depuis longtemps : nous avons de l'expĂ©rience avec Zalenium et, bien sĂ»r, nous avons essayĂ© Patroni — leur solution HA populaire pour PostgreSQL. L'approche de l'entreprise pour crĂ©er Postgres Operator a Ă©tĂ© prĂ©sentĂ©e par l'un de ses auteurs — Alexey Klyukin — lors du Postgres Mardi n°5, et nous l'avons apprĂ©ciĂ©.

C'est la solution la plus jeune parmi celles examinées dans l'article : le premier lancement a eu lieu en août 2018. Cependant, malgré le nombre limité de lancements formels, le projet a parcouru un long chemin, surpassant déjà en popularité la solution de Crunchy Data avec plus de 1300 étoiles sur GitHub et le nombre maximum de contributeurs (plus de 70).

« Sous le capot », cet opérateur utilise des solutions éprouvées :

  • Patroni et Spilo pour la gestion,
  • WAL-E — pour les sauvegardes,
  • PgBouncer — comme pool de connexions.

Voici comment est présentée l'architecture de l'opérateur de Zalando :

Aperçu des opérateurs PostgreSQL pour Kubernetes, notre sélection et notre expérience

L'opĂ©rateur est entiĂšrement gĂ©rĂ© via les Custom Resources, crĂ©ant automatiquement un StatefulSet Ă  partir de conteneurs, qui peuvent ensuite ĂȘtre personnalisĂ©s en ajoutant diffĂ©rents sidecars dans les pods. Tout cela constitue un avantage considĂ©rable par rapport Ă  l'opĂ©rateur de Crunchy Data.

Puisque nous avons choisi la solution de Zalando parmi 3 options examinées, la description de ses fonctionnalités sera présentée ci-dessous, immédiatement avec des exemples d'application.

Pratique avec Postgres Operator de Zalando

Le déploiement de l'opérateur est trÚs simple : il suffit de télécharger la version actuelle depuis GitHub et d'appliquer les fichiers YAML à partir du répertoire. manifests. En variante, vous pouvez également utiliser OperatorHub.

AprĂšs l'installation, il convient de se prĂ©occuper de la configuration des stockages pour les journaux et les sauvegardes. Cela se fait via ConfigMap postgres-operator dans l'espace de noms oĂč vous avez installĂ© l'opĂ©rateur. Une fois les stockages configurĂ©s, vous pouvez dĂ©ployer le premier cluster PostgreSQL.

Par exemple, le déploiement standard que nous avons est le suivant :

apiVersion: acid.zalan.do/v1
kind: postgresql
metadata:
 name: staging-db
spec:
 numberOfInstances: 3
 patroni:
   synchronous_mode: true
 postgresql:
   version: "12"
 resources:
   limits:
     cpu: 100m
     memory: 1Gi
   requests:
     cpu: 100m
     memory: 1Gi
 sidecars:
 - env:
   - name: DATA_SOURCE_URI
     value: 127.0.0.1:5432
   - name: DATA_SOURCE_PASS
     valueFrom:
       secretKeyRef:
         key: password
         name: postgres.staging-db.credentials
   - name: DATA_SOURCE_USER
     value: postgres
   image: wrouesnel/postgres_exporter
   name: prometheus-exporter
   resources:
     limits:
       cpu: 500m
       memory: 100Mi
     requests:
       cpu: 100m
       memory: 100Mi
 teamId: staging
 volume:
   size: 2Gi

Ce manifeste déploie un cluster de 3 instances avec un sidecar pour postgres_exporter, à partir duquel nous collectons les métriques de l'application. Comme vous pouvez le voir, tout est trÚs simple et si vous le souhaitez, vous pouvez créer littéralement un nombre illimité de clusters.

Il convient Ă©galement de prĂȘter attention Ă  le panneau web pour l'administration — postgres-operator-ui. Il est fourni avec l'opĂ©rateur et permet de crĂ©er et de supprimer des clusters, ainsi que de travailler avec les sauvegardes rĂ©alisĂ©es par l'opĂ©rateur.

Aperçu des opérateurs PostgreSQL pour Kubernetes, notre sélection et notre expérience
Liste des clusters PostgreSQL

Aperçu des opérateurs PostgreSQL pour Kubernetes, notre sélection et notre expérience
Gestion des sauvegardes

Une autre caractéristique intéressante est la prise en charge de Teams API. Ce mécanisme crée automatiquement des rÎles dans PostgreSQL, en fonction de la liste des noms d'utilisateurs fournie. AprÚs cela, l'API permet de renvoyer la liste des utilisateurs pour lesquels des rÎles sont créés automatiquement.

ProblĂšmes et leurs solutions

Cependant, l'utilisation de l'opérateur a rapidement révélé plusieurs inconvénients significatifs :

  1. absence de support pour nodeSelector;
  2. impossibilité de désactiver les sauvegardes;
  3. lors de l'utilisation de la fonction de création de bases, les privilÚges par défaut ne sont pas appliqués;
  4. il manque parfois de la documentation ou celle-ci est obsolĂšte.

Heureusement, beaucoup d'entre eux peuvent ĂȘtre rĂ©solus. Commençons par la fin — les problĂšmes avec de la documentation.

Vous rencontrerez probablement des difficultés pour spécifier une sauvegarde et comment connecter le bucket de sauvegarde à l'Interface Utilisateur de l'Opérateur. Cela est briÚvement mentionné dans la documentation, mais une description réelle se trouve dans PR:

  1. il faut créer un secret;
  2. le transmettre à l'opérateur dans le paramÚtre pod_environment_secret_name dans le CRD avec les paramÚtres de l'opérateur ou dans le ConfigMap (selon la maniÚre dont vous avez choisi d'installer l'opérateur).

Cependant, il s'avĂšre qu'actuellement, cela n'est pas possible. C'est pourquoi nous avons rassemblĂ© notre version de l'opĂ©rateur avec quelques dĂ©veloppements supplĂ©mentaires externes. Plus de dĂ©tails Ă  ce sujet — voir ci-dessous.

Si vous transmettez des paramĂštres Ă  l'opĂ©rateur pour la sauvegarde, Ă  savoir — wal_s3_bucket et les clĂ©s d'accĂšs dans AWS S3, alors il sauvegardera tout: non seulement les bases en production, mais aussi le staging. Cela ne nous convenait pas.

Dans la description des paramĂštres de Spilo, qui est l'enveloppe Docker de base pour PgSQL lors de l'utilisation de l'opĂ©rateur, il a Ă©tĂ© rĂ©vĂ©lĂ© : vous pouvez transmettre le paramĂštre WAL_S3_BUCKET vide, dĂ©sactivant ainsi les sauvegardes. De plus, Ă  notre grand plaisir, un PR prĂȘt, que nous avons immĂ©diatement intĂ©grĂ© dans notre fork. Il suffit maintenant d'ajouter enableWALArchiving: false au ressourcement du cluster PostgreSQL.

Oui, il y avait la possibilitĂ© de faire autrement, en lançant 2 opĂ©rateurs : un pour le staging (sans sauvegardes), et un autre — pour la production. Mais nous avons pu nous contenter d'un seul.

D'accord, nous avons appris Ă  donner accĂšs aux bases pour S3 et les sauvegardes ont commencĂ© Ă  ĂȘtre stockĂ©es. Comment faire fonctionner les pages de sauvegarde dans l'Interface Utilisateur de l'OpĂ©rateur ?

Aperçu des opérateurs PostgreSQL pour Kubernetes, notre sélection et notre expérience

Dans l'Interface Utilisateur de l'Opérateur, il sera nécessaire d'ajouter 3 variables :

  • SPILO_S3_BACKUP_BUCKET
  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY

AprÚs cela, la gestion des sauvegardes deviendra accessible, ce qui, dans notre cas, facilitera le travail avec le staging, permettant d'y envoyer des copies de production sans scripts supplémentaires.

Comme un autre avantage, on a mentionné le travail avec l'API Teams et des larges possibilités pour créer des bases et des rÎles au moyens de l'opérateur. Cependant, les rÎles créés n'avaient pas de privilÚges par défaut. En conséquence, l'utilisateur avec des droits en lecture ne pouvait pas lire les nouvelles tables.

Pourquoi cela ? Bien que dans le code Il existe les nĂ©cessaires GRANT, elles ne sont pas toujours appliquĂ©es. Il existe 2 mĂ©thodes : syncPreparedDatabases et syncDatabases. Il y a syncPreparedDatabases — bien que dans la section preparedDatabases Il existe il y ait une condition defaultRoles et defaultUsers pour la crĂ©ation des rĂŽles, — les droits par dĂ©faut ne s'appliquent pas. Nous sommes en train de prĂ©parer un patch pour que ces droits s'appliquent automatiquement.

Et dernier point dans les amĂ©liorations qui nous concernent — un patch, ajoutant la Node Affinity au StatefulSet créé. Nos clients prĂ©fĂšrent souvent rĂ©duire leurs coĂ»ts en utilisant des instances spot, et il est clairement risquĂ© d'y dĂ©ployer des services de base de donnĂ©es. Ce problĂšme pourrait also ĂȘtre rĂ©solu via des tolerations, mais la Node Affinity fournit une plus grande assurance.

Qu'est-ce qui en est sorti ?

À la suite de la rĂ©solution des problĂšmes Ă©voquĂ©s, nous avons forkĂ© le Postgres Operator de Zalando dans notre dĂ©pĂŽt, oĂč il est assemblĂ© avec des patches aussi utiles. Pour plus de commoditĂ©, nous avons Ă©galement Docker image.

Liste des PR acceptées dans le fork :

Ce serait formidable si la communautĂ© soutenait ces PR afin qu'elles puissent ĂȘtre intĂ©grĂ©es dans l'upstream avec la prochaine version de l'opĂ©rateur (1.6).

Bonus ! Histoire de succĂšs avec la migration de production

Si vous utilisez Patroni, vous pouvez migrer la production en direct vers l'opĂ©rateur avec un minimum de temps d'arrĂȘt.

Spilo permet de créer des clusters standby via des stockages S3 avec Wal-E, lorsque le log binaire PgSQL est d'abord sauvegardé dans S3, puis récupéré par la réplique. Mais que faire si vous avez ne utilisé Wal-E dans une ancienne infrastructure ? La solution à ce problÚme a déjà été proposée sur Habré.

La réplication logique de PostgreSQL vient à la rescousse. Cependant, nous n'allons pas entrer dans les détails, comme la création de publications et d'abonnements, car
 notre plan a échoué.

Le fait est qu'il y avait plusieurs tables trÚs chargées dans la BDD avec des millions de lignes, qui, de plus, étaient constamment ajoutées et supprimées. Un simple abonnement avec copy_data, lorsque la nouvelle réplique copie tout le contenu du maßtre, ne parvenait tout simplement pas à suivre le maßtre. La copie du contenu a duré une semaine, mais n'a jamais rattrapé le maßtre. Au final, nous avons pu résoudre le problÚme grùce à article un collÚgue d'Avito : il est possible de transférer les données en utilisant pg_dump. Je vais décrire notre (un peu modifié) version de cet algorithme.

L'idée est de créer une souscription désactivée liée à un slot de réplication spécifique, puis de corriger le numéro de transaction. Des répliques étaient disponibles pour le fonctionnement de la production. C'est important, car la réplique aide à créer un dump cohérent et à continuer à recevoir les changements du maßtre.

Dans les commandes suivantes décrivant le processus de migration, les notations suivantes seront utilisées pour les hÎtes :

  1. master — serveur source ;
  2. replica1 — rĂ©plique en streaming sur l'ancienne production ;
  3. replica2 — nouvelle rĂ©plique logique.

Plan de migration

1. Créons sur le maßtre une souscription à toutes les tables dans le schéma public de la base dbname:

psql -h master -d dbname -c "CREATE PUBLICATION dbname FOR ALL TABLES;"

2. Créons un slot de réplication sur le maßtre :

psql -h master -c "select pg_create_logical_replication_slot('repl', 'pgoutput');"

3. ArrĂȘtons la rĂ©plication sur l'ancienne rĂ©plique :

psql -h replica1 -c "select pg_wal_replay_pause();"

4. Obtenons le numéro de transaction du maßtre :

psql -h master -c "select replay_lsn from pg_stat_replication where client_addr = 'replica1';"

5. Réalisons un dump de l'ancienne réplique. Nous le ferons en plusieurs flux, ce qui aidera à accélérer le processus :

pg_dump -h replica1 --no-publications --no-subscriptions -O -C -F d -j 8 -f dump/ dbname

6. Chargeons le dump sur le nouveau serveur :

pg_restore -h replica2 -F d -j 8 -d dbname dump/

7. AprÚs le chargement du dump, nous pouvons relancer la réplication sur la réplique en streaming :

psql -h replica1 -c "select pg_wal_replay_resume();"

8. Créons une souscription sur la nouvelle réplique logique :

psql -h replica2 -c "create subscription oldprod connection 'host=replica1 port=5432 user=postgres password=secret dbname=dbname' publication dbname with (enabled = false, create_slot = false, copy_data = false, slot_name='repl');"

9. Obtenons oid de la souscription :

psql -h replica2 -d dbname -c "select oid, * from pg_subscription;"

10. Supposons que nous avons obtenu oid=1000. Appliquons le numéro de transaction à la souscription :

psql -h replica2 -d dbname -c "select pg_replication_origin_advance('pg_1000', 'AA/AAAAAAAA');"

11. Lancez la réplication :

psql -h replica2 -d dbname -c "alter subscription oldprod enable;"

12. VĂ©rifions le statut de la souscription, la rĂ©plication doit ĂȘtre opĂ©rationnelle :

psql -h replica2 -d dbname -c "select * from pg_replication_origin_status;"
psql -h master -d dbname -c "select slot_name, restart_lsn, confirmed_flush_lsn from pg_replication_slots;"

13. Une fois la réplication lancée et les bases synchronisées, il est possible d'effectuer le basculement.

14. AprÚs la désactivation de la réplication, il faut corriger les séquences. Cela est bien décrit dans un article sur wiki.postgresql.org.

Grùce à ce plan, le basculement s'est effectué avec un minimum de retards.

Conclusion

Les opérateurs Kubernetes simplifient diverses actions en les réduisant à la création de ressources K8s. Cependant, aprÚs avoir atteint une automatisation impressionnante grùce à eux, il est important de se rappeler qu'elle peut également apporter son lot de nuances inattendues, c'est pourquoi il faut choisir les opérateurs avec discernement.

AprÚs avoir examiné les trois opérateurs Kubernetes les plus populaires pour PostgreSQL, nous avons choisi le projet de Zalando. Nous avons dû surmonter certaines difficultés, mais le résultat a vraiment été satisfaisant, ce qui nous incite à étendre cette expérience à d'autres installations PgSQL. Si vous avez une expérience avec des solutions similaires, nous serions ravis de voir les détails dans les commentaires !

P.S.

Lisez aussi dans notre blog :

Source : habr.com

Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS đŸ”„ Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster