Bygga ett mycket tillgängligt PostgreSQL-kluster med Patroni, etcd, HAProxy

Det råkade bara vara så att vid den tidpunkt då problemet uppstod hade jag inte tillräckligt med erfarenhet för att utveckla och lansera den här lösningen ensam. Och så började jag googla.

Jag vet inte vad haken är, men för femtonde gången står jag inför det faktum att även om jag gör allt steg för steg som i handledningen, förbereder samma miljö som författaren, så fungerar ingenting. Jag har ingen aning om vad som är felet, men när jag stötte på det här igen bestämde jag mig för att jag ska skriva min egen handledning när allt fungerar. En som definitivt kommer att fungera.

Guider på Internet

Det råkar vara så att Internet inte lider av brist på olika guider, tutorials, steg-för-steg och liknande. Det råkade bara vara så att jag fick i uppdrag att utveckla en lösning för att bekvämt organisera och bygga ett failover PostgreSQL-kluster, vars huvudkrav var strömmande replikering från masterservern till alla repliker och automatisk provisionering av en reserv i händelse av en masterserver fel.

I detta skede bestämdes stapeln av tekniker som användes:

  • PostgreSQL som ett DBMS
  • Patroni som en klustringslösning
  • etcd som distribuerad lagring för Patroni
  • HAproxy för att organisera en enda ingångspunkt för applikationer som använder databasen

Installation

För din uppmärksamhet - bygga ett högst tillgängligt PostgreSQL-kluster med Patroni, etcd, HAProxy.

Alla operationer utfördes på virtuella maskiner med Debian 10 OS installerat.

ETCD

Jag rekommenderar inte att installera etcd på samma maskiner där patroni och postgresql kommer att finnas, eftersom diskbelastning är mycket viktig för etcd. Men i utbildningssyfte kommer vi att göra just det.
Låt oss installera etcd.

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

Lägg till innehåll i filen /etc/default/etcd

[medlem]

ETCD_NAME=datanode1 # värdnamn på din maskin
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"

ALLA IP-ADRESSER SKA ÄR GILTIGA. LISTER PEER, KLIENT etc. SKA STÄLLAS IN PÅ VÄRDENS IP-ADRESS

ETCD_LISTEN_PEER_URLS="http://192.168.0.143:2380» # adress till din bil
ETCD_LISTEN_CLIENT_URLS="http://192.168.0.143:2379,http://127.0.0.1:2379» # adress till din bil

[klunga]

ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.0.143:2380» # adress till din bil
ETCD_INITIAL_CLUSTER=»datanod1=http://192.168.0.143:2380,datanode2=http://192.168.0.144:2380,datanode3=http://192.168.0.145:2380» # adresser till alla maskiner i etcd-klustret
ETCD_INITIAL_CLUSTER_STATE="ny"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-1″
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.0.143:2379» # adress till din bil

Kör kommandot

systemctl restart etcd

PostgreSQL 9.6 + patroni

Det första du behöver göra är att ställa in tre virtuella maskiner för att installera nödvändig programvara på dem. Efter att ha installerat maskinerna, om du följer min handledning, kan du köra detta enkla skript som (nästan) kommer att göra allt för dig. Körs som root.

Observera att skriptet använder PostgreSQL version 9.6, detta beror på de interna kraven i vårt företag. Lösningen har inte testats på andra versioner av PostgreSQL.

#!/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

Därefter, i filen /etc/patroni.yml du just skapade, måste du placera följande innehåll, naturligtvis ändra IP-adresserna på alla ställen till de adresser du använder.
Var uppmärksam på kommentarerna i denna yaml. Ändra adresserna till dina egna på varje dator i klustret.

/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

Skriptet måste köras på alla tre datorer i klustret, och ovanstående konfiguration måste också placeras i filen /etc/patroni.yml på alla datorer.

När du har slutfört dessa operationer på alla datorer i klustret, kör följande kommando på någon av dem

systemctl start patroni
systemctl start postgresql

Vänta cirka 30 sekunder och kör sedan det här kommandot på de återstående datorerna i klustret.

HAproxy

Vi använder den underbara HAproxy för att tillhandahålla en enda ingångspunkt. Huvudservern kommer alltid att vara tillgänglig på adressen till den maskin på vilken HAproxy distribueras.

För att inte göra maskinen med HAproxy till en enda felpunkt kommer vi att lansera den i en Docker-container; i framtiden kan den lanseras i K8:s kluster och göra vårt failover-kluster ännu mer tillförlitligt.

Skapa en katalog där du kan lagra två filer - Dockerfile och haproxy.cfg. Gå till det.

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

Var försiktig, de tre sista raderna i filen haproxy.cfg bör lista adresserna till dina maskiner. HAproxy kommer att kontakta Patroni, i HTTP-huvudena kommer huvudservern alltid att returnera 200, och repliken kommer alltid att returnera 503.

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

Genom att vara i katalogen där båda våra filer "ligger", låt oss köra kommandona för att packa behållaren i följd, samt starta den med vidarebefordran av nödvändiga portar:

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

Nu, genom att öppna adressen till din maskin med HAproxy i webbläsaren och ange port 7000, kommer du att se statistik på ditt kluster.

Servern som är master kommer att vara i UPP-läge och replikerna kommer att vara i NED-läge. Detta är normalt, i själva verket fungerar de, men de ser ut så här eftersom de returnerar 503 för förfrågningar från HAproxy. Detta gör att vi alltid kan veta exakt vilken av de tre servrarna som är den nuvarande mastern.

Slutsats

Du är vacker! På bara 30 minuter har du implementerat ett utmärkt feltolerant och högpresterande databaskluster med strömmande replikering och automatisk reserv. Om du planerar att använda den här lösningen, kolla in med officiell Patroni-dokumentation, och särskilt med dess del som gäller patronictl-verktyget, som ger bekväm åtkomst till att hantera ditt kluster.

Grattis!

Källa: will.com

Lägg en kommentar