Creazione di un cluster PostgreSQL ad alta disponibilità utilizzando Patroni, etcd, HAProxy

È successo che al momento in cui è stato posto il problema, non avevo abbastanza esperienza per sviluppare e lanciare questa soluzione da solo. E poi ho iniziato a cercare su Google.

Non so quale sia il problema, ma per l'ennesima volta mi trovo di fronte al fatto che anche se faccio tutto passo passo come nel tutorial, preparando lo stesso ambiente dell'autore, poi non funziona mai nulla. Non ho idea di quale sia il problema, ma quando mi sono imbattuto di nuovo in questo problema, ho deciso che scriverò il mio tutorial quando tutto funzionerà. Uno che funzionerà sicuramente.

Guide su Internet

Si dà il caso che Internet non soffra della mancanza di varie guide, tutorial, istruzioni dettagliate e simili. È successo che mi è stato assegnato il compito di sviluppare una soluzione per organizzare e costruire comodamente un cluster PostgreSQL di failover, i cui requisiti principali erano la replica in streaming dal server master a tutte le repliche e il provisioning automatico di una riserva in caso di server master fallimento.

In questa fase è stato determinato lo stack di tecnologie utilizzate:

  • PostgreSQL come DBMS
  • patrono come soluzione di clustering
  • etcd come storage distribuito per Patroni
  • HAproxy per organizzare un unico punto di ingresso per le applicazioni che utilizzano il database

Installazione

Alla tua attenzione: creazione di un cluster PostgreSQL ad alta disponibilità utilizzando Patroni, etcd, HAProxy.

Tutte le operazioni sono state eseguite su macchine virtuali con sistema operativo Debian 10 installato.

etcd

Non consiglio di installare etcd sulle stesse macchine su cui verranno posizionati patroni e postgresql, poiché il carico del disco è molto importante per etcd. Ma per scopi educativi, faremo proprio questo.
Installiamo etcd.

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

Aggiungi contenuto al file /etc/default/etcd

[membro]

ETCD_NAME=datanode1 # nome host della tua macchina
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"

TUTTI GLI INDIRIZZI IP DEVONO ESSERE VALIDI. PEER LISTER, CLIENT ecc. DOVREBBERO ESSERE IMPOSTATI SULL'INDIRIZZO IP DELL'HOST

ETCD_LISTEN_PEER_URLS="http://192.168.0.143:2380» # indirizzo della vostra auto
ETCD_LISTEN_CLIENT_URLS="http://192.168.0.143:2379,http://127.0.0.1:2379» # indirizzo della vostra auto

[Cluster]

ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.0.143:2380» # indirizzo della vostra auto
ETCD_INITIAL_CLUSTER=»datanode1=http://192.168.0.143:2380,datanode2=http://192.168.0.144:2380,datanode3=http://192.168.0.145:2380» # indirizzi di tutte le macchine nel cluster etcd
ETCD_INITIAL_CLUSTER_STATE="nuovo"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-1″
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.0.143:2379» # indirizzo della vostra auto

Esegui il comando

systemctl restart etcd

PostgreSQL 9.6 + patroni

La prima cosa che devi fare è configurare tre macchine virtuali per installare su di esse il software necessario. Dopo aver installato le macchine, se segui il mio tutorial, potrai eseguire questo semplice script che farà (quasi) tutto per te. Funziona come root.

Tieni presente che lo script utilizza PostgreSQL versione 9.6, ciò è dovuto ai requisiti interni della nostra azienda. La soluzione non è stata testata su altre versioni di 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

Successivamente, nel file /etc/patroni.yml che hai appena creato, devi inserire i seguenti contenuti, ovviamente cambiando gli indirizzi IP in tutti i posti con gli indirizzi che usi.
Presta attenzione ai commenti in questo yaml. Modifica gli indirizzi con i tuoi su ciascuna macchina nel cluster.

/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

Lo script deve essere eseguito su tutte e tre le macchine del cluster e la configurazione precedente deve essere inserita anche nel file /etc/patroni.yml su tutte le macchine.

Una volta completate queste operazioni su tutte le macchine del cluster, esegui il comando seguente su ognuna di esse

systemctl start patroni
systemctl start postgresql

Attendi circa 30 secondi, quindi esegui questo comando sulle restanti macchine nel cluster.

HAproxy

Utilizziamo il meraviglioso HAproxy per fornire un unico punto di accesso. Il server master sarà sempre disponibile all'indirizzo della macchina su cui è distribuito HAproxy.

Per non rendere la macchina con HAproxy un single point of Failure, la lanceremo in un container Docker; in futuro potrà essere lanciata nel cluster K8 e rendere il nostro cluster di failover ancora più affidabile.

Crea una directory in cui puoi archiviare due file: Dockerfile e haproxy.cfg. Vai ad esso.

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

Fai attenzione, le ultime tre righe del file haproxy.cfg dovrebbero elencare gli indirizzi delle tue macchine. HAproxy contatterà Patroni, nelle intestazioni HTTP il server master restituirà sempre 200 e la replica restituirà sempre 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

Trovandoci nella directory in cui "si trovano" entrambi i nostri file, eseguiamo in sequenza i comandi per comprimere il contenitore, nonché avviarlo con l'inoltro delle porte necessarie:

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

Ora, aprendo l'indirizzo della tua macchina con HAproxy nel browser e specificando la porta 7000, vedrai le statistiche sul tuo cluster.

Il server master sarà nello stato UP e le repliche saranno nello stato DOWN. Questo è normale, infatti funzionano, ma si presentano così perché restituiscono 503 per le richieste di HAproxy. Questo ci permette di sapere sempre esattamente quale dei tre server è il master attuale.

conclusione

Sei favolosa! In soli 30 minuti hai distribuito un eccellente cluster di database con tolleranza agli errori e ad alte prestazioni con replica in streaming e fallback automatico. Se hai intenzione di utilizzare questa soluzione, dai un'occhiata con documentazione ufficiale Patroni, e soprattutto con la parte relativa all'utilità patronictl, che fornisce un comodo accesso alla gestione del cluster.

Congratulazioni!

Fonte: habr.com

Aggiungi un commento