
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 :
- est facilement configurable ;
- permet le travail avec des snapshots et de se restaurer Ă partir d'eux (idĂ©alement â avec le support de );
- permet de créer des topologies master-esclaves ;
- dispose d'une riche liste d'extensions ;
- 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 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 , sur .
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. Il 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 ; ;
- 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
de l'entreprise italienne Sorint.lab dans é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 :

Les dĂ©tails de la mise en Ćuvre de cet opĂ©rateur peuvent ĂȘtre consultĂ©s dans le rapport ou . 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 , 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
, 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 :

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 â 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 des Grafana et Prometheus prĂ©configurĂ©s sont Ă©galement envisagĂ©s. Dans la rĂ©cente une meilleure intĂ©gration avec le projet , 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Ă© â leur solution HA populaire pour PostgreSQL. L'approche de l'entreprise pour crĂ©er a Ă©tĂ© prĂ©sentĂ©e par l'un de ses auteurs â Alexey Klyukin â lors du , 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 pour la gestion,
- â pour les sauvegardes,
- â comme pool de connexions.
Voici comment est présentée l'architecture de l'opérateur de Zalando :

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. . En variante, vous pouvez également utiliser .
AprĂšs l'installation, il convient de se prĂ©occuper de la configuration . 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 , à 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 â . 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.

Liste des clusters PostgreSQL

Gestion des sauvegardes
Une autre caractéristique intéressante est la prise en charge de . 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 :
- absence de support pour nodeSelector;
- impossibilité de désactiver les sauvegardes;
- lors de l'utilisation de la fonction de création de bases, les privilÚges par défaut ne sont pas appliqués;
- 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 :
- il faut créer un secret;
- le transmettre à l'opérateur dans le paramÚtre
pod_environment_secret_namedans 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Ă© 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 , 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 ?

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 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 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 â , 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 , oĂč il est assemblĂ© avec des patches aussi utiles. Pour plus de commoditĂ©, nous avons Ă©galement .
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 , 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é 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. 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 à 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 :
- master â serveur source ;
- replica1 â rĂ©plique en streaming sur l'ancienne production ;
- 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 .
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
