ADMIN

2022

09

2022-08-30T12:00:00

Datenbanken und Applikationen

SCHWERPUNKT

068

Datenbank

Container

Kubernetes

Datenbanken containerisieren und skalieren

Ab ins Körbchen!

von Andreas Stolzenberger

Veröffentlicht in Ausgabe 09/2022 - SCHWERPUNKT

Klassische Datenbanken gelten als "Stateful"-Applikationen und passen damit theoretisch nicht in Container. Wie es mit den SQL-Klassikern unter Kubernetes dann doch sehr gut klappt und welche Datenbankoptionen Anwender für Scale-Out-Umgebungen haben, verrät unser Workshop. Dabei gehen wir unter anderem auf die Rolle von StatefulSets und mögliche Failover-Setups ein.

Viele Unternehmen möchten alte, monolithische Applikationen hin zu Scale-Out-Architekturen mit Containern migrieren. Leider stellt sich dieser Schritt weitaus komplizierter dar, als vielen IT-Abteilungen lieb ist. Eine cloudnative Architektur setzt voraus, dass die verschiedenen Komponenten der Applikationen über einen Message-Bus miteinander kommunizieren und sich somit auf verschiedene Knoten verteilen und skalieren lassen. Die große Herausforderung für den Entwickler ist dabei die Frage: Wo sichert die Applikation dann ihre Datenbestände?
Bislang übernahmen vorwiegend SQL-Datenbanken diese Rolle. Allerdings können nur sehr wenige SQL-Implementierungen als Cluster in einer Scale-Out-Architektur arbeiten. Dem Anwendungsentwickler bleibt nun die Wahl: entweder die bestehende Datenbanktechnologie in einem Container betreiben oder auf eine Scale-Out-Datenbank umsteigen. Diese Wahl stellt sich allerdings nur großen Unternehmen mit einer eigenen Softwareentwicklung. KMU hingegen arbeiten eher mit fertigen Werkzeugen und müssen daher zwangsläufig eine der Datenbanken nutzen, die ihre Applikation unterstützt.
Und hier zeigen sich die Entwickler ein wenig unflexibel: Trotz der stetig steigenden Zahl von NoSQL-Datenbanken für Scale-Out-Architekturen unterstützen viele Webapplikationen nach wie vor nur eine oder mehrere klassische SQL-Datenbanken. Zu den populärsten zählen dabei MariaDB (MySQL), PostgreSQL und Microsoft SQL. Wir zeigen deshalb im folgenden Workshop, wie Sie diese SQL-Klassiker zuverlässig in Containerumgebungen mit Docker/Podman oder Kubernetes betreiben, stellen aber auch ein paar interessante NoSQL-Ansätze vor.
Viele Unternehmen möchten alte, monolithische Applikationen hin zu Scale-Out-Architekturen mit Containern migrieren. Leider stellt sich dieser Schritt weitaus komplizierter dar, als vielen IT-Abteilungen lieb ist. Eine cloudnative Architektur setzt voraus, dass die verschiedenen Komponenten der Applikationen über einen Message-Bus miteinander kommunizieren und sich somit auf verschiedene Knoten verteilen und skalieren lassen. Die große Herausforderung für den Entwickler ist dabei die Frage: Wo sichert die Applikation dann ihre Datenbestände?
Bislang übernahmen vorwiegend SQL-Datenbanken diese Rolle. Allerdings können nur sehr wenige SQL-Implementierungen als Cluster in einer Scale-Out-Architektur arbeiten. Dem Anwendungsentwickler bleibt nun die Wahl: entweder die bestehende Datenbanktechnologie in einem Container betreiben oder auf eine Scale-Out-Datenbank umsteigen. Diese Wahl stellt sich allerdings nur großen Unternehmen mit einer eigenen Softwareentwicklung. KMU hingegen arbeiten eher mit fertigen Werkzeugen und müssen daher zwangsläufig eine der Datenbanken nutzen, die ihre Applikation unterstützt.
Und hier zeigen sich die Entwickler ein wenig unflexibel: Trotz der stetig steigenden Zahl von NoSQL-Datenbanken für Scale-Out-Architekturen unterstützen viele Webapplikationen nach wie vor nur eine oder mehrere klassische SQL-Datenbanken. Zu den populärsten zählen dabei MariaDB (MySQL), PostgreSQL und Microsoft SQL. Wir zeigen deshalb im folgenden Workshop, wie Sie diese SQL-Klassiker zuverlässig in Containerumgebungen mit Docker/Podman oder Kubernetes betreiben, stellen aber auch ein paar interessante NoSQL-Ansätze vor.
Vertrauenswürdige Quellen
In einer richtigen Scale-Out-Applikation sollte der Ausfall eines einzelnen Containers keinen Einfluss auf die Applikation als solche haben. Daher gab es in frühen Implementierungen auch keine Funktion, um einem einzelnen Container persistenten, also nicht flüchtigen Massenspeicher zur Verfügung zu stellen. Die SQL-Klassiker betreiben den Datenbankserver aber in einem einzelnen Container und wenn der ausfällt, ist die Datenbank verloren.
Da hilft es nichts, dass die Container-Plattform den Container in Sekundenbruchteilen neu starten kann. Die Plattform muss also dem Container einen zuverlässigen Massenspeicher bereitstellen, auf dem er seine Daten lagert und der den Tod eines Containers überlebt. Dieser Storage wird dann in der Regel als Overlay in das Dateisystem des Containers an einer vorgegebenen Stelle wie "/var/lib/ mysql" eingeblendet. Das bedeutet auf der anderen Seite, dass das Container-Template der jeweiligen Datenbank die passende Logik mitbringt, um den Inhalt des persistenten Storage richtig auszuwerten.
Startet ein Container mit einem leeren persistenten Storage (und auch nur dann), muss das "Housekeeping" des Container-Templates die passende Verzeichnisstruktur erstellen. Läuft der Container mit einem bereits beschriebenen persistenten Storage an, liest die Applikation die Daten und Konfiguration vom Overlay. Dabei muss die Logik im Zweifelsfall auch Update- oder Reparaturprozesse starten. Stürzt ein DB-Container ab und korrumpiert dabei die Datenbankdateien, muss der neu startende Container die Konsistenz prüfen.
Auf der anderen Seite könnte der Anwender einen Container mit der Datenbankversion 9 stoppen und dafür einen mit Version 10 starten. Dieser prüft den Datenbestand auf seine Version und führt gegebenenfalls ein Update durch, ohne dabei Informationen zu beschädigen.
Der Anwender muss daher ganz genau aufpassen, woher er sein Container-Template bezieht oder wie er selbst eines baut. Die meisten DB-Serverhersteller bieten ein offizielles Container-Template über eine der bekannten Docker-/Kubernetes-Registries und GitHub an. Die Dokumentation gibt dabei genau vor, was im Template enthalten ist und wie es Update- und Recovery-Szenarien behandelt. Wer seine eigene Vorlage bauen möchte, sollte in den GitHub-Repositories der offiziellen Builds nachsehen, was deren "entrypoint.sh"-Skripte vor dem Start der Datenbank alles erledigen.
In kleinen Schritten zum Container
Wer Container auf einem einzelnen Knoten mit Docker oder Podman betreibt, gibt diesen in der Regel keine eigene IP-Adresse — zumindest keine, die für andere Rechner im Netzwerk sichtbar wäre. Das Port-Forwarding leitet einen oder mehrere IP-Ports des Containers auf Ports des Hostsystems. Ein MariaDB-Container kann somit seinen Port 3306 direkt auf den Hostport 3306 oder einen beliebigen anderen weitergeben.
Alternativ könnte der Anwender der Containerumgebung einen Bridge-Adapter zur Verfügung stellen. Die Container lassen sich dann wie virtuelle Maschinen direkt mit individuellen IP-Adressen verwalten. In so einer Umgebung ließe sich ein "dezidierter" Maria-DB-Container als Ersatz für eine MariaDB-VM in etwa so betreiben:
podman run \
      --name maria \
      --volume /var/pods/maria:/var/lib/mysql:Z \
      --net pub_net \
      --ip 192.168.1.10 \
      --mac-address 12:34:56:78:9a:bc \
docker.io/mariadb:latest
Das Verzeichnis des Hostsystems "/var/ pods/maria" nimmt die Datenbankdateien des Containers auf. Stürzt dieser ab, bleiben die Daten erhalten. Das Ganze funktioniert ohne Port-Forwarding. Das vom Administrator definierte "pub_net" arbeitet auf einer Netzwerkbridge. Damit erreichen alle Systeme des lokalen Netzwerks den Maria­DB-Container über seine IP-Adresse.
Hier verweisen wir auf das Image "maria­db:latest". Jeder Neustart des Containers kann dabei ein Update der Datenbank auslösen – auch über Major-Versionen. Für Produktionsumgebungen sollten Sie daher stets die MariaDB-Versionsnummer angeben und ein Update nur nach entsprechenden Tests vornehmen. Die Image-Tags lassen dabei zu, dass Sie nur die Major- oder Minor-Releases festlegen, also zum Beispiel "mariadb:10" oder "maria­db:10.8.3". Ein derartiger Aufbau mit einem "generischen" Datenbankserver, den viele Clients im LAN direkt ansprechen, kommt jedoch eher selten zum Einsatz. Weitaus öfter arbeitet ein Datenbankserver für nur eine einzige Applikation.
Kubernetes-Test-Setup mit Microshift
Als Kubernetes-Umgebung für Tests und Development eignet sich das simple Microshift. Richten Sie dazu einfach eine virtuelle EL8/ Centos-8-Streams/Fedora35-Maschine im Minimal-Setup mit zwei bis vier vCPUs und 4 bis 8 GByte RAM ein und schalten sie die Firewall aus. Dann sind es nur wenige Zeilen:dnf module enable -y cri-o:1.21dnf install -y cri-o cri-toolssystemctl enable crio –nowdnf copr enable -y @redhat-et/microshiftdnf install -y microshiftsystemctl enable microshift –nowWährend der Dienst startet und die benötigten Container-Images aus dem Internet zieht, laden Sie die oc/kubectl-Clients herunter:curl -O https://mirror.openshift.com/ pub/open-shift-v4/$(uname -m)/ clients/ocp/stable/openshift-client-linux.tar.gztar -xf openshift-client-linux.tar.gz -C /usr/local/bin oc kubectlPrüfen Sie, ob die Backend-Dienste laufen:crictl pssollte eine Liste an Containern zurückliefern. Wenn dies der Fall ist, kopieren Sie die Konfigurationsdatei in das Home-Verzeichnis des Nutzers:mkdir ~/.kubecat /var/lib/microshift/resources/kubeadmin/kubeconfig > ~/.kube/confMöchten Sie Ihren Kubernetes-Server von einem anderen System aus verwalten, etwa einer Windows-Workstation, kopieren Sie zunächst die angegebene kubeconfig-Datei auf das Clientsystem. Laden Sie die Datei in einen Editor und suchen Sie nach der Zeileserver: https://127.0.0.1:6443Ersetzen Sie "127.0.0.1" mit der externen IP-Adresse Ihrer VM. Die Zeile kommt mehrfach in der kubeconfig-Datei vor. Installieren Sie dann die nötigen kubectl/oc-Client-Tools für Ihre Workstation. Dann können Sie ihre Microshift-VM von Ihrer Arbeitsstation aus bedienen.
Bild 1: Das Kubernetes-StatefulSet von MariaDB hat den persistenten Storage erstellt und den Datenbankcontainer gestartet. Zudem läuft ein Webfrontend mit phpMyAdmin im Namespace.
Das zweite Beispiel zeigt, wie Sie einen MariaDB-Server auf Kubernetes laufen lassen (siehe Kasten "Kubernetes-Test-Setup mit Microshift"). Dazu nutzen Sie ein so genanntes StatefulSet. Das stellt sicher, dass eine Applikation mit einem "State" stets den passenden persistenten Storage zur Verfügung hat. Erzeugen Sie dazu die Datei "mariadb-state.yml" – sie beginnt mit dem Service. Beachten Sie, dass Sie die in diesem Workshop abgedruckten Listings in der korrekten Reihenfolge in einer einzigen YML-Datei zusammenfassen müssen.
---
apiVersion: v1
kind: Service
metadata:
      name: mariadb
      labels:
           app: mariadb
spec:
      type: NodePort
      ports:
      - port: 3306
         protocol: TCP
      selector:
         app: mariadb
Das deklariert den Datenbank-Port als "Service". Über diese Definition lassen sich dann andere Applikationen sehr einfach mit dem Datenbankserver verbinden.
Da es sich um einen Single-Node-Cluster handelt und wir den MariaDB-Container direkt ansprechen möchten, legen wir den Service als "NodePort" an. Kubernetes generiert dann ein automatisches Port-Mapping. Weiter geht es in der Datei mit einer ConfigMap:
---
apiVersion: v1
kind: ConfigMap
metadata:
      name: mariadb
      labels:
         app: mariadb
data:
      MYSQL_ROOT_PASSWORD: mysqlroot
      MYSQL_DATABASE: db1
      MYSQL_USER: mysqluser
      MYSQL_PASSWORD: mysqlpwd
Die als "data" angegebenen Werte entsprechen den Environment-Variable-Deklarationen ("-e"), die Sie unter Docker/ Podman auf der Kommandozeile übergeben. Allerdings stehen die Daten einer "ConfigMap" im Klartext in der Kubernetes-Konfiguration.
In einer produktiven Umgebung würden Sie die Passwörter separat als "Secret" definieren und damit verschlüsselt sichern. Jetzt kommt das eigentliche StatefulSet:
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
     name: mariadb
spec:
      serviceName: "mariadb"
      replicas: 1
      selector:
           matchLabels:
                app: mariadb
Das deklariert den Kubernetes- "Pod" mit Namen und Zahl der Replicas. Da Maria­DB (in dieser Konfiguration) keine Active-Active-Spiegelung unterstützt, läuft der Pod nur mit Replica 1. Das StatefulSet kümmert sich darum, dass zu jeder Zeit genau ein Pod läuft. Stürzt dieser aus irgendwelchen Gründen einmal ab, startet Kubernetes wie im Kasten "Neustart des MariaDB-Pods" ersichtlich automatisch binnen Sekunden einen neuen. Ein Pod kann einen oder mehrere Container enthalten, die stets zusammen laufen und nicht separat voneinander skalieren können. Meistens jedoch besteht ein Pod aus je einem Container – wie hier "mariadb:latest" – alternativ mit Angabe der Versionsnummer (siehe oben). Optional könnten Sie an dieser Stelle Quota-Regeln angeben, also wie viel RAM- und CPU-Anteile der Container maximal oder minimal bekommt. Die Environment-Variablen bezieht unser Pod aus der zuvor deklarierten ConfigMap. Wichtig an dieser Stelle ist der Volume-Mount-Punkt für das persistente Volume (PV):
volumeClaimTemplates:
- metadata:
         name: mariadb
    spec:
         accessModes: [ "ReadWriteOnce" ]
         resources:
          requests:
               storage: 10Gi
Aus dem "volumeClaimTemplate" generiert das StatefulSet automatisch einen "Persistent Volume Claim", der wiederum das PV erstellt und an den Pod bindet. Um das StatefulSet zu starten, erstellen Sie einfach einen Namespace (Projects) und führen die angegebene YML-Datei aus:
oc new-project mysql
oc create –f mariadb-state.yml
Wenn Sie nur den kubectl-Client verwenden, sieht das Kommando so aus:
kubectl create namespace mysql
kubectl apply –f mariadb-state.yml
Bild 2: Das phpMyAdmin-Frontend im Kubernetes-Mainspace der Datenbank kommuniziert über den Service mit dem MariaDB-Pod.
PostgreSQL und Microsoft SQL
Nach dem exakt gleichen Prinzip erzeugen Sie auch StatefulSets für PostgreSQL- oder Microsoft-SQL-Server in Containern.
Bei PostgreSQL nutzen Sie statt 3306 den Port 5432, das Image "postgresql:latest" oder "postgresql:14" und in die ConfigMap schreiben Sie beispielsweise:
data:
      POSTGRES_DB: postgresdb
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: test123
Microsoft liefert für den SQL-Server zwei unterschiedliche Images aus. Über die hauseigene Registry beziehen Sie via "mcr.microsoft.com/mssql/server" das aktuelle SQL-Server-Image auf Basis von Ubuntu, während der Link "mcr.microsoft.com/mssql/rhel/server" einen auf einen RHEL 8 (UBI8 = Universal Base Image 8) basierenden SQL-Server enthält. Der MS-SQL-Server nutzt den Port 1433. Bei der Config-Map müssen Sie auf ein kleines Detail achten:
data:
      ACCEPT_EULA: "Y"
      SA_PASSWORD: "<LangesPasswort>"
      MSSQL_PID: "Developer"
Der MS-SQL-Server verlangt ein langes Passwort mit acht Stellen oder mehr. Geben Sie hier wie im PGSQL-Beispiel nur "test123" an, stoppt die MS-Software den Container direkt nach dem Start und Sie landen in einer Crash-Schleife. Ebenso Pflicht ist die Variable "ACCEPT_EULA".
Listing 1: MariaDB-Pod-Neustart
template:     metadata:          labels:                app: mariadb     spec:          containers::          - name: mariadb           image: mariadb:latest           ports:           - containerPort: 3306             name: mariadb           volumeMounts:           - name: mariadb             mountPath: /var/lib/mysql           envFrom:           - configMapRef:             name: mariadb
Failover implementieren
Mit einem StatefulSet oder einem Kubernetes-Deployment brauchen Sie sich um die Verfügbarkeit der Applikation wenig Sorgen zu machen. Stürzt ein Datenbank-POD ab, startet Kubernetes binnen Sekunden einen neuen und verbindet ihn mit dem bestehenden persistenten Storage. In einem Kubernetes-Cluster deckt das natürlich auch den Absturz eines Hosts ab, wobei Kubernetes die neuen Pods dann auf einem anderen Knoten startet. Komplizierter Active-Passive-Konstrukte mit Quota- und Pacemaker-Regelwerk bedarf es nicht mehr.
Wie Sie die Datenbanken selbst vom persistenten Volume sichern, hängt vom Storage-Backend und Ihrer Sicherungsstrategie ab. Sie können beispielsweise einen Sidecar-Container (zweiter Container im selben POD) oder einen separaten POD im Read-Only-Modus auf das PV zugreifen lassen und von dort die physischen Dateien sichern. Das setzt voraus, dass Sie im Datenbank-POD selbst zu gegebenen Zeiten die DB stoppen, um die DB-Dateien auf dem Datenträger ordnungsgemäß zu schließen. Am besten funktionieren die bordeigenen Mittel, wie zeitlich getaktete DB-Dumps oder ein zweiter Pod, der als Replication-Receiver asynchron alle Transaktionen des ersten DB-Servers spiegelt. Für MariaDB [1] und PostgreSQL [2] gibt es hierzu gute Anleitungen im Internet.
Replikationsknoten eigenen sich dann auch für ein rudimentäres Scale-Out-Szenario. Via Replikation können Sie mehrere Read-Only-Spiegel-PODs der SQL-Datenbank starten, auf die dann Applikations-PODs zugreifen, die lediglich Lesezugriff zur Datenbank benötigen. Das entlastet den Haupt-Pod der Datenbank.
Scale-Out dimensionieren
Zu den wesentlichen Funktionen einer relationalen Datenbank gehören die in Echtzeit abgefragten Relationen zwischen den tabellarisch gesicherten Daten (Queries mit JOIN). Daher muss ein SQL-Server den kompletten Bestand der Datenbank auf dem abgefragten Knoten vorhalten. Konzepte wie Scale Out und "Data Sharding", bei dem Teile der Daten verteilt auf mehrere Knoten lagern und kein Knoten über alle Informationen verfügt, lassen sich hier nur schwer umsetzen.
Die nicht ganz so bekannte Datenbank "NuoDB" [3] beispielsweise verspricht volle SQL-Funktionalität mit Scale-Out-Architektur. Nuo setzt dabei auf zwei Knotentypen: Storage-Manager mit persistenten Volumes und Transaktionsknoten. Stark vereinfacht gesagt arbeiten die Transaktions-Nodes dabei als In-Memory-Cache der Storage-Knoten. Wenn Sie NuoDB testen wollen, finden Sie auf der Website des Projekts ein passendes Helm-Chart für die Community-Edition, die maximal drei Knoten erlaubt. Allerdings klappte das in unserer Testumgebung nur dann, wenn wir Microshift auf einer entsprechend großen Maschine laufen ließen – NuoDB setzt pro Knoten-POD 8 GByte RAM voraus. Richtiges Scale Out funktioniert daher bevorzugt mit NoSQL-Datenbanken. Diese arbeiten mit ganz unterschiedlichen Ansätzen, Daten- und Abfragestrukturen.
Cassandra: NoSQL mit Struktur
Das Open-Source-Project "Apache Cassandra" sichert die Daten wie ein SQL-Server in Tabellen. Für die Abfrage setzt es auf die eigene Query-Language "CQL" (Cassandra Query Language), die, wie der Name vermuten lässt, sich stark an SQL orientiert. Anders als dort gibt es in CQL aber keine Relationen und somit auch keine JOIN-Queries, die die Daten aus mehreren verknüpften Tabellen abfragen.
Somit kann Cassandra die Tabellen mit Redundanz auf mehrere Knoten verteilen. Stürzt ein einzelner Knoten ab, verteilt das System die verloren gegangenen Datenbestände aus den Redundanzen heraus neu. Fügt der Anwender weitere Knoten hinzu, gleicht das System die Tabellen passend zur Knotenzahl und den Redundanzvorgaben ebenfalls automatisch neu an. Ähnlich einer SQL-Datenbank setzt Cassandra aber strukturierte Daten und Datentypen voraus.
Cassandra eignet sich gut als SQL-Ablösung für Applikationen, die das Datenmanagement in der Applikation selbst erledigen und dazu keine "höheren" SQL-Funktionen wie JOIN benötigen. Wer mit den simplen CRUD-Funktionen (Create, Read, Update, Delete – im Deutschen auch als RUDI bezeichnet, mit Insert statt Create) allein klarkommt, kann seine Applikation recht simpel von SQL auf CQL umstellen und das Datenbank-Backend ändern.
Ein Cassandra-Cluster lässt sich problemlos über ein StatefulSet auf Kubernetes starten [4]. Mit der richtigen Konfiguration finden die Knoten automatisch zueinander und die Replika-Zahl bestimmt die Größe des Clusters. Möchten Sie Cassandra auf einem Testcluster wie dem beschriebenen Microshift ausprobieren, müssen Sie genug freies RAM mitbringen, denn Cassandra ist in Java geschrieben und hat einen guten Speicherhunger. Unser Setup lief auf einem alten Notebook mit Core i7 und 16 GByte RAM – das genügte.
Dokumentzentrisches NoSQL
Einen ganz anderen Ansatz verflgen dokumentzentrische Datenbanken wie Couchbase oder MongoDB. Anstelle strukturierter Tabellen sichern diese Datenbanken Informationen mit Keys und Values. Jedes Dokument könnte dabei prinzipiell jeweils eigene Keys verwenden. Diese NoSQL-Datenbanken fokussieren sich auf den Datensatz selbst und gelten deshalb als dokumentzentrisch, nicht tabellarisch. Zu den Schlüsseln gibt es Indizes, sodass die Datenbank die eingelagerten Daten auch wieder findet. Mithilfe einfacher, berechneter Hash-Werte können MongoDB und Couchbase ihre Dokumente mit Redundanz sehr einfach auf mehrere Knoten verteilen.
Das funktioniert dann prinzipiell wie GlusterFS [5] oder Ceph [6]. An die Stelle einer Query-Language rückt bei Dokumentdatenbanken die API des jeweiligen Herstellers. Eine einheitliche Abfragesprache gibt es nicht. Daher kommt es nur in Ausnahmefällen vor, dass Anwendungsentwickler mit einer bestehenden SQL-Anbindung ihre Applikation auf NoSQL umstellen. Dazu sind die Ansätze einfach zu verschieden.
Hingegen kommen die Entwickler moderner Webapplikationen recht flott und einfach mit dieser Art der Datenhaltung klar. Für jede moderne Programmiersprache existieren einfache Funktionsbibliotheken, die den Umgang mit Dokumentdatenbanken stark vereinfachen. Für den Anwendungsentwickler entfällt zudem der langwierige Prozess, im Vorfeld erst einmal eine Datentabellen- und Variablenstruktur zu erarbeiten.
Dennoch ist das Fehlen einer einheitlichen Query-Language für dokumentzentrische NoSQL-Datenbanken sicher einer der Gründe, warum sich diese Technologien nur schleppend als "generische" Datenbanken für Applikationen von der Stange etablieren. Wer sich diese Werkzeuge aus der Nähe ansehen will, muss im Internet nicht lange suchen. Für Couchbase gibt es ein vorgefertigtes Helm-Chart, das die Installation auf Kubernetes zum Kinderspiel macht [7].
Besondere Dienste
Zu den NoSQL-Datenbanken für den Allgemeinbedarf gesellen sich ein paar moderne Scale-Out-Datenbanken für spezielle Einsatzgebiete. Dazu zählt beispielsweise Elasticsearch, das ähnlich MongoDB eine Dokumentenstruktur aufweist und sich recht simpel über mehrere Knoten verteilt betreiben lässt. Elasticsearch liefert, wie der Name vermuten lässt, eine starke Suchfunktion mit. Daher kommt es sehr oft dort zum Einsatz, wo vergleichsweise unstrukturierte Daten (wie etwa Logdateien) gezielt nach Informationen durchsucht werden müssen.
Immer häufiger ersetzen Anwender in Applikationen mit wenig oder simplen Datenbeständen die Datenbank durch einfache Key/Value-Stores. Zu den populärsten gehört dabei aktuell sicher Redis. Vielen Scale-Out-Applikationen dient es als Kommunikationszentrale, sodass die PODs Daten und Konfigurationsinformationen untereinander austauschen. Redis arbeitet In-Memory, kann Daten aber auch in vorgegebenen Intervallen auf einen persistenten Storage ausgeben, sodass es nach einem POD-Neustart die Bestände zurücklädt.
Fazit
Mit Konzepten wie dem StatefulSet von Kubernetes sind klassische Datenbanken wie MariaDB, MS-SQL oder PostgreSQL in einer Containerumgebung passend aufgehoben. Kubernetes liefert dabei eine gute, wenn nicht sogar bessere Verfügbarkeit der Datenbank als ein aufwendiges Active-Passive-Failover-Konstrukt mit Pacemaker. Das setzt allerdings ein zuverlässiges Storage-Backend voraus. NoSQL-Datenbanken versprechen eine bessere Integration in Scale-Out-Umgebungen besonders bei Anwendungen mit großen, aber nicht zwangsweise zusammenhängenden Datenbeständen. Eine Migration bestehender SQL-Anwendungen hin zu NoSQL erscheint, mit Ausnahme von Cassandra, in den meisten Fällen zu aufwendig, da die Datenstrukturen sehr stark voneinander abweichen.
(ln)
Link-Codes
[2] PostgreSQL-Wiki: Streaming Replication: https://wiki.postgresql.org/wiki/Streaming_Replication/
[4] Deployment von Cassandra mittels StatefulSet: https://kubernetes.io/docs/tutorials/stateful-application/cassandra/
[5] "GlusterFS einrichten und nutzen" in IT-Administrator 06/2021: https://www.it-administrator.de/magazin/heftarchiv/artikel/352217.html
[6] "Storage mit Ceph" in IT-Administrator 06/2022: https://www.it-administrator.de/magazin/heftarchiv/artikel/378396.html