Найти в Дзене

Создание отказоустойчивого кластера PostgreSQL с использованием consul+patroni

Для создания кластера нам понадобиться создать 6 серверов, три машины будут использовать ОС "Centos 8" и три ОС "Debian 12". Все команды будут вводиться через ssh под пользователем root. Centos 8: PG-SQL-01 – 10.1.104.56/28 PG-SQL-02 – 10.1.104.57/28 PG-SQL-03 – 10.1.104.58/28 Debian 12: PG-haproxy-01 – 10.1.104.51/28 PG-haproxy-02 – 10.1.104.52/28 PG-adm – 10.1.104.61/28 Так же необходимо зарезервировать один адрес для виртуального IP, через который будет работать наш кластер. Virtual IP – 10.1.104.60/28 Для всех серверов PG-SQL ставим необходимые компоненты. yum install zip yum install yum-utils Из-за ограничений доступа не все сервисы можно установить непосредственно из ОС, поэтому для скачивания некоторых программ может потребоваться использовать VPN. Дистрибутив программы можно скачать с сайта https://developer.hashicorp.com/consul/install нам нужен файл для Linux AMD64 Загружаем скаченный файл на все сервера PG-SQL с помощь WinSCP. Командой ls проверяем, что файл в той папке, г
Оглавление

Для создания кластера нам понадобиться создать 6 серверов, три машины будут использовать ОС "Centos 8" и три ОС "Debian 12". Все команды будут вводиться через ssh под пользователем root.

Centos 8:

PG-SQL-01 – 10.1.104.56/28

PG-SQL-02 – 10.1.104.57/28

PG-SQL-03 – 10.1.104.58/28

Debian 12:

PG-haproxy-01 – 10.1.104.51/28

PG-haproxy-02 – 10.1.104.52/28

PG-adm – 10.1.104.61/28

Так же необходимо зарезервировать один адрес для виртуального IP, через который будет работать наш кластер.

Virtual IP – 10.1.104.60/28

Для всех серверов PG-SQL ставим необходимые компоненты.

yum install zip

yum install yum-utils

Подготовка Consul

Из-за ограничений доступа не все сервисы можно установить непосредственно из ОС, поэтому для скачивания некоторых программ может потребоваться использовать VPN.

Дистрибутив программы можно скачать с сайта https://developer.hashicorp.com/consul/install

нам нужен файл для Linux AMD64

-2

Загружаем скаченный файл на все сервера PG-SQL с помощь WinSCP.

Командой ls проверяем, что файл в той папке, где находимся и мы.

-3

Распаковываем архив.

unzip consul_1.20.1_linux_amd64.zip -d /usr/bin/

После распаковки проверяем, что Consul установился.

consul -v

-4

Добавляем пользователя для Consul и даем ему необходимые права.

useradd -r -c 'Consul' consul

mkdir -p /var/lib/consul /etc/consul.d

chown consul:consul /var/lib/consul /etc/consul.d

chmod 775 /var/lib/consul /etc/consul.d

-5

Добавляем правила доступа.

firewall-cmd --add-port={8300,8301,8302,8500,8600}/tcp --permanent

firewall-cmd --add-port={8301,8302,8600}/udp –permanent

firewall-cmd --permanent --add-port=5432/tcp

firewall-cmd --permanent --add-port=8008/tcp

firewall-cmd --reload

-6

Создаем службу.

nano /etc/systemd/system/consul.service

[Unit]

Description=Consul Service Discovery Agent

Documentation=https://www.consul.io/

After=network-online.target

Wants=network-online.target

[Service]

Type=simple

User=consul

Group=consul

ExecStart=/usr/bin/consul agent \

-config-dir=/etc/consul.d

ExecReload=/bin/kill -HUP $MAINPID

KillSignal=SIGINT

TimeoutStopSec=5

Restart=on-failure

SyslogIdentifier=consul

[Install]

WantedBy=multi-user.target

-7

Генерируем ключ на одном из серверов, он будет один для всех.

consul keygen

-8

Добавляем данный ключ и адреса серверов в конфигурационный файл (для каждого сервера потребуется подменить значение "node_name" и добавить в строку "encrypt" сгенерированный ключ).

nano /etc/consul.d/config.json

{

"bind_addr": "0.0.0.0",

"bootstrap_expect": 3,

"client_addr": "0.0.0.0",

"datacenter": "dc1",

"node_name": "PG-SQL-01",

"data_dir": "/var/lib/consul",

"domain": "consul",

"enable_local_script_checks": true,

"dns_config": {

"enable_truncate": true,

"only_passing": true

},

"enable_syslog": true,

"encrypt": "Aag5RHZVukruT3Zv817b+s/q6Cdk9jmSF7S8dzThEmM=",

"leave_on_terminate": true,

"log_level": "INFO",

"rejoin_after_leave": true,

"retry_join": [

"10.1.104.56",

"10.1.104.57",

"10.1.104.58"

],

"server": true,

"start_join": [

"10.1.104.56",

"10.1.104.57",

"10.1.104.58"

],

"ui_config": { "enabled": true }

}

-9

Запускаем службу.

systemctl daemon-reload

systemctl start consul

systemctl enable consul

-10

Проверяем статус службы.

systemctl status consul

-11

Проверяем кто стал лидером (лидер может определится не сразу).

consul operator raft list-peers

-12

Еще, несколько дополнительных команд для проверки доступности серверов.

consul members

consul members -detailed

-13

Так же Consul имеет свой веб интерфейс (на просторах интернета можно найти статьи как можно ограничить доступ к статистике средствами самого Consul).

Вход на веб интерфейс http://ip:8500

-14

Устанавливаем PostgreSQL

dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm

dnf -qy module disable postgresql

dnf install postgresql16-server -y

sudo /usr/pgsql-16/bin/postgresql-16-setup initdb

systemctl enable postgresql-16

systemctl start postgresql-16

-15

Проверяем статус службы.

systemctl status postgresql-16

-16

Подготавливаем PostgreSQL для работы с сервисом patroni.

Узнаем путь к базе PostgreSQL.

su - postgres -c "psql -c 'SHOW data_directory;'"

-17

Останавливаем PostgreSQL и удаляем базу на всех серверах.

systemctl disable postgresql-16 --now

rm -rf /var/lib/pgsql/16/data/*

-18

Подготавливаем patroni

Устанавливаем python.

yum install python3.11.x86_64 -y

Смотрим, что python установлен.

python3.11 –version

-19

Ставим дополнительные компоненты.

yum install python3-pip python3-psycopg2 gcc python3-devel -y

Устанавливаем patroni для Consul.

pip3 install patroni[consul]

-20

Проверяем, что patroni установился.

patroni –version

-21

Создаем файл конфигурации (в файле нам нужно поменять name и поменять в двух местах ip адрес на адрес сервера, на котором вы редактируете файл. Также в этом файле вы задаете пароль для пользователя postgres и replicator).

mkdir /etc/patroni

nano /etc/patroni/patroni.yml

name: PG-SQL-1

scope: PG-SQL

watchdog:

mode: off

consul:

host: "localhost:8500"

register_service: true

# token: 08099d25-da75-c555-eab8-30f863e2d0bb

restapi:

listen: 0.0.0.0:8008

connect_address: "10.1.104.56:8008"

# auth: 'patrest:password'

bootstrap:

dcs:

ttl: 30

loop_wait: 10

maximum_lag_on_failover: 1048576

postgresql:

use_pg_rewind: true

use_slots: true

parameters:

archive_mode: "on"

wal_level: hot_standby

max_wal_senders: 10

wal_keep_segments: 8

archive_timeout: 1800s

max_replication_slots: 5

hot_standby: "on"

wal_log_hints: "on"

initdb:

- encoding: UTF8

- data-checksums

pg_hba:

- local all postgres peer

- host replication replicator 10.1.104.0/24 md5

- host replication replicator 127.0.0.1/32 trust

- host all all 0.0.0.0/0 md5

postgresql:

pgpass: /var/lib/pgsql/16/.pgpass

listen: 0.0.0.0:5432

connect_address: "10.1.104.56:5432"

data_dir: /var/lib/pgsql/16/data/

bin_dir: /usr/pgsql-16/bin/

pg_rewind:

username: postgres

password: <ваш пароль>

pg_hba:

- local all postgres peer

- host replication replicator 10.1.104.0/24 md5

- host replication replicator 127.0.0.1/32 trust

- host all all 0.0.0.0/0 md5

replication:

username: replicator

password: <ваш пароль>

superuser:

username: postgres

password: <ваш пароль>

-22
-23

Создаем файл службы.

nano /lib/systemd/system/patroni.service

[Unit]

Description=Patroni service

After=syslog.target network.target

[Service]

Type=simple

User=postgres

Group=postgres

ExecStart=/usr/local/bin/patroni /etc/patroni/patroni.yml

ExecReload=/bin/kill -s HUP $MAINPID

KillMode=process

TimeoutSec=30

Restart=no

[Install]

WantedBy=multi-user.target

-24

Поочередно стартуем на серверах.

systemctl daemon-reload

systemctl enable patroni --now

systemctl status patroni

-25

Проверяем кластер и кто стал лидером.

patronictl -c /etc/patroni/patroni.yml list

-26

Настройка haproxy

Далее мы переходим к серверам на базе ОС Debian 12.

Выставляем временную зону.

timedatectl set-timezone Europe/Moscow

Устанавливаем haproxy.

apt install haproxy -y

Редактируем конфигурационный файл.

nano /etc/haproxy/haproxy.cfg

global

maxconn 100000

log /dev/log local0

log /dev/log local1 notice

chroot /var/lib/haproxy

stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners

stats timeout 30s

user haproxy

group haproxy

daemon

defaults

mode tcp

log global

retries 2

timeout queue 5s

timeout connect 5s

timeout client 60m

timeout server 60m

timeout check 15s

listen stats

mode http

bind *:7000

stats enable

stats uri /

listen production

bind *:5432

option httpchk OPTIONS/master

http-check expect status 200

default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions

server PG-SQL-01 10.1.104.56:5432 maxconn 100 check port 8008

server PG-SQL-02 10.1.104.57:5432 maxconn 100 check port 8008

server PG-SQL-03 10.1.104.58:5432 maxconn 100 check port 8008

listen standby

bind *:5433

option httpchk OPTIONS/replica

http-check expect status 200

default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions

server PG-SQL-01 10.1.104.56:5432 maxconn 100 check port 8008

server PG-SQL-02 10.1.104.57:5432 maxconn 100 check port 8008

server PG-SQL-03 10.1.104.58:5432 maxconn 100 check port 8008

-27

Проверяем конфигурацию.

haproxy -f /etc/haproxy/haproxy.cfg -c

-28

Перезагружаем и проверяем службу (не надо пугаться красных элементов при проверке статуса, они указывают лишь на то, что другие сервера не являются сейчас лидером).

systemctl restart haproxy

systemctl status haproxy

-29

Смотрим информацию через веб интерфейс (в дальнейшем можно будет использовать общий ip адрес).

http://10.1.104.51:7000/

-30

На скриншоте мы видим два раздела, в первом мы видим доступность лидера, во втором мы видим доступность репликации).

Для организации единого ip адреса (Virtual IP) устанавливаем службу keepalived.

apt install keepalived -y

Для настройки keepalived необходимо определить имя сетевого интерфейса.

ip a

-31

видим, что наш сетевой интерфейс имеет имя ens33

Создаем конфигурационный файл.

nano /etc/keepalived/keepalived.conf

Для основного сервера

! Configuration File for keepalived

vrrp_script chk_haproxy {

script "killall -0 haproxy" # check the haproxy process

interval 2 # every 2 seconds

weight 2 # add 2 points if OK

}

vrrp_instance VI_1 {

interface ens33 # interface to monitor

state MASTER # MASTER on web-node-1, BACKUP on web-node-2

virtual_router_id 51

priority 101 # 101 on web-node-1, 100 on web-node-2

virtual_ipaddress {

10.1.101.60/28 # virtual ip address

}

track_script {

chk_haproxy

}

}

-32

Для вспомогательного сервера

! Configuration File for keepalived

vrrp_script chk_haproxy {

script "killall -0 haproxy" # check the haproxy process

interval 2 # every 2 seconds

weight 2 # add 2 points if OK

}

vrrp_instance VI_1 {

interface ens33 # interface to monitor

state SLAVE # MASTER on web-node-1, BACKUP on web-node-2

virtual_router_id 51

priority 100 # 101 on web-node-1, 100 on web-node-2

virtual_ipaddress {

10.1.104.60/28 # virtual ip address

}

track_script {

chk_haproxy

}

}

-33

Добавляем сетевые правила.

echo net.ipv4.ip_nonlocal_bind=1 >> /etc/sysctl.conf

echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf

sysctl -p

-34

Запускаем службу.

systemctl enable keepalived

systemctl start keepalived

systemctl status keepalived

-35

После перезагрузки сервера проверяем, что у нас появился дополнительный адрес на сетевом интерфейсе.

-36

Установка системы управления pgAdmin 4

Устанавливаем необходимые компоненты.

apt install curl gpg -y

Задаем репозиторий.

curl -fsS https://www.pgadmin.org/static/packages_pgadmin_org.pub | gpg --dearmor -o /usr/share/keyrings/packages-pgadmin-org.gpg

-37

Устанавливаем программу pgadmin4

apt install pgadmin4

sh -c 'echo "deb [signed-by=/usr/share/keyrings/packages-pgadmin-org.gpg] https://ftp.postgresql.org/pub/pgadmin/pgadmin4/apt/$(lsb_release -cs) pgadmin4 main" > /etc/apt/sources.list.d/pgadmin4.list && apt update'

apt install pgadmin4 -y

включаем веб интерфейс.

/usr/pgadmin4/bin/setup-web.sh

На этом шаге нужно ввести адрес электронной почты, который будет является логином для входа в веб.

-38
-39

Ссылка для веб интерфейса.

http://10.1.104.61/pgadmin4

-40

Входим и добавляем наш кластер используя Virtual IP и пароль для postgres указанный нами ранее в конфигурации к patroni.

-41