Aufbau eines hochverfügbaren PostgreSQL-Clusters mit Patroni, etcd, HAProxy

Es hat sich ergeben, dass ich zum Zeitpunkt der Aufgabenerstellung nicht über ausreichende Erfahrung verfügte, um diese Lösung allein zu entwickeln und zu implementieren. Also begann ich zu googeln.

Ich weiß nicht, woran es liegt, aber immer wieder stelle ich fest, dass es selbst, wenn ich alles Schritt für Schritt wie im Tutorial mache und die gleiche Umgebung wie der Autor vorbereite, letztendlich nie funktioniert. Ich habe keine Ahnung, woran das liegt, aber als ich erneut damit konfrontiert wurde, beschloss ich — ich schreibe mein eigenes Tutorial, wenn alles funktioniert. Eines, das definitiv funktionieren wird.

Anleitungen im Internet

Es hat sich ergeben, dass das Internet nicht an einer Vielzahl von Anleitungen, Tutorials, Schritt-für-Schritt-Anleitungen und ähnlichen Dingen leidet. Es hat sich ergeben, dass ich die Aufgabe erhalten habe, eine Lösung für die bequeme Organisation und den Aufbau eines ausfallsicheren PostgreSQL-Clusters zu entwickeln, wobei die Hauptanforderungen die Streaming-Replikation vom Master-Server auf alle Replikate und die automatische Übergabe im Falle eines Ausfalls des Master-Servers waren.

In dieser Phase wurde der Technologie-Stack definiert:

  • PostgreSQL als DBMS
  • Patroni als Lösung für die Clusterbildung
  • etcd als verteiltes Speichersystem für Patroni
  • HAproxy zur Schaffung eines gemeinsamen Zugangspunkts für Anwendungen, die die Datenbank nutzen.

Installation

Wir präsentieren den Aufbau eines PostgreSQL-Hochverfügbarkeitsclusters unter Verwendung von Patroni, etcd, HAProxy.

Alle Operationen wurden auf virtuellen Maschinen mit installiertem Debian 10 durchgeführt.

im entsprechenden Docker-Image

Ich empfehle nicht, etcd auf denselben Maschinen zu installieren, auf denen sich patroni und postgresql befinden, da die Belastung der Festplatten für etcd sehr wichtig ist. Aber zu Ausbildungszwecken werden wir es genau so machen.
Lassen Sie uns etcd installieren.

#!/bin/bash
apt-get update
apt-get install etcd

Fügen Sie den Inhalt in die Datei /etc/default/etcd ein

[member]

ETCD_NAME=datanode1 # Hostname Ihres Geräts
ETCD_DATA_DIR=„/var/lib/etcd/default.etcd“

ALLE IP-ADRESSEN SOLLTEN GÜLTIG SEIN. LISTER PEER, CLIENT usw. SOLLTEN AUF DIE IP-ADRESSE DES HOSTS EINGESTELLT WERDEN.

ETCD_LISTEN_PEER_URLS=„http://192.168.0.143:2380„ # Adresse Ihres Geräts
ETCD_LISTEN_CLIENT_URLS=„http://192.168.0.143:2379,http://127.0.0.1:2379„ # Adresse Ihres Geräts

[cluster]

ETCD_INITIAL_ADVERTISE_PEER_URLS=„http://192.168.0.143:2380„ # Adresse Ihres Geräts
ETCD_INITIAL_CLUSTER=„datanode1=http://192.168.0.143:2380,datanode2=http://192.168.0.144:2380,datanode3=http://192.168.0.145:2380„ # Adressen aller Maschinen im etcd-Cluster
ETCD_INITIAL_CLUSTER_STATE=„new“
ETCD_INITIAL_CLUSTER_TOKEN=„etcd-cluster-1“
ETCD_ADVERTISE_CLIENT_URLS=„http://192.168.0.143:2379„ # Adresse Ihres Geräts

Führen Sie den Befehl aus

systemctl restart etcd

PostgreSQL 9.6 + patroni

Das Erste, was Sie tun müssen, ist, drei virtuelle Maschinen einzurichten, um die erforderliche Software darauf zu installieren. Nach der Installation der Maschinen können Sie, wenn Sie meinem Tutorial folgen, dieses einfache Skript ausführen, das (fast) alles für Sie erledigt. Es wird unter root gestartet.

Bitte beachten Sie, dass das Skript die Version PostgreSQL 9.6 verwendet, was auf die internen Anforderungen unseres Unternehmens zurückzuführen ist. Die Lösung wurde nicht auf anderen Versionen von PostgreSQL getestet.

#!/bin/bash
apt-get install gnupg -y
echo "deb http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main" >> /etc/apt/sources.list
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
apt-get update
apt-get install postgresql-9.6 python3-pip python3-dev libpq-dev -y
systemctl stop postgresql
pip3 install --upgrade pip
pip install psycopg2
pip install patroni[etcd]
echo "
[Unit]
Description=Runners to orchestrate a high-availability PostgreSQL
After=syslog.target network.target

[Service]
Type=simple

User=postgres
Group=postgres

ExecStart=/usr/local/bin/patroni /etc/patroni.yml

KillMode=process

TimeoutSec=30

Restart=no

[Install]
WantedBy=multi-user.targ
" > /etc/systemd/system/patroni.service
mkdir -p /data/patroni
chown postgres:postgres /data/patroni
chmod 700 /data/patroniпо
touch /etc/patroni.yml

Als nächstes müssen Sie den gerade erstellten Datei /etc/patroni.yml den folgenden Inhalt hinzufügen, wobei Sie selbstverständlich die IP-Adressen an allen Stellen durch Ihre eigenen ersetzen.
Achten Sie auf die Kommentare in diesem YAML. Ändern Sie die Adressen in Ihre eigenen auf jeder Maschine des Clusters.

/etc/patroni.yml

scope: pgsql # muss auf allen Knoten gleich sein
namespace: /cluster/ # muss auf allen Knoten gleich sein
name: postgres1 # muss auf allen Knoten unterschiedlich sein

restapi:
    listen: 192.168.0.143:8008 # Adresse des Knotens, an dem sich diese Datei befindet
    connect_address: 192.168.0.143:8008 # Adresse des Knotens, an dem sich diese Datei befindet

etcd:
    hosts: 192.168.0.143:2379,192.168.0.144:2379,192.168.0.145:2379 # listen Sie hier alle Ihre Knoten auf, falls Sie etcd auch auf diesen installieren

# dieser Abschnitt (bootstrap) wird in Etcd:///config geschrieben, nachdem ein neuer Cluster initialisiert wurde
# und alle anderen Cluster-Mitglieder werden es als `global configuration` verwenden
bootstrap:
    dcs:
        ttl: 100
        loop_wait: 10
        retry_timeout: 10
        maximum_lag_on_failover: 1048576
        postgresql:
            use_pg_rewind: true
            use_slots: true
            parameters:
                    wal_level: replica
                    hot_standby: "on"
                    wal_keep_segments: 5120
                    max_wal_senders: 5
                    max_replication_slots: 5
                    checkpoint_timeout: 30

    initdb:
    - encoding: UTF8
    - data-checksums
    - locale: de_DE.UTF8
    # die init pg_hba.conf muss die Adressen ALLER Maschinen enthalten, die im Cluster verwendet werden
    pg_hba:
    - host replication postgres ::1/128 md5
    - host replication postgres 127.0.0.1/8 md5
    - host replication postgres 192.168.0.143/24 md5
    - host replication postgres 192.168.0.144/24 md5
    - host replication postgres 192.168.0.145/24 md5
    - host all all 0.0.0.0/0 md5

    users:
        admin:
            password: admin
            options:
                - createrole
                - createdb

postgresql:
    listen: 192.168.0.143:5432 # Adresse des Knotens, an dem sich diese Datei befindet
    connect_address: 192.168.0.143:5432 # Adresse des Knotens, an dem sich diese Datei befindet
    data_dir: /data/patroni # dieses Verzeichnis wird von dem oben beschriebenen Skript erstellt und die erforderlichen Berechtigungen gesetzt
    bin_dir:  /usr/lib/postgresql/9.6/bin # geben Sie den Pfad zu Ihrem Verzeichnis mit postgresql an
    pgpass: /tmp/pgpass
    authentication:
        replication:
            username: postgres
            password: postgres
        superuser:
            username: postgres
            password: postgres
    create_replica_methods:
        basebackup:
            checkpoint: 'fast'
    parameters:
        unix_socket_directories: '.'

tags:
    nofailover: false
    noloadbalance: false
    clonefrom: false
    nosync: false

Das Skript muss auf allen drei Maschinen des Clusters ausgeführt werden, ebenso muss die bereitgestellte Konfiguration in die Datei /etc/patroni.yml auf allen Maschinen eingefügt werden.

Nachdem Sie diese Schritte auf allen Maschinen des Clusters ausgeführt haben, führen Sie den folgenden Befehl auf einer von ihnen aus.

systemctl start patroni
systemctl start postgresql

Warten Sie etwa 30 Sekunden, und führen Sie dann diesen Befehl auf den anderen Maschinen des Clusters aus.

HAproxy

Wir verwenden das großartige HAproxy, um einen einheitlichen Zugangspunkt bereitzustellen. Der Master-Server wird immer unter der Adresse der Maschine verfügbar sein, auf der HAproxy bereitgestellt ist.

Um zu verhindern, dass die Maschine mit HAproxy einen einzelnen Ausfallpunkt darstellt, starten wir sie in einem Docker-Container. Später kann sie in einem K8s-Cluster betrieben werden, wodurch unser ausfallsicherer Cluster noch zuverlässiger wird.

Erstellen Sie ein Verzeichnis, in dem Sie zwei Dateien – Dockerfile und haproxy.cfg – speichern können. Wechseln Sie dorthin.

Dockerfile

FROM ubuntu:latest

RUN apt-get update 
    && apt-get install -y haproxy rsyslog 
    && rm -rf /var/lib/apt/lists/*

RUN mkdir /run/haproxy

COPY haproxy.cfg /etc/haproxy/haproxy.cfg

CMD haproxy -f /etc/haproxy/haproxy.cfg && tail -F /var/log/haproxy.log

Seien Sie vorsichtig, in den letzten drei Zeilen der Datei haproxy.cfg sollten die Adressen Ihrer Maschinen aufgeführt sein. HAproxy wird die Anfragen an Patroni weiterleiten, der HTTP-Header des Master-Servers gibt immer 200 zurück, während der Replica 503 zurückgibt.

haproxy.cfg

global
    maxconn 100

defaults
    log global
    mode tcp
    retries 2
    timeout client 30m
    timeout connect 4s
    timeout server 30m
    timeout check 5s

listen stats
    mode http
    bind *:7000
    stats enable
    stats uri /

listen postgres
    bind *:5000
    option httpchk
    http-check expect status 200
    default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions
    server postgresql1 192.168.0.143:5432 maxconn 100 check port 8008
    server postgresql2 192.168.0.144:5432 maxconn 100 check port 8008
    server postgresql3 192.168.0.145:5432 maxconn 100 check port 8008

In dem Verzeichnis, in dem sich beide Dateien befinden, führen wir nacheinander die Befehle zum Verpacken des Containers sowie dessen Start mit den erforderlichen Portweiterleitungen aus:

docker build -t my-haproxy .
docker run -d -p5000:5000 -p7000:7000 my-haproxy 

Wenn Sie jetzt die Adresse Ihrer Maschine mit HAproxy in Ihrem Browser öffnen und den Port 7000 angeben, sehen Sie die Statistiken Ihres Clusters.

Der Server, der sich im Zustand UP befindet, ist der Master, während die Replikate im Zustand DOWN sind. Das ist normal; sie arbeiten tatsächlich, werden jedoch in dieser Weise angezeigt, weil sie 503 auf Anfragen von HAproxy zurückgeben. Dadurch wissen wir immer genau, welcher der drei Server momentan der Master ist.

Fazit

Sie sind großartig! In nur 30 Minuten haben Sie einen hervorragenden ausfallsicheren und leistungsstarken Cluster mit Datenbank-Replikation und automatischem Failover eingerichtet. Wenn Sie planen, diese Lösung einzusetzen, lesen Sie die offizielle Patroni-Dokumentation, insbesondere den Abschnitt über das Tool patronictl, das einen bequemen Zugang zur Verwaltung Ihres Clusters bietet.

Herzlichen Glückwunsch!

Quelle: habr.com

60GB SSD 8Gb DDR4