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

Zufälligerweise hatte ich zum Zeitpunkt der Problemstellung nicht genug Erfahrung, um diese Lösung alleine zu entwickeln und auf den Markt zu bringen. Und dann habe ich angefangen zu googeln.

Ich weiß nicht, wo der Haken liegt, aber zum x-ten Mal werde ich mit der Tatsache konfrontiert, dass selbst wenn ich alles Schritt für Schritt mache wie im Tutorial, die gleiche Umgebung wie der Autor vorbereite, dann nie etwas funktioniert. Ich habe keine Ahnung, was los ist, aber als ich wieder darauf stieß, beschloss ich, mein eigenes Tutorial zu schreiben, wenn alles klappt. Eines, das auf jeden Fall funktionieren wird.

Ratgeber im Internet

Es ist einfach so, dass es im Internet nicht an verschiedenen Anleitungen, Tutorials, Schritt-für-Schritt-Anleitungen und dergleichen mangelt. Zufälligerweise wurde ich damit beauftragt, eine Lösung für die bequeme Organisation und den Aufbau eines Failover-PostgreSQL-Clusters zu entwickeln, dessen Hauptanforderungen die Streaming-Replikation vom Master-Server auf alle Replikate und die automatische Bereitstellung einer Reserve im Falle eines Master-Servers waren Versagen.

Zu diesem Zeitpunkt wurde der Stapel der verwendeten Technologien festgelegt:

  • PostgreSQL als DBMS
  • Patron als Clustering-Lösung
  • etcd als verteilter Speicher für Patroni
  • HAproxy zum Organisieren eines einzigen Einstiegspunkts für Anwendungen, die die Datenbank verwenden

Einstellung

Zu Ihrer Aufmerksamkeit: Aufbau eines hochverfügbaren PostgreSQL-Clusters mit Patroni, etcd, HAProxy.

Alle Vorgänge wurden auf virtuellen Maschinen mit installiertem Debian 10-Betriebssystem durchgeführt.

usw

Ich empfehle nicht, etcd auf denselben Rechnern zu installieren, auf denen sich Patroni und Postgresql befinden, da die Festplattenlast für etcd sehr wichtig ist. Aber aus Bildungsgründen werden wir genau das tun.
Lassen Sie uns etcd installieren.

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

Fügen Sie Inhalt zur Datei /etc/default/etcd hinzu

[Mitglied]

ETCD_NAME=datanode1 # Hostname Ihres Computers
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 Autos
ETCD_LISTEN_CLIENT_URLS="http://192.168.0.143:2379,http://127.0.0.1:2379» # Adresse Ihres Autos

[Cluster]

ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.0.143:2380» # Adresse Ihres Autos
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="neu"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-1″
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.0.143:2379» # Adresse Ihres Autos

Führen Sie den Befehl aus

systemctl restart etcd

PostgreSQL 9.6 + Benutzer

Первое, что необходимо сделать, это установить три виртуальные машины для установки на них необходимого ПО. После установки машин, если вы следуете моему туториалу, вы можете запустить этот простой скрипт, который (почти) все сделает за вас. Запускается из-под root.

Bitte beachten Sie, dass das Skript PostgreSQL Version 9.6 verwendet, dies ist auf die internen Anforderungen unseres Unternehmens zurückzuführen. 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 in der soeben erstellten Datei /etc/patroni.yml die folgenden Inhalte einfügen und natürlich die IP-Adressen an allen Stellen in die von Ihnen verwendeten Adressen ändern.
Beachten Sie die Kommentare in diesem Yaml. Ändern Sie die Adressen auf jedem Computer im Cluster in Ihre eigenen.

/etc/patroni.yml

scope: pgsql # должно быть одинаковым на всех нодах
namespace: /cluster/ # должно быть одинаковым на всех нодах
name: postgres1 # должно быть разным на всех нодах

restapi:
    listen: 192.168.0.143:8008 # адрес той ноды, в которой находится этот файл
    connect_address: 192.168.0.143:8008 # адрес той ноды, в которой находится этот файл

etcd:
    hosts: 192.168.0.143:2379,192.168.0.144:2379,192.168.0.145:2379 # перечислите здесь все ваши ноды, в случае если вы устанавливаете etcd на них же

# this section (bootstrap) will be written into Etcd:/<namespace>/<scope>/config after initializing new cluster
# and all other cluster members will use it as a `global configuration`
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: en_US.UTF8
    # init pg_hba.conf должен содержать адреса ВСЕХ машин, используемых в кластере
    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 # адрес той ноды, в которой находится этот файл
    connect_address: 192.168.0.143:5432 # адрес той ноды, в которой находится этот файл
    data_dir: /data/patroni # эту директорию создаст скрипт, описанный выше и установит нужные права
    bin_dir:  /usr/lib/postgresql/9.6/bin # укажите путь до вашей директории с postgresql
    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 und die obige Konfiguration muss auch auf allen Maschinen in der Datei /etc/patroni.yml abgelegt werden.

Sobald Sie diese Vorgänge auf allen Maschinen im Cluster abgeschlossen haben, führen Sie auf einer beliebigen Maschine den folgenden Befehl aus

systemctl start patroni
systemctl start postgresql

Warten Sie etwa 30 Sekunden und führen Sie dann diesen Befehl auf den verbleibenden Computern im Cluster aus.

HAproxy

Wir nutzen den wunderbaren HAproxy, um einen einzigen Einstiegspunkt bereitzustellen. Der Master-Server ist immer unter der Adresse des Computers verfügbar, auf dem HAproxy bereitgestellt wird.

Um die Maschine mit HAproxy nicht zu einem Single Point of Failure zu machen, werden wir sie in einem Docker-Container starten; in Zukunft kann sie im K8-Cluster gestartet werden und unseren Failover-Cluster noch zuverlässiger machen.

Erstellen Sie ein Verzeichnis, in dem Sie zwei Dateien speichern können – Dockerfile und haproxy.cfg. Gehen 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 Patroni kontaktieren, in den HTTP-Headern gibt der Master-Server immer 200 zurück und das Replikat gibt immer 503 zurück.

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

Da wir uns in dem Verzeichnis befinden, in dem unsere beiden Dateien „liegen“, führen wir nacheinander die Befehle zum Packen des Containers aus und starten ihn mit der Weiterleitung der erforderlichen Ports:

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

Wenn Sie nun die Adresse Ihres Rechners mit HAproxy im Browser öffnen und Port 7000 angeben, werden Ihnen Statistiken zu Ihrem Cluster angezeigt.

Der Server, der der Master ist, befindet sich im UP-Zustand und die Replikate befinden sich im DOWN-Zustand. Das ist normal, tatsächlich funktionieren sie, aber sie erscheinen so, weil sie 503 für Anfragen von HAproxy zurückgeben. Dadurch wissen wir immer genau, welcher der drei Server der aktuelle Master ist.

Abschluss

Du bist wunderschön! In nur 30 Minuten haben Sie einen hervorragenden fehlertoleranten und leistungsstarken Datenbankcluster mit Streaming-Replikation und automatischem Fallback bereitgestellt. Wenn Sie planen, diese Lösung zu verwenden, schauen Sie sich das an mit offizieller Patroni-Dokumentation, und insbesondere mit seinem Teil, der das Dienstprogramm „patronictl“ betrifft, das bequemen Zugriff auf die Verwaltung Ihres Clusters bietet.

Herzlichen Glückwunsch!

Source: habr.com

Kommentar hinzufügen