Benutzer-Werkzeuge

Webseiten-Werkzeuge


it-wiki:kubernetes:postgresql_mit_zalando_bereitstellen

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
it-wiki:kubernetes:postgresql_mit_zalando_bereitstellen [2024/03/19 10:36] – [Zalando-Operator in Ihrem Cluster bereitstellen] markoit-wiki:kubernetes:postgresql_mit_zalando_bereitstellen [2024/04/25 05:31] (aktuell) marko
Zeile 1: Zeile 1:
-====== PostgreSQL mit Zalando in Kubernetes bereitstellen ======+====== PostgreSQL mit Zalando Operator in Kubernetes bereitstellen ======
 In dieser Anleitung erfahren Sie, wie Sie mit dem [[https://github.com/zalando/postgres-operator|Zalando Postgres-Operator]] Postgres-Cluster in bereitstellen. In dieser Anleitung erfahren Sie, wie Sie mit dem [[https://github.com/zalando/postgres-operator|Zalando Postgres-Operator]] Postgres-Cluster in bereitstellen.
  
Zeile 135: Zeile 135:
   * ''spec.volume'' sind die Parameter für den nichtflüchtigen Speicher   * ''spec.volume'' sind die Parameter für den nichtflüchtigen Speicher
   * ''spec.tolerations'' ist die Toleranz-Pod-Vorlage, mit der Cluster-Pods auf pool-postgres-Knoten geplant werden können   * ''spec.tolerations'' ist die Toleranz-Pod-Vorlage, mit der Cluster-Pods auf pool-postgres-Knoten geplant werden können
-  * ''spec.nodeAffinity'' ist die Pod-Vorlage nodeAffinity, die GKE mitteilt, dass Cluster-Pods lieber auf pool-postgres-Knoten geplant werden sollen.+  * ''spec.nodeAffinity'' ist die Pod-Vorlage nodeAffinity, die Kubernetes mitteilt, dass Cluster-Pods lieber auf pool-postgres-Knoten geplant werden sollen.
   * ''spec.resources'' sind Anfragen und Limits für Cluster-Pods   * ''spec.resources'' sind Anfragen und Limits für Cluster-Pods
   * ''spec.sidecars'' ist eine Liste der Sidecar-Container, die postgres-exporter enthält   * ''spec.sidecars'' ist eine Liste der Sidecar-Container, die postgres-exporter enthält
Zeile 142: Zeile 142:
  
 ===== Einfachen Postgres-Cluster erstellen ===== ===== Einfachen Postgres-Cluster erstellen =====
-  - Erstellen Sie mithilfe der grundlegenden Konfiguration einen neuen Postgres-Cluster: <code bash>kubectl apply -n postgres -f manifests/01-basic-cluster/my-cluster.yaml</code> Mit diesem Befehl wird eine benutzerdefinierte PostgreSQL-Ressource des Zalando-Operators erstellt: +  - Erstellen Sie mithilfe der grundlegenden Konfiguration einen neuen Postgres-Cluster: <code bash>kubectl apply -n postgres -f manifests/01-basic-cluster/my-cluster.yaml</code> Mit diesem Befehl wird eine benutzerdefinierte PostgreSQL-Ressource des Zalando-Operators erstellt:\\  * CPU- und Speicheranforderungen und -limits\\  * Markierungen und Affinitäten zum Verteilen der bereitgestellten Pod-Replikate auf Kubernetes-Knoten.\\ * Eine Datenbank\\ * Zwei Nutzer mit Datenbankinhaberberechtigungen\\ * Ein Nutzer ohne Berechtigungen 
-  * CPU- und Speicheranforderungen und -limits +  - Warten Sie, bis Kubernetes die erforderlichen Arbeitslasten gestartet hat: <code bash>kubectl wait pods -l cluster-name=my-cluster --for condition=Ready --timeout=300s -n postgres</code> Die Verarbeitung dieses Befehls kann einige Minuten dauern. 
-  * Markierungen und Affinitäten zum Verteilen der bereitgestellten Pod-Replikate auf GKE-Knoten. +  - Prüfen Sie, ob Kubernetes die Postgres-Arbeitslasten erstellt hat: <code bash>kubectl get pod,svc,statefulset,deploy,pdb,secret -n postgres</code> Die Ausgabe sieht in etwa so aus: <code bash>NAME                                    READY   STATUS  RESTARTS   AGE 
-  * Eine Datenbank +pod/my-cluster-0                        1/1     Running           6m41s 
-  * Zwei Nutzer mit Datenbankinhaberberechtigungen +pod/my-cluster-1                        1/1     Running           5m56s 
-  * Ein Nutzer ohne Berechtigungen+pod/my-cluster-2                        1/1     Running           5m16s 
 +pod/postgres-operator-db9667d4d-rgcs8   1/    Running           12m
  
-  - Warten Sie, bis Kubernetes die erforderlichen Arbeitslasten gestartet hat: <code bash>kubectl wait pods -cluster-name=my-cluster  --for condition=Ready --timeout=300s -n postgres</code> Die Verarbeitung dieses Befehls kann einige Minuten dauern+NAME                        TYPE        CLUSTER-IP  EXTERNAL-IP   PORT(S)   AGE 
-  - +service/my-cluster          ClusterIP   10.52.12.109   <none>       5432/TCP   6m43s 
 +service/my-cluster-config   ClusterIP   None        <none>      <none>  5m55s 
 +service/my-cluster-repl     ClusterIP   10.52.6.152 <none>      5432/TCP   6m43s 
 +service/postgres-operator   ClusterIP   10.52.8.176 <none>      8080/TCP   12m 
 + 
 +NAME                        READY   AGE 
 +statefulset.apps/my-cluster   3/  6m43s 
 + 
 +NAME                                READY   UP-TO-DATE   AVAILABLE   AGE 
 +deployment.apps/postgres-operator   1/                        12m 
 + 
 +NAME                                                MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE 
 +poddisruptionbudget.policy/postgres-my-cluster-pdb                N/A                               6m44s 
 + 
 +NAME                                                            TYPE                DATA   AGE 
 +secret/my-user.my-cluster.credentials.postgresql.acid.zalan.do  Opaque              2   6m45s 
 +secret/postgres.my-cluster.credentials.postgresql.acid.zalan.do   Opaque            2   6m44s 
 +secret/sh.helm.release.v1.postgres-operator.v1                  helm.sh/release.v1        12m 
 +secret/standby.my-cluster.credentials.postgresql.acid.zalan.do  Opaque              2   6m44s 
 +secret/zalando.my-cluster.credentials.postgresql.acid.zalan.do  Opaque              2   6m44s</code> 
 + 
 +Der Operator erstellt die folgenden Ressourcen: 
 +  * Ein Postgres-StatefulSet, das drei Pod-Replikate für Postgres steuert 
 +  * Einen ''PodDisruptionBudgets'', wodurch mindestens ein verfügbares Replikat garantiert wird 
 +  * Den ''my-cluster''-Dienst, der nur auf das Leader-Replikat ausgerichtet ist 
 +  * Den ''my-cluster-repl''-Dienst, der den Postgres-Port für eingehende Verbindungen und für die Replikation zwischen Postgres-Replikaten verfügbar macht 
 +  * Den monitorlosen Dienst ''my-cluster-config'' zum Abrufen der Liste der laufenden Postgres-Pod-Replikate 
 +  * Secrets mit Nutzeranmeldedaten für den Zugriff auf die Datenbank und die Replikation zwischen Postgres-Knoten 
 + 
 +===== Bei Postgres authentifizieren ===== 
 +Sie können Postgres-Nutzer erstellen und ihnen Datenbankberechtigungen zuweisen. Das folgende Manifest beschreibt beispielsweise eine benutzerdefinierte Ressource, die Nutzer und Rollen zuweist: 
 +<code yaml> 
 +apiVersion: "acid.zalan.do/v1" 
 +kind: postgresql 
 +metadata: 
 +  name: my-cluster 
 +spec: 
 +  ... 
 +  users: 
 +    mydatabaseowner: 
 +    superuser 
 +    - createdb 
 +    myuser: [] 
 +  databases: 
 +    mydatabase: mydatabaseowner 
 +</code> 
 + 
 +In diesem Manifest: 
 +  * Der ''mydatabaseowner''-Nutzer hat die Rollen [[https://www.postgresql.org/docs/16/sql-createrole.html|SUPERUSER und CREATEDB]], die uneingeschränkte Administratorrechte gewähren (Verwaltung der Postgres-Konfiguration, neue Datenbanken, Tabellen und Nutzer erstellen, usw). 
 +  * Dem Nutzer ''myuser'' wurden keine Rollen zugewiesen. Dies folgt der [[https://wiki.postgresql.org/wiki/Client_Authentication|Best Practice]] zur Verwendung von ''SUPERUSER'', um Nutzer mit den geringsten Berechtigungen zu erstellen. Detaillierte Rechte werden ''myuser'' von ''mydatabaseowner'' gewährt. Aus Sicherheitsgründen sollten Sie ''myuser''-Anmeldedaten nur für Clientanwendungen freigeben. 
 + 
 +===== Passwörter speichern ===== 
 +Verwenden Sie die [[https://www.postgresql.org/docs/current/auth-password.html|empfohlene Methode zum Speichern von Passwörtern]] ''scram-sha-256''. Das folgende Manifest beschreibt beispielsweise eine benutzerdefinierte Ressource, die die ''scram-sha-256''-Verschlüsselung mit dem Feld ''postgresql.parameters.password_encryption'' angibt: 
 +<code yaml> 
 +apiVersion: "acid.zalan.do/v1" 
 +kind: postgresql 
 +metadata: 
 +  name: my-cluster 
 +spec: 
 +  ... 
 +  postgresql: 
 +    parameters: 
 +      password_encryption: scram-sha-256 
 +</code> 
 + 
 +===== Nutzeranmeldedaten rotieren ===== 
 +Sie können [[https://postgres-operator.readthedocs.io/en/latest/administrator/#password-rotation-in-k8s-secrets|Nutzeranmeldedaten rotieren]], die in Kubernetes-Secrets mit Zalando gespeichert sind. Das folgende Manifest beschreibt beispielsweise eine benutzerdefinierte Ressource, die die Rotation von Nutzeranmeldedaten mithilfe des Felds ''usersWithSecretRotation'' definiert: 
 +<code yaml> 
 +apiVersion: "acid.zalan.do/v1" 
 +kind: postgresql 
 +metadata: 
 +  name: my-cluster 
 +spec: 
 +  ... 
 +  usersWithSecretRotation: 
 +  - myuser 
 +  - myanotheruser 
 +  - ... 
 +</code> 
 + 
 +===== Authentifizierungsbeispiel: Verbindung zu Postgres herstellen ===== 
 +In diesem Abschnitt erfahren Sie, wie Sie einen Postgres-Beispielclient bereitstellen und mit dem Passwort aus einem Kubernetes-Secret eine Verbindung zur Datenbank herstellen. 
 +  - Führen Sie den Client-Pod aus, um mit Ihrem Postgres-Cluster zu interagieren: <code bash>kubectl apply -n postgres -f manifests/02-auth/client-pod.yaml</code> Die Anmeldedaten der Nutzer myuser und mydatabaseowner werden aus den zugehörigen Secrets übernommen und als Umgebungsvariablen im Pod bereitgestellt. 
 +  - Stellen Sie eine Verbindung zum Pod her, wenn er bereit ist: <code bash>kubectl wait pod postgres-client --for=condition=Ready --timeout=300s -n postgres 
 +kubectl exec -it postgres-client -n postgres -- /bin/bash</code> 
 +  - Stellen Sie eine Verbindung zu Postgres her und versuchen Sie, eine neue Tabelle mit den myuser-Anmeldedaten zu erstellen: <code bash>PGPASSWORD=$CLIENTPASSWORD psql \ 
 +  -h my-cluster \ 
 +  -U $CLIENTUSERNAME \ 
 +  -d mydatabase \ 
 +  -c "CREATE TABLE test (id serial PRIMARY KEY, randomdata VARCHAR ( 50 ) NOT NULL);"</code> Der Befehl sollte mit einem Fehler wie diesem fehlschlagen: <code bash>ERROR:  permission denied for schema public 
 +LINE 1: CREATE TABLE test (id serial PRIMARY KEY, randomdata VARCHAR...</code> Der Befehl schlägt fehl, da sich Nutzer ohne zugewiesene Berechtigungen standardmäßig nur bei Postgres anmelden und Datenbanken auflisten können. 
 +  - Erstellen Sie eine Tabelle mit ''mydatabaseowner''-Anmeldedaten und gewähren Sie ''myuser'' **alle** Berechtigungen für die Tabelle: <code bash>PGPASSWORD=$OWNERPASSWORD psql \ 
 +  -h my-cluster \ 
 +  -U $OWNERUSERNAME \ 
 +  -d mydatabase \ 
 +  -c "CREATE TABLE test (id serial PRIMARY KEY, randomdata VARCHAR ( 50 ) NOT NULL);GRANT ALL ON test TO myuser;GRANT ALL ON SEQUENCE test_id_seq TO myuser;" </code> Die Ausgabe sieht in etwa so aus: <code bash>CREATE TABLE 
 +GRANT 
 +GRANT </code> 
 +  - Fügen Sie zufällige Daten mit den Anmeldedaten myuser in die Tabelle ein: <code bash>for i in {1..10}; do 
 +  DATA=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 13) 
 +  PGPASSWORD=$CLIENTPASSWORD psql \ 
 +  -h my-cluster \ 
 +  -U $CLIENTUSERNAME \ 
 +  -d mydatabase \ 
 +  -c "INSERT INTO test(randomdata) VALUES ('$DATA');" 
 +done</code> Die Ausgabe sieht in etwa so aus: <code bash>INSERT 0 1 
 +INSERT 0 1 
 +INSERT 0 1 
 +INSERT 0 1 
 +INSERT 0 1 
 +INSERT 0 1 
 +INSERT 0 1 
 +INSERT 0 1 
 +INSERT 0 1 
 +INSERT 0 1</code> 
 +  - Rufen Sie die eingefügten Werte ab: <code bash>PGPASSWORD=$CLIENTPASSWORD psql \ 
 +  -h my-cluster \ 
 +  -U $CLIENTUSERNAME \ 
 +  -d mydatabase \ 
 +  -c "SELECT * FROM test;"</code> Die Ausgabe sieht in etwa so aus: <code bash>id |  randomdata 
 +----+--------------- 
 +  1 | jup9HYsAjwtW4 
 +  2 | 9rLAyBlcpLgNT 
 +  3 | wcXSqxb5Yz75g 
 +  4 | KoDRSrx3muD6T 
 +  5 | b9atC7RPai7En 
 +  6 | 20d7kC8E6Vt1V 
 +  7 | GmgNxaWbkevGq 
 +  8 | BkTwFWH6hWC7r 
 +  9 | nkLXHclkaqkqy 
 + 10 | HEebZ9Lp71Nm3 
 +(10 rows)</code> 
 +  - Beenden Sie die Pod-Shell: <code bash>exit</code>
it-wiki/kubernetes/postgresql_mit_zalando_bereitstellen.1710844587.txt.gz · Zuletzt geändert: 2024/03/19 10:36 von marko