---
status: "accepted (Beispiel)"
date: 2026-11-13
decision-makers: "fiktive Rollen: Plattformverantwortliche, Leitung Anwendungsentwicklung"
consulted: "fiktive Rollen: Datenbankbetrieb, Sicherheit"
informed: "fiktive Rollen: Fachbereiche, Betrieb"
---
<!-- markdownlint-disable-next-line MD025 -->
# PostgreSQL-Hochverfügbarkeit: CloudNativePG vs. Patroni auf VMs

> **Beispiel-ADR, kein Kundenprojekt.** Dieses Dokument zeigt, wie SKAFFON Architekturentscheidungen im Format [MADR 4.0.0](https://adr.github.io/madr/) festhält. Kontext, Annahmen und Rollen sind **fiktiv**. Die technischen Aussagen zu den Werkzeugen stützen sich auf die verlinkte Projektdokumentation (Stand der Prüfung: 13. November 2026). Die Entscheidung gilt nur unter den genannten Annahmen und ist keine allgemeine Empfehlung.

## Context and Problem Statement

Angenommen wird eine fachliche Anwendung mit PostgreSQL als führendem Datenspeicher. Die Anwendung läuft bereits auf einer produktiv betriebenen Kubernetes-Plattform mit drei Verfügbarkeitszonen; Deployments laufen über GitOps. Die Datenbank soll beim Ausfall eines Knotens oder einer Zone automatisch auf eine Replika umschalten, und Datenfehler (zum Beispiel versehentliches Löschen) sollen sich per Point-in-Time-Recovery (PITR) zurückdrehen lassen. Konkrete Wiederanlaufziele (RPO/RTO) sind im Beispiel nicht festgelegt; sie würden im realen Projekt aus Geschäftssicht festgelegt und per Restore-Test belegt.

Wie betreiben wir die Hochverfügbarkeit der PostgreSQL-Datenbank: deklarativ per Operator auf Kubernetes (CloudNativePG) oder klassisch auf virtuellen Maschinen mit Patroni?

## Decision Drivers

* **Plattformpassung:** Die Anwendung und das Team arbeiten bereits mit Kubernetes und GitOps; ein zweites Betriebsmodell erzeugt Aufwand.
* **Sichere Umschaltung:** Genau ein Primary; definierter Umgang mit Split-Brain-Situationen.
* **Backup und PITR:** Kontinuierliche WAL-Archivierung, Wiederherstellung auf einen Zeitpunkt, wiederholbarer Restore-Test.
* **Betriebsaufwand und Know-how:** Welche Fähigkeiten braucht das Team, wie viele bewegliche Teile gibt es?
* **Zonenausfall:** Betrieb über drei Zonen ohne manuellen Eingriff.
* **Offenheit und Portabilität:** Standard-PostgreSQL, keine herstellerspezifische Datenbank-Engine, überprüfbare Open-Source-Werkzeuge.
* **Disaster Recovery über Standorte hinweg:** Optionen für eine zweite Region oder ein zweites Rechenzentrum.

## Considered Options

* CloudNativePG (Kubernetes-Operator)
* Patroni auf virtuellen Maschinen (mit etcd, Verbindungsschicht und pgBackRest)

## Decision Outcome

Gewählte Option: „CloudNativePG (Kubernetes-Operator)“, weil unter den angenommenen Randbedingungen (bestehende Kubernetes-Plattform mit drei Zonen, GitOps, Team mit Kubernetes-Erfahrung) die Hochverfügbarkeit ohne zusätzliches Koordinationssystem und ohne zweites Betriebsmodell erreicht wird und Konfiguration, Rollen, Backup-Zeitplan und Topologie deklarativ im Repository liegen.

Die Entscheidung ist **an die Annahmen gebunden**. Läge die Datenbank auf vorhandenen VMs ohne Kubernetes-Betrieb im Team, würde die Abwägung zugunsten von Patroni ausfallen.

### Consequences

* Good, because die Hochverfügbarkeit nutzt laut Projektdokumentation die Kubernetes-API direkt und braucht keinen separaten Konsensspeicher wie etcd, Consul oder ZooKeeper.
* Good, because der Operator Dienste für lesenden und schreibenden Zugriff bereitstellt (Read-Write-Service auf den Primary, Read-Only-Service auf Replikas). Eine eigene Verbindungsschicht für das Routing zum Primary entfällt.
* Good, because Topologie, Instanzzahl, Rollen, Backup-Zeitplan und PostgreSQL-Parameter als Kubernetes-Ressourcen im Git-Repository versioniert und per GitOps ausgerollt werden.
* Good, because die Dokumentation für Produktion mehrere Zonen (drei oder mehr) empfiehlt und der Operator den Lebenszyklus des Clusters über die Zonen hinweg steuert.
* Bad, because das Team Kubernetes-Betrieb (Storage-Klassen, Knoten-Scheduling, Operator-Upgrades) sicher beherrschen muss. Die Dokumentation empfiehlt, Produktions-Datenbanken auf dafür reservierten Worker-Knoten zu betreiben; das kostet Kapazität.
* Bad, because ein automatisches Failover **zwischen** Kubernetes-Clustern nicht im Umfang des Operators liegt; die Dokumentation beschreibt dafür eine manuelle oder von einem übergeordneten Werkzeug koordinierte Umschaltung („Replica Cluster“). Disaster-Recovery-Szenarien über zwei Standorte müssen daher gesondert entworfen und geübt werden.
* Bad, because der native Backup-Pfad des Operators veraltet ist: Laut Dokumentation sind Barman-Cloud-Backups im Kernbetrieb seit Version 1.26 zugunsten des Barman-Cloud-Plugins (CNPG-I) abgekündigt, Version 1.31 ist die letzte Minor-Version mit nativer Unterstützung. Neue Installationen sollten daher gleich das Plugin einsetzen, und das Plugin ist ein zusätzlicher Bestandteil, der mit dem Operator versioniert und betrieben werden muss.

### Confirmation

* Architektur-Review des Cluster-Manifests gegen diese Entscheidung (drei Instanzen, Verteilung auf drei Zonen und getrennte Knoten, WAL-Archivierung aktiv).
* Regelmäßiger **Failover-Test** (Primary-Pod löschen, später Knoten-Ausfall simulieren) mit gemessener Umschaltdauer, dokumentiert im Betriebsbericht.
* Regelmäßiger **Restore-Test** (PITR in einen neuen, getrennten Cluster) mit gemessener Wiederherstellungsdauer; daraus wird abgeleitet, ob die vereinbarten Ziele erreichbar sind.
* Prüfung vor jedem Operator-Upgrade, ob der verwendete Backup-Pfad weiter unterstützt wird (Release-Hinweise des Projekts).

## Pros and Cons of the Options

### CloudNativePG (Kubernetes-Operator)

[CloudNativePG](https://cloudnative-pg.io/) ist ein Kubernetes-Operator für PostgreSQL und laut Projektdokumentation ein Projekt der Cloud Native Computing Foundation in der Stufe „Incubating“. Replikation erfolgt über die in PostgreSQL eingebaute physische Streaming-Replikation (asynchron, optional synchron beziehungsweise quorum-basiert). Vgl. [Architektur](https://cloudnative-pg.io/docs/current/architecture/), [automatisches Failover](https://cloudnative-pg.io/docs/current/failover/), [Backup](https://cloudnative-pg.io/docs/current/backup/).

* Good, because kein externer Konsensspeicher und keine separate Verbindungsschicht nötig sind.
* Good, because der Failover laut Dokumentation zweistufig abläuft: Der gestörte Primary wird zuerst heruntergefahren, damit die Replikas keine WAL mehr empfangen; erst danach wird ein neuer Primary bestimmt. Das soll Zeitlinien-Abweichungen zwischen altem und neuem Primary vermeiden.
* Good, because Backups mit WAL-Archivierung und PITR über das Barman-Cloud-Plugin in Objektspeicher oder über Kubernetes-Volume-Snapshots möglich sind; Backups können von einer Replika erfolgen, um den Primary zu entlasten.
* Good, because sich Replica-Cluster in anderen Kubernetes-Clustern für Disaster Recovery deklarativ beschreiben lassen.
* Neutral, because die Wiederanlaufziele von Replikationsmodus, Backup-Rhythmus, Speicher und Datenvolumen abhängen und gemessen, nicht angenommen werden.
* Bad, because ein Kubernetes-Betrieb Voraussetzung ist und der Operator ein zusätzliches, zu aktualisierendes Plattform-Bauteil darstellt.
* Bad, because Backup-Fähigkeiten in Plugins verlagert werden (siehe Consequences).

### Patroni auf virtuellen Maschinen

[Patroni](https://patroni.readthedocs.io/) ist laut Dokumentation eine Vorlage („template“) für PostgreSQL-HA-Lösungen in Python. Der Primary wird über einen verteilten Konsensspeicher (DCS) bestimmt; unterstützt werden etcd, Consul, ZooKeeper, Exhibitor, Kubernetes und ein Raft-Modus (vgl. [README](https://github.com/patroni/patroni/blob/master/README.rst)). Die Dokumentation fordert für das DCS drei oder fünf Knoten. Patroni bietet eine REST-API, die unter anderem Lastverteiler wie HAProxy für Health-Checks nutzen, und optional einen Watchdog als zusätzliche Schutzebene gegen Split-Brain ([Watchdog](https://patroni.readthedocs.io/en/latest/watchdog.html), [REST-API](https://patroni.readthedocs.io/en/latest/rest_api.html)). Für Backups wird üblicherweise ein separates Werkzeug wie [pgBackRest](https://pgbackrest.org/) eingesetzt.

* Good, because der Ansatz ausgereift und unabhängig von Kubernetes ist und auf vorhandenen VMs, auch außerhalb von Cloud-Umgebungen, funktioniert.
* Good, because Patroni viele Stellschrauben bietet, etwa die Begrenzung des Replikationsverzugs für Failover-Kandidaten (`maximum_lag_on_failover`) und den optionalen synchronen Modus.
* Good, because pgBackRest vollständige, differenzielle und inkrementelle Backups mit WAL-Archivierung abdeckt und Patroni Replikas aus solchen Backups aufbauen kann (benutzerdefinierte Bootstrap-Methoden).
* Neutral, because Patroni auch nativ auf Kubernetes läuft (Kubernetes als DCS). Diese Variante ist in diesem ADR nicht bewertet.
* Bad, because mehrere Komponenten selbst zu bauen, zu überwachen und zu aktualisieren sind: Patroni, ein DCS-Cluster mit mindestens drei Knoten, eine Verbindungsschicht, das Backup-Werkzeug und die VM-Basis.
* Bad, because die Dokumentation festhält, dass das Testen einer HA-Lösung in der Verantwortung des Betreibers liegt; zur Umschaltung über zwei Rechenzentren mit asynchroner Replikation beschreibt sie eine manuelle Promotion (automatische Promotion sei dort nicht möglich).
* Bad, because deklaratives GitOps hier nur über zusätzliche Automatisierung (zum Beispiel Konfigurationsmanagement) erreicht wird.

## More Information

* Diese Entscheidung ist zu überprüfen, wenn sich die Annahmen ändern: Wegfall der Kubernetes-Plattform, Anforderung automatischen Failovers zwischen zwei Standorten, oder wenn die Abkündigung des nativen Backup-Pfads beziehungsweise Änderungen am Plugin-Modell die Betriebsweise berühren.
* Replikation ersetzt kein Backup: Sie schützt vor dem Ausfall eines Knotens, nicht vor Datenfehlern. Beide Optionen setzen eine getrennte Backup- und WAL-Archivierung mit getestetem Restore voraus.
* Verwandte Leistung: [Managed PostgreSQL](https://skaffon.de/managed-services/managed-postgresql/).
* Quellen (geprüft am 13. November 2026): [CloudNativePG-Dokumentation](https://cloudnative-pg.io/docs/current/), [Patroni-Dokumentation](https://patroni.readthedocs.io/), [PostgreSQL-Dokumentation zu Hochverfügbarkeit und Replikation](https://www.postgresql.org/docs/current/high-availability.html).
