Изграждане на кластер с висока наличност на PostgreSQL, използвайки Patroni, etcd, HAProxy

Получи се така, че в момента на поставяне на задачата не разполагах с достатъчно опит, за да разработя и стартирам това решение сам. И затова започнах да търся в Гугъл.

Не знам в какво е проблема, но вече за пореден път се сблъсквам с това, че дори ако правя всичко стъпка по стъпка, както в туториала, подготвяйки същата среда като автора, никога нищо не работи. Нямам представа в какво е проблема, но когато отново се сблъсках с това, реших — ще напиша свой туториал, когато всичко проработи. Такъв, който със сигурност ще работи.

Гайдове в Интернет

Получи се така, че интернет не страда от липса на различни гайдове, туториали, стъпка по стъпка и подобни неща. Получи се така, че ми беше поставена задачата да разработя решение за удобна организация и изграждане на отказоустойчив кластер PostgreSQL, главните изисквания към който бяха потокова репликация от Master сървъра към всички реплики и автоматичен преход при отказ на Master сървъра.

На този етап беше определен стекът на използваните технологии:

  • PostgreSQL като СУБД
  • Patroni като решение за кластеризация
  • etcd като разпределено хранилище за Patroni
  • HAproxy за организиране на единна точка за достъп за приложенията, използващи базата

Инсталиране

Представяме ви изграждането на кластер с висока наличност на PostgreSQL, използвайки Patroni, etcd, HAProxy.

Всички операции се извършваха на виртуални машини с инсталирана ОС Debian 10.

etcd

Не препоръчвам да инсталирате etcd на същите машини, където ще се намират patroni и postgresql, тъй като за etcd е изключително важна натовареността на дисковете. Но с цел обучение, ще постъпим точно така.
Ще инсталираме etcd.

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

Добавете съдържанието в файла \/etc\/default\/etcd

[member]

ETCD_NAME=datanode1 # hostname на вашата машина
ETCD_DATA_DIR="\/var\/lib\/etcd\/default.etcd"

ВСИЧКИ IP АДРЕСИ ТРЯБВА ДА СА ВАЛИДНИ. LISTEN PEER, CLIENT и т.н. ТРЯБВА ДА БЪДАТ ЗАДАДЕНИ НА IP АДРЕСА НА ХОСТА

ETCD_LISTEN_PEER_URLS="http://192.168.0.143:2380" # адрес на вашата машина
ETCD_LISTEN_CLIENT_URLS="http:\/\/192.168.0.143:2379,http:\/\/127.0.0.1:2379" # адрес на вашата машина

[cluster]

ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.0.143:2380" # адрес на вашата машина
ETCD_INITIAL_CLUSTER="datanode1=http:\/\/192.168.0.143:2380,datanode2=http:\/\/192.168.0.144:2380,datanode3=http:\/\/192.168.0.145:2380" # адреси на всички машини в кластера etcd
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-1"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.0.143:2379" # адрес на вашата машина

Изпълнете командата

systemctl restart etcd

PostgreSQL 9.6 + patroni

Първото нещо, което трябва да направите, е да инсталирате три виртуални машини, за да инсталирате необходимия софтуер. След инсталирането на машините, ако следвате моето ръководство, можете да стартирате този прост скрипт, който (почти) всичко ще направи вместо вас. Стартира се от root.

Обърнете внимание, че скриптът използва версия PostgreSQL 9.6, което се дължи на вътрешните изисквания на нашата компания. Решението не е тествано на други версии на 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

След това, в току-що създадения файл /etc/patroni.yml, трябва да поставите следното съдържание, разбира се, променяйки ip-адресите на всички места на адресите, които използвате.
Обърнете внимание на коментарите в този yaml. Променете адресите на вашите, на всяка машина в клъстера.

/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 на тях

# този раздел (bootstrap) ще бъде записан в Etcd:/<namespace>/<scope>/config след инициализация на новия кластер
# и всички други членове на клъстера ще го използват като `глобална конфигурация`
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

Скриптът трябва да бъде изпълнен на всички три машини в клъстера, а предоставената конфигурация трябва да бъде поставена в файла /etc/patroni.yml на всички машини.

Когато извършите тези операции на всички машини в клъстера, изпълнете следната команда на която и да е от тях

systemctl start patroni
systemctl start postgresql

Изчакайте около 30 секунди, след което изпълнете тази команда на останалите машини в клъстера.

HAproxy

Използваме страхотен HAproxy за предоставяне на единна точка за достъп. Master-сървърът винаги ще бъде достъпен на адреса на машината, на която е инсталиран HAproxy.

За да не направим машината с HAproxy единствена точка на отказ, ще я стартираме в контейнер Docker, а по-късно може да я пуснем в клъстер K8’s и да направим нашия отказоустойчив клъстер още по-надежден.

Създайте директория, в която ще можете да съхранявате два файла — Dockerfile и haproxy.cfg. Преминете в нея.

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

Бъдете внимателни, в трите последни реда на файла haproxy.cfg трябва да са изброени адресите на вашите машини. HAproxy ще се свързва с Patroni, в HTTP заглавията master-сървърът винаги ще връща 200, а replica — 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

Намирайки се в директорията, където са нашите два файла, ще изпълним последователно командите за опаковане на контейнера, както и неговото стартиране с пренасочване на необходимите портове:

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

Сега, отваряйки в браузъра адреса на вашата машина с HAproxy и указвайки порт 7000, ще видите статистика за вашия клъстер.

В състояние UP ще бъде този сървър, който е master, а репликите ще бъдат в състояние DOWN. Това е нормално, всъщност те работят, но се показват по този начин, защото връщат 503 на запитванията от HAproxy. Това ни позволява винаги точно да знаем кой от трите сървъра е в момента master.

Заключение

Вие сте невероятни! Всичко това само за 30 минути сте разположили отличен отказоустойчив и производителен клъстер с база данни с потокова репликация и автоматично въвеждане на резерв. Ако планирате да използвате това решение, запознайте се с официалната документация на Patroni, а особено с нейната част, касаеща утилитата patronictl, предоставяща удобен достъп за управление на вашия клъстер.

Поздравления!

Източник: habr.com

Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster