“Persistence is hard” - als Kubernetes Administrator ist man sich dieser Tatsache bewusst.
Datenbanken sind ein zentraler Bestandteil vieler Anwendungen und müssen zuverlässig und
sicher betrieben werden. Gerne hätte man Unterstützung, insbesondere wenn man viele Instanzen
erstellen und verwalten muss. Die Automatisierung von Datenbanken in Kubernetes ist eine
Herausforderung, die mit Operatoren gelöst werden kann. In diesem Artikel zeigen wir
am Beispiel des “Crunchy Data Postgres Operator”
, wie das gelingen kann.
Architektur
Das Ziel des Postgres-Operators von Crunchy Data (PGO) ist es, eine schnelle und unkomplizierte
Möglichkeit zu bieten, Anwendungen sowohl in Entwicklungs- als auch in Produktionsumgebungen
mit PostgreSQL zu betreiben. Das klingt interessant :-)
Um besser zu verstehen, wie PGO dies ermöglicht, sollte man sich die Architektur
des Operators ansehen.
PGO Architektur (Quelle: CrunchyData)
Der Crunchy PostgreSQL Operator erweitert Kubernetes um eine höhere Abstraktionsebene
für die einfachere Erstellung und Verwaltung von PostgreSQL-Clustern. Er nutzt „Custom Resources“
und definiert spezielle Custom Resource Definitions (CRDs), um sich selbst und die
erzeugten PostgreSQL-Cluster zu steuern.
PGO selbst läuft als Kubernetes-Deployment mit einem einzigen Container, dem Operator.
Der Operator verwendet dafür Kubernetes-Controller, die sämtliche Ereignisse auf Kubernetes-Ressourcen (Jobs, Pods)
sowie auf den Custom Resources (PostgresCluster, PGUpgrade) überwachen, und den gewünschten deklarierten
Zustand rekonsilieren.
Der PGO ist sehr leistungsfähig und kann hochverfügbare Cluster mit mehreren Replikas, Backup-Optionen (lokal & S3)
sowie Monitoring und Connection Pooling bereitstellen.
Installation
Der Start fällt dank der sehr guten Dokumentation leicht. Der Quickstart Guide
führt
durch die Installation des Postgres Operators bis hin zur Bereitstellung der ersten
Postgres-Datenbank.
Die einzige Voraussetzung ist ein Kubernetes-Cluster, der mit kubectl erreichbar ist.
Der Operator wird mit Helm oder kustomize installiert. Dafür sind nur wenige Schritte
erforderlich:
Beispiel-Repository mit Standard-Konfigurationen klonen:
git clone https://github.com/CrunchyData/postgres-operator-examples.git
cd postgres-operator-examples
Im Beispiel-Repo sind verschiedene Beispiel-Konfigurationen für das Deployment
des Operators und von Datenbanken via Helm oder Kustomize enthalten.
Installation des Operators im Namespace “postgres-operator” per Kustomize erfolgt mit:
Nach der Installation kann die erste Postgres-Datenbank erstellt werden. Dazu wird
eine Custom Resource Definition (CRD) verwendet, die die Konfiguration der Datenbank
beschreibt. Ein Beispiel für eine einfache Datenbank ist im Verzeichnis kustomize/postgres
enthalten:
kubectl apply -k kustomize/postgres
Im Endeffekt wird nur eine Custom Resource erstellt, die die Datenbank beschreibt.
Der Postgres Operator sorgt dafür, dass die Datenbank-Instanz erstellt wird und
weitere dafür notwendigen Ressourcen (Backup-Pod, ConfigMaps, Secrets, Services,PVCs, …)
bereitgestellt werden.
Wenn man den Operator mit Backup-Repo betreiben möchte, dann benötigt man mindestens
eine weitere Node, da der Repo-Container standardmäßig auf einer anderen Node als die Datenbank-Instanz
laufen muss. Alternativ kann die topology-spread-constraints
für die Backup-Repos entsprechend anpassen.
Kurz darauf sehen wir bereits die Container und Secrets in unserem Namespace “mynamespace” und können
unsere Datenbank verwenden.
Zugriff!
Um auf die Datenbank zugreifen zu können, starten wir z.B. einen Container, in dem wir dann
uns mit psql mit der Datenbank verbinden. Dazu mounten wir das vom Operator für unsere Datenbank-Instanz
erstellte Secret hippo-pguser-rhino und mappen sämtliche Schlüssel als Umgebungsvariablen, die wir dann
für das psql-Kommando verwenden können.
Und los geht’s - nun können wir mit unserer Datenbank-Instanz interagieren.
bash
%User auflisten
\du+% Datenbanken auflisten
\l
Wenn diese Kommandos funktionieren, dann kann auch eine Anwendung mit den Informationen
aus dem Secret auf die Datenbank zugreifen.
Nutzung des Public Schema
Bitte beachten: Postgres empfiehlt aus Sicherheitsgründen schon seit langem, die Berechtigungen
für das “public”-Schema zu entziehen. Mit Postgres 15 wurde diese Empfehlung zum Standardverhalten.
Diese Änderung erhöht die Sicherheit, bereitet aber Schwierigkeiten für diejenigen, die sich als Benutzer mit
der Datenbank verbinden und sofort versuchen, Tabellen zu erstellen.
Um ein Schema für den Benutzer einzurichten, kann das Feld spec.databaseInitSQL verwendet werden,
um per Init-SQL-Script entsprechende Schemas zu erstellen.
Man kann aber auch die Funktion zur automatischen Erstellung von User-Schemas verwenden, die
einfach per Annotation im CRD aktiviert werden kann. Weitere Informationen dazu finden sich im
User / Database Management Tutorial
.
Damit wird direkt beim Anlegen eines Benutzers ein Schema mit dem Namen des Benutzers erstellt,
das Postgres auch bevorzugt im search_path verwendet, wie folgendes Statement zeigt:
SHOW search_path;
search_path
-----------------
"$user", public
Konfiguration
Backup
Das Backup wird standardmäßig aktiviert und erfolgt via pgBackRest
. Die Konfiguration
ist im Backup Guide
beschrieben. Die Sicherung erfolgt mit einem separaten Container
und kann auf verschiedene Arten konfiguriert werden. So kann z.B. die Anzahl der Backups
und die Aufbewahrungsdauer festgelegt werden. Auch die Verschlüsselung der Backups ist
möglich. Die Konfiguration erfolgt über die Custom Resource Definition (CRD) des Operators.
Lange Zeit war es nicht möglich, z.B. für Test-Datenbanken auf ein Backup zu verzichten.
Optionales Backup
Ein relativ neues Feature der Version 5.7 ist das oft nachgefragte
“Optional Backup”.
Damit können Datenbanken von der Sicherung ausgeschlossen werden. Dies ist z.B. sinnvoll,
wenn eine Datenbank nur temporäre Daten enthält oder nicht gesichert werden soll, z.B. eine
Development-Datenbank. Die Konfiguration erfolgt ebenfalls über die CRD des Operators.
Weitere Informationen finden sich im Guide Optional Backup
.
Um unsere bereits deployte Beispieldatenbank (siehe oben) ohne Backup zu betreiben,
löschen wir den backup-Zweig aus der Spec und fügen eine Annotation hinzu,
die es dem Operator erlaubt, ein bestehendes Backup zu verwerfen.
Wenn eine Datenbank neu ohne Backup erstellt wird, ist diese Annotation nicht notwendig.
Natürlich ist das Betreiben einer Datenbank wesentlich mehr als nur das Erstellen
und Löschen von Datenbanken. Der Operator bietet viele Funktionen, die den täglichen
Betrieb von Datenbanken in Kubernetes erleichtern.
Dazu gehören:
Überwachung
Cluster-Management
Skalierung/Clustering
Konfigurationsänderungen
Versions-Upgrade
Migration
…
CrunchyData hat für diese Themen Tutorials für Day Two Operations
erstellt und
typische Fragestellungen mit zahlreichen Guides
dokumentiert. Dadurch zeigt sich
die eigentliche Stärke und Reife der Lösung.
Kubernetes - Helm Deployment
Neben der Möglichkeit, den Postgres Operator mittels kustomize zu installieren, bietet
CrunchyData auch ein Helm-Chart
an. Das Chart ist sehr flexibel und bietet viele
Konfigurationsmöglichkeiten.
Die Installation des Operators mit Helm ist etwas umständlich, da die Charts (nicht mehr?)
in einem Repository verfügbar sind. Stattdessen muss das Chart heruntergeladen und
z.B. als Dependency in das eigene Chart eingebunden werden. Die Standard-Values sind
für den Einstieg gut geeignet und lassen sich bei speziellen Anforderungen leicht anpassen.
CrunchyData stellt auch ein Helm-Chart für das Deployment von Datenbank-Instanzen bereit,
das in die Deployments der Anwendungen, die Postgres-Datenbanken benötigen, eingebunden
werden kann.
Bei der Installation des Operators mit Helm via ArgoCD kann beim Synchronisieren
der Custom Resource Definitions (CRDs) der Fehler “Too long: must have at most 262144 bytes” auftreten.
Dies liegt daran, dass Kubernetes eine Größenbeschränkung von 256 KB für Annotations hat.
Standardmäßig verwendet Argo CD Client-Side Apply, wodurch die Annotation last-applied-configuration
hinzugefügt wird, was bei umfangreichen CRDs dazu führen kann, dass diese Grenze überschritten wird.
Die empfohlene Lösung ist die Aktivierung von Server-Side Apply, das diese Annotation nicht hinzufügt.
Dies kann in Argo CD ab Version 2.5 durch Setzen der Sync-Option ServerSideApply=true erreicht werden.
Für frühere Versionen kann kubectl replace als Alternative verwendet werden, jedoch mit Vorsicht,
da es zu unerwarteten Ergebnissen führen kann, wenn mehrere Clients ein Objekt ändern.
In diesem Artikel
wird das Problem und die Lösung sehr gut beschrieben.
Fazit
Der Crunchy Data Postgres Operator ist ein ausgereiftes System, um Postgres-Datenbanken in
Kubernetes zu betreiben. Die Installation ist einfach und die Konfiguration erfolgt über
Custom Resource Definitions (CRDs). Der Operator bietet viele Funktionen, die das Betreiben
von Datenbanken in Kubernetes erleichtern. Die Dokumentation ist sehr gut und enthält viele
Beispiele und Tutorials. Der Operator ist eine gute Wahl für die Automatisierung von
Postgres-Datenbanken in Kubernetes.
Der Operator bietet Unterstützung für die Administration von Postgres-Datenbanken in Kubernetes
und verbirgt einen Großteil der Komplexität. Dennoch bleibt der stabile Betrieb einer (oder vieler!)
Datenbank/en eine Herausforderung und erfordert ein gewisses Maß an Erfahrung und Wissen.
Alex Bloss - Leiter attempto-Lab.
Kreativer Kopf, Innovator, kritischer Denker, Entwickler, praktischer Architekt, CTO, Trend Scout und neugieriger Entdecker mit mehr als zwanzig Jahren Erfahrung.
OpenSCAD ermöglicht die Erstellung komplexer Designs durch einfache Codezeilen. Statt visuell zu entwerfen, definiert man die Form durch Skripting, was dynamische und parametrisierbare Ansätze bietet.
Welche Auswirkungen hat die KI auf die Arbeit agiler Teams in der Software-Entwicklung? Werden wir durch Tools ergänzt oder übernimmt Agent Smith? Wir verschaffen uns einen Überblick über die aktuelle Entwicklung und Trends in der KI und wie agentenbasierten Workflows unsere Arbeit verändern könnten.