Отказоустойчивый кластер PostgreSQL. Ubuntu18. Debian 10. Debian 11. Debian 12. AstraLinux.

Отказоустойчивый кластер PostgreSQL. Ubuntu18. Debian 10. Debian 11. Debian 12. AstraLinux.

Цель данной статьи заключается в описании процесса создания отказоустойчивого высокодоступного (high availability, HA) кластера PostgreSQL.

Используемые программные продукты:

  • Patroni — шаблон для построения отказоустойчивых кластеров на базе PostgreSQL. Обеспечивает автоматическое переключение на резервный сервер при сбое ведущего сервера. Patroni управляет экземпляром базы данных PostgreSQL и использует внешние системы (ZooKeeper, etcd, Consul или Kubernetes) для хранения общей для всех узлов кластера информации, такой как список узлов кластера и положение ведущего сервера.
  • etcd — согласованное распределенное хранилище пар ключ-значение, обеспечивающее надежный способ хранения данных, к которым могут обращаться распределенная система или кластер машин.
  • HAProxy — прокси сервер TCP и HTTP трафика. Позволяет создать единую точку подключения к PostgreSQL, не зависящую от распределения ролей в кластерах PostgreSQL.

 

Предполагается, что для создания кластера используются три сервера с установленной ОС Ubuntu 18: haproxy, db01, db02 (192.168.10.30, 192.168.10.31, 192.168.10.32).

На первом этапе разворачиваем на машинах кластер etcd, процесс создания кластера рассматривается в отдельной статье: Установка и настройка кластера etcd. Ubuntu 18. Debian 10. Debian 11.

Следующим этапом устанавливаем на хосты db01 и db02 СУБД PostgreSQL, так как готовим инфраструктуру для работы 1С, то разворачивать будем официальную сборку PG 14.5-3 от 1С.

Установка PostgreSQL.

Установка локали ru_RU.utf8:

# locale-gen ru_RU.UTF-8
# update-locale
# localectl set-locale LANG=ru_RU.utf8

Установка библиотек:
# apt install libxslt1.1 libllvm6.0 ssl-cert libjson-perl

Загрузка и установка необходимых версий библиотек для PG:

# wget http://security.ubuntu.com/ubuntu/pool/main/p/postgresql-common/postgresql-client-common_242ubuntu1_all.deb
# wget http://security.ubuntu.com/ubuntu/pool/main/p/postgresql-common/postgresql-common_242ubuntu1_all.deb
# dpkg -i ./postgresql-client-common_242ubuntu1_all.deb
# dpkg -i ./postgresql-common_242ubuntu1_all.deb

Устанавливаем PG от 1С:

# dpkg -i ./libpq5_14.5-3.1C_amd64.deb
# dpkg -i ./postgresql-client-14_14.5-3.1C_amd64.deb
# dpkg -i ./postgresql-14_14.5-3.1C_amd64.deb

Кластер PG инициализировать не нужно.
Запрещаем автоматический запуск PostgreSQL при старте операционной системы. Остановкой и запуском PostgreSQL будет управлять Patroni.

# systemctl stop postgresql
# systemctl disable postgresql

 

UPD 27/01/2024

Потребовалось установить кластер на Astra Linux для нативной версии PostgreSQL 14. Изменения затронули только сам процесс установки PostgreSQL, остальное без изменений.

# astra-ce https://dl.astralinux.ru/astra/stable/1.7_x86-64/repository-extended/
# astra-ce status
# apt update
# apt policy postgresql-14
# apt install postgresql-14
# systemctl status postgresql
# systemctl disable postgresql
# systemctl stop postgresq
l

 

Установка Patroni.

В стандартных репозиториях Ubuntu и Debian содержится пакет patroni, однако на момент установки сборка пакета оказалась не самой свежей и не понимала параметры конфигурации PG , которые появились начиная с версии PG 13. Поэтому устанавливаем Patroni через pip.

Установка Pytnon 3 и вспомогательных пакетов:

# apt install python3 gcc python3-dev python3-pip python3-etcd

# python3 -m pip install --upgrade pip

Драйвер Pytnon для подключения к PG:

# python3 -m pip install psycopg2-binary

Установка Patroni:

# python3 -m pip install patroni

Создание каталога для файла конфигурации Patroni:

# mkdir /etc/patroni/

# chmod 755 /etc/patroni/

В каталоге создаём файл config.yml

# chmod 640 /etc/patroni/config.yml

# chown -R postgres:postgres /etc/patroni/

Файл config.yml:

scope: pgsql # должно быть одинаковым на всех нодах
namespace: /cluster/ # должно быть одинаковым на всех нодах
name: db01 # должно быть разным на всех нодах

restapi:
    listen: 192.168.10.31:8008 # адрес той ноды, в которой находится этот файл
    connect_address: 192.168.10.31:8008 # адрес той ноды, в которой находится этот файл

etcd:
    hosts: 192.168.10.31:2379,192.168.10.32:2379,192.168.10.30: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_size: 8
                   max_wal_senders: 5
                   max_replication_slots: 5
                   checkpoint_timeout: 30

    initdb:
     - auth-host: md5
     - auth-local: peer
     - encoding: UTF8
     - data-checksums
     - locale: ru_RU.UTF-8
#     - locale: en_US.UTF-8

    # 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.10.31/24 md5
    - host replication postgres 192.168.10.32/24 md5
    - host all all 0.0.0.0/0 md5

    users:
        admin:
            password: admin
            options:
                - createrole
                - createdb

postgresql:
    listen: 192.168.10.31:5432 # адрес той ноды, в которой находится этот файл
    connect_address: 192.168.10.31:5432 # адрес той ноды, в которой находится этот файл
    data_dir: /var/lib/postgresql/14/data # эту директорию создаст скрипт, описанный выше и установит нужные права
    bin_dir:  /usr/lib/postgresql/14/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

Создаём каталог для размещения баз PG:

# mkdir -p /var/lib/postgresql/14/data/
# chown postgres:postgres /var/lib/postgresql/14/data/
# chmod 750 /var/lib/postgresql/14/data/

Для управления сервисом Patroni создаём файл /lib/systemd/system/patroni.service со следующим содержимым:

[Unit]
Description=Runners to orchestrate a high-availability PostgreSQL
After=network.target
ConditionPathExists=/etc/patroni/config.yml

[Service]
Type=simple

User=postgres
Group=postgres

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

# only kill the patroni process, not it's children, so it will gracefully stop postgres
KillMode=process

# Give a reasonable amount of time for the server to start up/shut down
TimeoutSec=30

# Do not restart the service if it crashes, we want to manually inspect database on failure
Restart=no

[Install]
WantedBy=multi-user.target

Выполняем включение автозапуска и стартуем Patroni:
# systemctl enable patroni
# systemctl start patroni

На хосте db02 выполняем аналогичные действия, отличаться будет лишь файл конфигурации config.yml:

scope: pgsql # должно быть одинаковым на всех нодах
namespace: /cluster/ # должно быть одинаковым на всех нодах
name: db02 # должно быть разным на всех нодах

restapi:
    listen: 192.168.10.32:8008 # адрес той ноды, в которой находится этот файл
    connect_address: 192.168.10.32:8008 # адрес той ноды, в которой находится этот файл

etcd:
    hosts: 192.168.10.31:2379,192.168.10.32:2379,192.168.10.30: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
                   wal_level: replica
                   hot_standby: "on"
                   wal_keep_size: 8
                   max_wal_senders: 5
                   max_replication_slots: 5
                   checkpoint_timeout: 30

    initdb:
     - auth-host: md5
     - auth-local: peer
     - encoding: UTF8
     - data-checksums
     - locale: ru_RU.UTF-8
#     - locale: en_US.UTF-8

    # 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.10.31/24 md5
    - host replication postgres 192.168.10.32/24 md5
    - host all all 0.0.0.0/0 md5

    users:
        admin:
            password: admin
            options:
                - createrole
                - createdb

postgresql:
    listen: 192.168.10.32:5432 # адрес той ноды, в которой находится этот файл
    connect_address: 192.168.10.32:5432 # адрес той ноды, в которой находится этот файл
    data_dir: /var/lib/postgresql/14/data # эту директорию создаст скрипт, описанный выше и установит нужные права
    bin_dir:  /usr/lib/postgresql/14/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

 

Установка HAProxy.

На узел hapoxy выполняется установка:

# apt -y install haproxy

Файл конфигурации HAProxy  /etc/haproxy/haproxy.cfg:

global
        maxconn 100
        log     127.0.0.1 local2
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 *:5432
    option httpchk
    http-check expect status 200
    default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions
    server db01 192.168.10.31:5432 maxconn 100 check port 8008
    server db02 192.168.10.32:5432 maxconn 100 check port 8008

Для проверки состояния кластера на хостах db01 или db02 выполняется команда:
# patronictl -c /etc/patroni/config.yml list

+--------+---------------+---------+---------+----+-----------+
| Member | Host          | Role    | State   | TL | Lag in MB |
+ Cluster: pgsql (7161680026250428483) ------+----+-----------+
| db01   | 192.168.10.31 | Leader  | running |  1 |           |
| db02   | 192.168.10.32 | Replica | running |  1 |         0 |
+--------+---------------+---------+---------+----+-----------+

Для мониторинга также можно использовать веб-интерфейс HAProxy http://192.168.10.30:7000

После запуска кластера в работу взаимодействие с PG производится по адресу 192.168.10.30:5432

Имитация сбоя одного из хостов PG-кластера проводится командой:
# systemctl stop patroni

При отказе одного из узлов кластер продолжит принимать подключения и обработку данных. После восстановления узла на него происходит автоматическая репликация данных.

Nicko

Добавить комментарий