Budowa klastra PostgreSQL o wysokiej dostępności z użyciem Patroni, etcd, HAProxy

Nie miałem wystarczającego doświadczenia, aby opracować i uruchomić to rozwiązanie samodzielnie, więc zacząłem szukać informacji w internecie.

Nie wiem, gdzie tkwi problem, ale po raz kolejny napotykam sytuację, że mimo iż wykonuję wszystko krok po kroku jak w tutorialu i przygotowuję to samo środowisko co autor, to nic nie działa. Nie mam pojęcia, o co tu chodzi, ale kiedy znowu się z tym zderzyłem, postanowiłem — napiszę swój własny tutorial, gdy już wszystko zadziała. Taki, który na pewno będzie działał.

Przewodniki w Internecie

Nie brakuje w sieci różnych przewodników, tutoriali, krok po kroku i im podobnych rzeczy. Otrzymałem zadanie opracować rozwiązanie do wygodnej organizacji i budowy odpornego na błędy klastra PostgreSQL, którego głównymi wymaganiami były strumieniowa replikacja z serwera Master na wszystkie replikacje oraz automatyczne wprowadzanie zapasowego źródła w przypadku awarii serwera Master.

Na tym etapie określono stos używanych technologii:

  • PostgreSQL jako SGBD
  • Patroni jako rozwiązanie do klastrowania
  • etcd jako rozproszone repozytorium dla Patroni
  • HAproxy do zapewnienia jednego punktu wejścia dla aplikacji korzystających z bazy danych

Instalacja

Przedstawiamy — budowę klastra PostgreSQL o wysokiej dostępności z użyciem Patroni, etcd, HAProxy.

Wszystkie operacje były wykonywane na maszynach wirtualnych z zainstalowanym systemem operacyjnym Debian 10.

etcd

Nie polecam instalowania etcd na tych samych maszynach, na których będą znajdować się Patroni i PostgreSQL, ponieważ dla etcd bardzo ważny jest obciążenie dysków. Jednak w celach szkoleniowych zrobimy to w ten sposób.
Zainstalujemy etcd.

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

Dodaj zawartość do pliku /etc/default/etcd

[member]

ETCD_NAME=datanode1 # nazwa hosta twojej maszyny
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"

WSZYSTKIE ADRESY IP MUSZĄ BYĆ WAŻNE. ADRESY PEER, KLIENTA itp. MUSZĄ BYĆ USTAWIONE NA ADRES IP GOSPODARZA

ETCD_LISTEN_PEER_URLS="http://192.168.0.143:2380" # adres twojej maszyny
ETCD_LISTEN_CLIENT_URLS="http://192.168.0.143:2379,http://127.0.0.1:2379" # adres twojej maszyny

[cluster]

ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.0.143:2380" # adres twojej maszyny
ETCD_INITIAL_CLUSTER="datanode1=http://192.168.0.143:2380,datanode2=http://192.168.0.144:2380,datanode3=http://192.168.0.145:2380" # adresy wszystkich maszyn w klastrze etcd
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-1"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.0.143:2379" # adres twojej maszyny

Wykonaj polecenie

systemctl restart etcd

PostgreSQL 9.6 + Patroni

Pierwszą rzeczą, którą musisz zrobić, jest zainstalowanie trzech maszyn wirtualnych, na których zainstalujesz potrzebne oprogramowanie. Po zainstalowaniu maszyn, jeśli śledzisz mój samouczek, możesz uruchomić ten prosty skrypt, który (prawie) wszystko za ciebie zrobi. Uruchamia się z konta root.

Zauważ, że skrypt używa wersji PostgreSQL 9.6, co jest spowodowane wewnętrznymi wymaganiami naszej firmy. Rozwiązanie nie było testowane na innych wersjach 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

Następnie w utworzonym właśnie pliku /etc/patroni.yml musisz umieścić następującą zawartość, oczywiście zmieniając adresy IP we wszystkich miejscach na te, które używasz.
Zwróć uwagę na komentarze w tym yaml. Zmień adresy na swoje, na każdej maszynie klastra.

/etc/patroni.yml

zakres: pgsql # musi być taki sam na wszystkich węzłach
namespace: /cluster/ # musi być taki sam na wszystkich węzłach
name: postgres1 # musi być inny na wszystkich węzłach

restapi:
    listen: 192.168.0.143:8008 # adres węzła, na którym znajduje się ten plik
    connect_address: 192.168.0.143:8008 # adres węzła, na którym znajduje się ten plik

etcd:
    hosts: 192.168.0.143:2379,192.168.0.144:2379,192.168.0.145:2379 # wymień tutaj wszystkie swoje węzły, jeśli instalujesz etcd na nich

# ta sekcja (bootstrap) zostanie zapisana w Etcd:/<namespace>/<scope>/config po zainicjowaniu nowego klastra
# i wszyscy inni członkowie klastra będą używać tego jako `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 powinien zawierać adresy WSZYSTKICH maszyn używanych w klastrze
    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 # adres węzła, na którym znajduje się ten plik
    connect_address: 192.168.0.143:5432 # adres węzła, na którym znajduje się ten plik
    data_dir: /data/patroni # ten katalog zostanie utworzony przez skrypt opisany powyżej i ustawione zostaną odpowiednie uprawnienia
    bin_dir:  /usr/lib/postgresql/9.6/bin # podaj ścieżkę do swojego katalogu z 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: '.'

tagi:
    nofailover: false
    noloadbalance: false
    clonefrom: false
    nosync: false

Skrypt należy uruchomić na wszystkich trzech maszynach klastra, a także należy umieścić podaną konfigurację w pliku /etc/patroni.yml na wszystkich maszynach.

Gdy wykonasz te operacje na wszystkich maszynach klastra, wykonaj następującą komendę na jednej z nich

systemctl start patroni
systemctl start postgresql

Poczekaj około 30 sekund, a następnie wykonaj tę komendę na pozostałych maszynach klastra.

HAproxy

Używamy wspaniałego HAproxy, aby zapewnić jednolity punkt wejścia. Serwer master zawsze będzie dostępny pod adresem maszyny, na której jest wdrożone HAproxy.

Aby uniknąć uczynienia maszyny z HAproxy jedynym punktem awarii, uruchomimy go w kontenerze Docker, a później możemy go uruchomić w klastrze K8s, co uczyni nasz klaster odporny na awarie jeszcze bardziej niezawodnym.

Utwórz katalog, w którym będziesz mógł przechowywać dwa pliki — Dockerfile i haproxy.cfg. Przejdź do niego.

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

Uważaj, w trzech ostatnich linijkach pliku haproxy.cfg powinny być wymienione adresy twoich maszyn. HAproxy będzie komunikować się z Patroni, w nagłówkach HTTP serwer master zawsze zwróci 200, a replika — 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

Będąc w katalogu, w którym znajdują się oba nasze pliki, wykonajmy kolejno polecenia do spakowania kontenera, a następnie jego uruchomienia z przekierowaniem wymaganych portów:

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

Teraz, otwierając w przeglądarce adres twojej maszyny z HAproxy i wskazując port 7000, zobaczysz statystyki swojego klastra.

W stanie UP będzie znajdować się ten serwer, który jest masterem, a repliki będą w stanie DOWN. To normalne, w rzeczywistości działają, ale są w takim stanie, ponieważ zwracają 503 na zapytania od HAproxy. Pozwala nam to zawsze dokładnie wiedzieć, który z trzech serwerów jest aktualnie masterem.

Podsumowanie

Jesteś niesamowity! Zaledwie w 30 minut uruchomiłeś doskonały odporny na awarie i wydajny klaster baz danych z replikacją strumieniową i automatycznym przełączaniem awaryjnym. Jeśli planujesz korzystać z tego rozwiązania, zapoznaj się z oficjalną dokumentacją Patroni, a szczególnie z jej częścią dotyczącą narzędzia patronictl, które zapewnia wygodny dostęp do zarządzania twoim klastrem.

Gratulacje!

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster