Eine kurze Tour durch PostgreSQL-Operatoren für Kubernetes, unsere Auswahlmöglichkeiten und Erfahrungen





Immer häufiger gehen folgende Anfragen von Kunden ein: „Wir wollen es wie Amazon RDS, aber billiger“; "Wir wollen es wie RDS, aber überall in jeder Infrastruktur." Um eine solche verwaltete Lösung auf Kubernetes zu implementieren, haben wir uns den aktuellen Status der beliebtesten Betreiber für PostgreSQL angesehen (Stolon, Betreiber von Crunchy Data und Zalando) und unsere Wahl getroffen.



Dieser Artikel ist unsere Erfahrung sowohl aus theoretischer Sicht (Überprüfung von Lösungen) als auch aus praktischer Sicht (was wurde ausgewählt und was kam daraus). Aber zuerst wollen wir herausfinden, welche allgemeinen Anforderungen für einen möglichen Ersatz für RDS gelten ...



Was ist RDS?



Wenn Leute über RDS sprechen, meinen sie nach unserer Erfahrung einen verwalteten DBMS-Service, der:



  1. leicht anpassbar;
  2. hat die Fähigkeit, mit Schnappschüssen zu arbeiten und diese wiederherzustellen (vorzugsweise mit PITR- Unterstützung );
  3. Ermöglicht das Erstellen von Master-Slave-Topologien.
  4. hat eine reichhaltige Liste von Erweiterungen;
  5. Bietet Auditing und Benutzer- / Zugriffsverwaltung.


Generell können die Ansätze zur Implementierung der Aufgabe sehr unterschiedlich sein, aber der Weg mit bedingtem Ansible liegt uns nicht nahe. (Eine ähnliche Schlussfolgerung wurde von Kollegen bei 2GIS gezogen, als sie versuchten , ein "Tool zur schnellen Bereitstellung eines auf Postgres basierenden Failover-Clusters" zu erstellen.)



Betreiber sind der allgemein akzeptierte Ansatz zur Lösung solcher Probleme im Kubernetes-Ökosystem. Weitere Einzelheiten zu Datenbanken, die in Kubernetes ausgeführt werden, wurden bereits von der Flant-Technologieabteilung mitgeteilt.destolin einem seiner Berichte .



NB : Um schnell einfache Operatoren zu erstellen, empfehlen wir Ihnen, auf unser Open Source - Dienstprogramm für Shell-Operatoren zu achten . Mit dieser Funktion können Sie dies ohne Kenntnis von Go tun, jedoch auf eine Weise, die Systemadministratoren besser bekannt ist: in Bash, Python usw.



Es gibt mehrere beliebte K8-Operatoren für PostgreSQL:



  • Stolon;
  • Crunchy Data PostgreSQL-Operator;
  • Zalando Postgres Betreiber.


Schauen wir sie uns genauer an.



Betreiberauswahl



Zusätzlich zu den oben bereits erwähnten wichtigen Funktionen haben wir als Infrastrukturbetriebsingenieure in Kubernetes von den Betreibern Folgendes erwartet:



  • Bereitstellung von Git und von benutzerdefinierten Ressourcen ;
  • Pod-Anti-Affinitäts-Unterstützung;
  • Installieren der Knotenaffinität oder des Knotenselektors;
  • Toleranzen einstellen;
  • Verfügbarkeit von Tuning-Möglichkeiten;
  • verständliche Technologien und sogar Befehle.


Ohne auf die einzelnen Punkte einzugehen (fragen Sie in den Kommentaren, wenn Sie nach dem Lesen des gesamten Artikels Fragen dazu haben), stelle ich im Allgemeinen fest, dass diese Parameter für eine detailliertere Beschreibung der Spezialisierung von Clusterknoten erforderlich sind, um sie für bestimmte Anwendungen zu bestellen. Auf diese Weise können wir das optimale Gleichgewicht zwischen Leistung und Kosten erreichen.



Nun zu den PostgreSQL-Operatoren selbst.



1. Stolon



Stolon vom italienischen Unternehmen Sorint.lab wurde im bereits erwähnten Bericht als eine Art Benchmark unter den Betreibern von DBMS angesehen. Dies ist ein ziemlich altes Projekt: Die erste Veröffentlichung fand bereits im November 2015 (!) Statt. Das GitHub-Repository verfügt über fast 3000 Sterne und mehr als 40 Mitwirkende.



In der Tat ist Stolon ein großartiges Beispiel für eine gut durchdachte Architektur:





Die Details des Geräts dieses Bedieners finden Sie im Bericht oder in der Projektdokumentation . Im Allgemeinen genügt es zu sagen, dass er alles Beschriebene tun kann: Failover, Proxys für transparenten Clientzugriff, Backups ... Darüber hinaus bieten Proxys den Zugriff über einen Endpunktdienst - im Gegensatz zu den beiden anderen unten beschriebenen Lösungen (sie verfügen über zwei Dienste für den Zugriff) Base).



Stolon verfügt jedoch nicht über benutzerdefinierte Ressourcen , weshalb es nicht so bereitgestellt werden kann, dass einfach und schnell - "wie heiße Kuchen" - DBMS-Instanzen in Kubernetes erstellt werden. Die Verwaltung erfolgt über das Dienstprogramm stolonctl, die Bereitstellung - über das Helm-Diagramm, und die Benutzereinstellungen werden in ConfigMap definiert.



Einerseits stellt sich heraus, dass der Operator nicht sehr ein Operator ist (schließlich verwendet er keine CRD). Andererseits handelt es sich um ein flexibles System, mit dem Sie Ressourcen in K8s nach Ihren Wünschen anpassen können.



Zusammenfassend schien es für uns persönlich nicht optimal, für jede Datenbank ein eigenes Diagramm zu erstellen. Deshalb suchten wir nach Alternativen.



2. Crunchy Data PostgreSQL-Operator



Der Betreiber von Crunchy Data , einem jungen amerikanischen Startup, schien eine logische Alternative zu sein. Die öffentliche Geschichte beginnt mit der ersten Veröffentlichung im März 2017, seitdem hat das GitHub-Repository knapp 1300 Sterne und mehr als 50 Mitwirkende erhalten. Die neueste Version vom September wurde getestet, um mit Kubernetes 1.15-1.18, OpenShift 3.11+ und 4.4+, GKE und VMware Enterprise PKS 1.3+ zu funktionieren.



Die Crunchy Data PostgreSQL Operator-Architektur erfüllt auch die angegebenen Anforderungen: Die







Verwaltung erfolgt über ein Dienstprogramm pgo, generiert jedoch wiederum benutzerdefinierte Ressourcen für Kubernetes. Daher hat uns der Betreiber als potenzielle Nutzer erfreut:



  • es gibt Kontrolle über CRD;
  • bequeme Benutzerverwaltung (auch über CRD);
  • Integration mit anderen Komponenten der Crunchy Data Container Suite - einer speziellen Sammlung von Container-Images für PostgreSQL und Dienstprogrammen für die Arbeit damit (einschließlich pgBackRest, pgAudit, Contrib-Erweiterungen usw.).


Versuche, den Operator von Crunchy Data aus zu verwenden, ergaben jedoch mehrere Probleme:



  • Es gab keine Möglichkeit von Toleranzen - nur nodeSelector wird bereitgestellt.
  • Die von uns erstellten Pods waren Teil der Bereitstellung, obwohl wir eine statusbehaftete Anwendung bereitgestellt haben. Im Gegensatz zu StatefulSets können Bereitstellungen keine Datenträger erstellen.


Der letzte Nachteil führt zu lustigen Momenten: In der Testumgebung konnten 3 Replikate mit einer lokalen Speicherplatte ausgeführt werden , wodurch der Bediener berichtete, dass 3 Replikate funktionierten (obwohl dies nicht der Fall war).



Ein weiteres Merkmal dieses Bedieners ist seine vorgefertigte Integration in verschiedene Hilfssysteme. Zum Beispiel ist es einfach, pgAdmin und pgBounce zu installieren, und die Dokumentation behandelt die vorkonfigurierten Grafana und Prometheus. In der jüngsten Version 4.5.0-beta1 wird die verbesserte Integration in das pgMonitor- Projekt separat erwähnt , wodurch der Bediener eine sofortige visuelle Visualisierung der Metriken für PgSQL bietet.



Die seltsame Auswahl der generierten Kubernetes-Ressourcen führte uns jedoch zu einer anderen Lösung.



3. Zalando Postgres Operator



Wir kennen Zalando-Produkte seit langem: Wir haben Erfahrung mit Zalenium und haben natürlich Patroni ausprobiert - die beliebte HA-Lösung für PostgreSQL. Einer seiner Autoren, Aleksey Klyukin, sprach am Postgres-Dienstag Nr. 5 über den Ansatz des Unternehmens zur Schaffung des Postgres-Betreibers , und es hat uns gefallen. Dies ist die jüngste im Artikel diskutierte Lösung: Die erste Veröffentlichung fand im August 2018 statt. Trotz der geringen Anzahl formeller Veröffentlichungen hat das Projekt einen langen Weg zurückgelegt und die Popularität der Lösung von Crunchy Data mit mehr als 1300 Sternen auf GitHub und der maximalen Anzahl von Mitwirkenden (70+) bereits übertroffen. Unter der Haube dieses Betreibers werden bewährte Lösungen verwendet:













So wird die Bedienerarchitektur von Zalando dargestellt:







Der Bediener wird vollständig über benutzerdefinierte Ressourcen verwaltet und erstellt automatisch ein StatefulSet aus Containern, das dann durch Hinzufügen verschiedener Seitenwagen zu den Pods angepasst werden kann. All dies ist ein bedeutendes Plus im Vergleich zum Betreiber von Crunchy Data.



Da es sich um die Zalando-Lösung handelte, die wir unter den drei in Betracht gezogenen Optionen ausgewählt haben, wird im Folgenden eine weitere Beschreibung ihrer Funktionen zusammen mit der Anwendungspraxis vorgestellt.



Übe mit Zalandos Postgres Operator



Das Bereitstellen eines Operators ist sehr einfach: Laden Sie einfach die aktuelle Version von GitHub herunter und wenden Sie die YAML-Dateien aus dem Manifests- Verzeichnis an . Alternativ können Sie auch OperatorHub verwenden .



Nach der Installation sollten Sie sich Gedanken über das Einrichten von Speichern für Protokolle und Sicherungen machen . Dies erfolgt über ConfigMap postgres-operatorin dem Namespace, in dem Sie die Anweisung installiert haben. Mit den konfigurierten Repositorys können Sie Ihren ersten PostgreSQL-Cluster bereitstellen.



Unsere Standardbereitstellung sieht beispielsweise folgendermaßen aus:



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


Dieses Manifest stellt einen Cluster von 3 Instanzen mit einem Beiwagen in Form von postgres_exporter bereit , aus dem wir Anwendungsmetriken entnehmen. Wie Sie sehen, ist alles sehr einfach, und wenn Sie möchten, können Sie buchstäblich eine unbegrenzte Anzahl von Clustern erstellen.



Es lohnt sich, auf das Webadministrationspanel - postgres-operator-ui - zu achten . Es wird mit dem Operator geliefert und ermöglicht Ihnen das Erstellen und Löschen von Clustern sowie das Arbeiten mit vom Operator erstellten Sicherungen. Verwaltung von





PostgreSQL-





Clusterlisten-Backups



Eine weitere interessante Funktion ist die Team-API- Unterstützung . Dieser Mechanismus erstellt automatisch Rollen in PostgreSQLbasierend auf der resultierenden Liste von Benutzernamen. Danach können Sie über die API eine Liste der Benutzer zurückgeben, für die Rollen automatisch erstellt werden.



Probleme und Lösungen



Die Verwendung des Bedieners ergab jedoch bald mehrere wesentliche Nachteile:



  1. mangelnde Unterstützung für nodeSelector;
  2. Unfähigkeit, Backups zu deaktivieren;
  3. Bei Verwendung der Datenbankerstellungsfunktion werden keine Standardberechtigungen angezeigt.
  4. In regelmäßigen Abständen ist nicht genügend Dokumentation vorhanden oder veraltet.


Glücklicherweise können viele von ihnen gelöst werden. Beginnen wir am Ende - Probleme mit der Dokumentation .



Höchstwahrscheinlich werden Sie feststellen, dass nicht immer klar ist, wie ein Backup registriert und ein Backup-Bucket mit der Benutzeroberfläche des Bedieners verbunden wird. Die Dokumentation spricht im Vorbeigehen darüber, aber die eigentliche Beschreibung findet sich in der PR :



  1. du musst ein Geheimnis machen;
  2. pod_environment_secret_name CRD ConfigMap ( , ).


Wie sich herausstellte, ist dies derzeit jedoch nicht möglich. Aus diesem Grund haben wir unsere eigene Version des Betreibers mit einigen zusätzlichen Entwicklungen von Drittanbietern zusammengestellt. Siehe unten für weitere Details.



Wenn Sie die Parameter für die Sicherung an den Bediener übergeben, nämlich die wal_s3_bucketZugriffsschlüssel in AWS S3, sichert er alles : nicht nur die Basen in der Produktion, sondern auch die Bereitstellung. Es passte nicht zu uns.



In der Beschreibung der Parameter an Spilo, den grundlegenden Docker-Wrapper für PgSQL bei Verwendung des Operators, stellte sich heraus, dass Sie den Parameter WAL_S3_BUCKETleer übergeben können, wodurch Sicherungen deaktiviert werden. Außerdem wurde zu unserer großen Freude eine fertige PR gefunden , die wir sofort in unsere Gabel aufgenommen haben. Jetzt reicht es aus, einfach den enableWALArchiving: falsePostgreSQL-Cluster zur Ressource hinzuzufügen .



Ja, es gab die Möglichkeit, dies anders zu machen, indem zwei Operatoren ausgeführt wurden: einer für die Bereitstellung (ohne Backups) und der zweite für die Produktion. Aber so konnten wir mit einem auskommen.



Ok, wir haben gelernt, wie man den Zugriff für S3 auf die Datenbanken überträgt, und Backups begannen, in den Speicher zu gelangen. Wie können Sicherungsseiten in der Benutzeroberfläche des Bedieners funktionieren?







In der Bediener-Benutzeroberfläche müssen Sie 3 Variablen hinzufügen:



  • SPILO_S3_BACKUP_BUCKET
  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY


Danach wird die Verwaltung von Backups verfügbar, was in unserem Fall die Arbeit mit dem Staging vereinfacht und es Ihnen ermöglicht, Slices aus der Produktion dort ohne zusätzliche Skripte zu liefern.



Als weiteres Plus wurden die Arbeit mit der Team-API und umfassende Möglichkeiten zum Erstellen von Basen und Rollen mithilfe von Operator-Tools genannt. Die erstellten Rollen hatten jedoch keine Standardrechte . Dementsprechend konnte ein Benutzer mit Leserechten die neuen Tabellen nicht lesen.



Warum so? Trotz der Tatsache, dass der Code die erforderlichen enthältGRANT , werden sie nicht immer verwendet. Es gibt 2 Methoden: syncPreparedDatabasesund syncDatabases. B syncPreparedDatabases- trotz der Tatsache, dass preparedDatabases es eine Bedingung in dem Abschnitt defaultRolesund gibtdefaultUsersZum Erstellen von Rollen werden die Standardrechte nicht angewendet. Wir bereiten gerade einen Patch vor, damit diese Rechte automatisch angewendet werden.



Und der letzte Moment in den Verbesserungen , die für uns relevant sind, ist ein Patch , der dem erstellten StatefulSet Node Affinity hinzufügt. Unsere Kunden ziehen es oft vor, die Kosten durch die Verwendung von Spot-Instanzen zu senken, und sie sollten Datenbankdienste eindeutig nicht hosten. Dieses Problem könnte durch Toleranzen gelöst werden, aber das Vorhandensein von Node Affinity gibt viel Vertrauen.



Was ist passiert?



Als Ergebnis der Lösung der oben genannten Probleme haben wir Postgres Operator von Zalando in unser Repository eingebunden , wo es mit solchen nützlichen Patches erstellt wird. Der Einfachheit halber haben wir auch ein Docker-Image zusammengestellt .



Forked PR-Liste:





Es ist großartig, wenn die Community diese PRs unterstützt, damit sie mit der nächsten Version des Operators (1.6) vorgelagert werden.



Bonus! Erfolgsgeschichte der Produktionsmigration



Wenn Sie Patroni verwenden, kann die Live-Produktion mit minimalen Ausfallzeiten auf den Bediener migriert werden.



Mit Spilo können Sie mit Wal-E Standby-Cluster über S3-Speicher erstellen, wenn das PgSQL-Binärprotokoll zuerst in S3 gespeichert und dann vom Replikat heruntergeladen wird. Aber was , wenn Sie nicht in Ihrem alten Infrastruktur Wal-E haben? Die Lösung für dieses Problem wurde bereits für Habré vorgeschlagen .



Die logische Replikation von PostgreSQL hilft. Wir werden jedoch nicht näher auf die Erstellung von Veröffentlichungen und Abonnements eingehen, da ... unser Plan fehlgeschlagen ist.



Tatsache ist, dass die Datenbank mehrere geladene Tabellen mit Millionen von Zeilen hatte, die außerdem ständig aufgefüllt und gelöscht wurden. Einfaches Abonnement mitcopy_dataWenn ein neues Replikat den gesamten Inhalt vom Master kopiert, hat es einfach nicht mit dem Master Schritt gehalten. Das Kopieren des Inhalts hat eine Woche lang funktioniert, aber den Master nie eingeholt. Infolgedessen hat ein Artikel von Kollegen von Avito zur Lösung des Problems beigetragen : Sie können Daten mithilfe von übertragen pg_dump. Ich werde unsere (leicht modifizierte) Version dieses Algorithmus beschreiben.



Die Idee ist, dass Sie ein Abonnement deaktivieren können, das an einen bestimmten Replikationssteckplatz gebunden ist, und dann die Transaktionsnummer festlegen können. Es gab Repliken für Produktionsarbeiten. Dies ist wichtig, da das Replikat dabei hilft, einen konsistenten Speicherauszug zu erstellen und weiterhin Änderungen vom Master zu erhalten.



In nachfolgenden Befehlen, die den Migrationsprozess beschreiben, werden die folgenden Hostnotationen verwendet:



  1. Master - Quellserver;
  2. replica1 - Streaming-Replik auf alte Produktion;
  3. replica2 ist eine neue logische Replik.


Migrationsplan



1. Erstellen Sie im Assistenten ein Abonnement für alle Tabellen im publicDatenbankschema dbname:



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


2. Erstellen Sie einen Replikationssteckplatz auf dem Master:



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


3. Beenden Sie die Replikation auf dem alten Replikat:



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


4. Holen Sie sich die Transaktionsnummer vom Master:



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


5. Lassen Sie uns die alte Replik sichern. Wir werden dies in mehreren Threads tun, um den Prozess zu beschleunigen:



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


6. Laden Sie den Speicherauszug auf den neuen Server hoch:



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


7. Nach dem Herunterladen des Speicherauszugs können Sie die Replikation auf dem Streaming-Replikat starten:



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


7. Erstellen Sie ein Abonnement für ein neues logisches Replikat:



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');"


8. oidAbonnements erhalten:



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


9. Nehmen wir an, es wurde empfangen oid=1000. Wenden wir die Transaktionsnummer auf das Abonnement an:



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


10. Beginnen wir mit der Replikation:



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


11. Überprüfen Sie den Abonnementstatus. Die Replikation sollte funktionieren:



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;"


12. Nachdem die Replikation gestartet und die Datenbanken synchronisiert wurden, können Sie umschalten.



13. Nach dem Deaktivieren der Replikation müssen Sie die Sequenzen korrigieren. Dies ist in einem Artikel auf wiki.postgresql.org gut dokumentiert .



Dank dieses Plans verlief die Umstellung mit minimalen Verzögerungen.



Fazit



Mit Kubernetes-Operatoren können Sie verschiedene Aktivitäten vereinfachen, indem Sie sie auf die Erstellung von K8-Ressourcen reduzieren. Nachdem Sie mit ihrer Hilfe eine bemerkenswerte Automatisierung erreicht haben, sollten Sie bedenken, dass dies eine Reihe unerwarteter Nuancen mit sich bringen kann. Wählen Sie Ihre Bediener daher mit Bedacht aus.



Nachdem wir die drei beliebtesten Kubernetes-Operatoren für PostgreSQL überprüft hatten, entschieden wir uns für ein Projekt von Zalando. Wir mussten einige Schwierigkeiten mit ihm überwinden, aber das Ergebnis war sehr erfreulich. Deshalb planen wir, diese Erfahrung auf einige andere PgSQL-Installationen auszudehnen. Wenn Sie Erfahrung mit ähnlichen Lösungen haben, freuen wir uns über die Details in den Kommentaren!



PS



Lesen Sie auch in unserem Blog:






All Articles