Получи се така, че в момента на поставяне на задачата не разполагах с достатъчно опит, за да разработя и стартирам това решение сам. И затова започнах да търся в Гугъл.
Не знам в какво е проблема, но вече за пореден път се сблъсквам с това, че дори ако правя всичко стъпка по стъпка, както в туториала, подготвяйки същата среда като автора, никога нищо не работи. Нямам представа в какво е проблема, но когато отново се сблъсках с това, реших — ще напиша свой туториал, когато всичко проработи. Такъв, който със сигурност ще работи.
Гайдове в Интернет
Получи се така, че интернет не страда от липса на различни гайдове, туториали, стъпка по стъпка и подобни неща. Получи се така, че ми беше поставена задачата да разработя решение за удобна организация и изграждане на отказоустойчив кластер PostgreSQL, главните изисквания към който бяха потокова репликация от Master сървъра към всички реплики и автоматичен преход при отказ на Master сървъра.
На този етап беше определен стекът на използваните технологии:
- PostgreSQL като СУБД
- като решение за кластеризация
- 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="" # адрес на вашата машина
ETCD_LISTEN_CLIENT_URLS="" # адрес на вашата машина
[cluster]
ETCD_INITIAL_ADVERTISE_PEER_URLS="" # адрес на вашата машина
ETCD_INITIAL_CLUSTER="datanode1=" # адреси на всички машини в кластера etcd
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-1"
ETCD_ADVERTISE_CLIENT_URLS="" # адрес на вашата машина
Изпълнете командата
systemctl restart etcdPostgreSQL 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 минути сте разположили отличен отказоустойчив и производителен клъстер с база данни с потокова репликация и автоматично въвеждане на резерв. Ако планирате да използвате това решение, запознайте се , а особено с нейната част, касаеща утилитата patronictl, предоставяща удобен достъп за управление на вашия клъстер.
Поздравления!
Източник: habr.com
