Высокая доступность PostgreSQL с Patroni и HAProxy

Столкнулись с задачей поддержки устойчивой базы данных PostgreSQL в постоянно меняющемся цифровом мире? Если термин “Patroni” соответствует вашим техническим амбициям, вы на пороге открытия решения, которое превращает PostgreSQL в крепость высокой доступности.

Конечно, вас ждет вызов, но не бойтесь – вы начинаете трансформационное путешествие к созданию непоколебимого кластера PostgreSQL. Представьте себе будущее, где прерывания в работе базы данных – всего лишь мелкие помехи, а ваша конфигурация PostgreSQL выступает в качестве воплощения надежности.

Приготовьтесь укрепить свою среду PostgreSQL, сделав ее непоколебимым бастионом!

Предварительные условия

Перед тем как приступить к реализации высокой доступности для PostgreSQL, убедитесь, что у вас есть следующее:

  • Пять (или более) серверов с Linux – в этом руководстве используются серверы Debian 12, каждый из которых имеет не-корневого пользователя с правами sudo/администратора следующим образом:
Hostname IP Address Used as
postgres01 192.168.5.20 PostgreSQL Server
postgres02 192.168.5.21 PostgreSQL Server
postgres03 192.168.5.22 PostgreSQL Server
etcd 192.168.5.15 Cluster Data Store
haproxy 192.168.5.16 Load Balancer

Установка сервера PostgreSQL и Patroni

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

Patroni – это приложение на основе Python для создания отказоустойчивого развертывания PostgreSQL в ваших центрах обработки данных, от металла до Kubernetes. Patroni доступен в официальном репозитории PostgreSQL и поддерживает серверы PostgreSQL 9.5-16.

Чтобы установить сервер PostgreSQL и Patroni, выполните следующее:

? ПРИМЕЧАНИЕ: Выполните следующие операции на серверах PostgreSQL. В данном случае – postgres01, postgres02 и postgres03.

1. Откройте терминал и выполните команду curl ниже, которая не выводит ничего на экран, но добавляет GPG-ключ репозитория PostgreSQL в /usr/share/keyrings/pgdg.gpg.

? В этом руководстве используется учетная запись root для выполнения команды для обеспечения совместимости с демонстрацией. Однако помните, что использование учетной записи без привилегий root с привилегиями sudo настоятельно рекомендуется. С учетной записью без привилегий root необходимо добавлять префикс sudo к вашим командам для повышения безопасности и соблюдения лучших практик.

curl -fsSL <https://www.postgresql.org/media/keys/ACCC4CF8.asc> | sudo gpg --dearmor -o /usr/share/keyrings/pgdg.gpg

2. Затем выполните следующую команду, которая также не выводит ничего на экран, но добавляет репозиторий PostgreSQL в список источников пакетов в файле /etc/apt/sources.list.d/pgdg.list.

sh -c 'echo "deb [arch=amd64 signed-by=/usr/share/keyrings/pgdg.gpg] <https://apt.postgresql.org/pub/repos/apt> $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'

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

apt update
Adding PostgreSQL repository and updating package index

4. После обновления выполните следующую команду для установки следующих пакетов:

  • postgresql-15 – Система управления базами данных PostgreSQL версии 15.
  • patroni – Открытое решение для обеспечения высокой доступности в PostgreSQL, шаблон для кластеров PostgreSQL HA с использованием Python и etcd.
  • python3-etcd – Библиотека клиента Python для взаимодействия с etcd, распределенным хранилищем ключ-значение. Эта библиотека позволяет приложениям на Python взаимодействовать и управлять кластерами etcd.
  • python3-psycopg2 – Адаптер PostgreSQL для Python 3, соединяющий приложения Python и базы данных PostgreSQL.
apt install postgresql-15 postgresql-server-dev-15 patroni python3-etcd python3-psycopg2

Введите Y, чтобы продолжить установку при запросе.

Installing packages including PostgreSQL 15 and Patroni

5. После установки пакетов выполните каждую из следующих команд, которые не выводят информацию в терминал, но выполняют следующее:

  • Остановите службы postgresql и patroni. На Debian/Ubuntu службы postgresql и patroni автоматически запускаются после установки.
  • Создайте символическую ссылку для двоичных файлов PostgreSQL в каталоге /usr/sbin. Таким образом, обеспечивается возможность выполнения двоичных файлов PostgreSQL для создания и управления PostgreSQL в Patroni.
systemctl stop postgresql patroni
ln -s /usr/lib/postgresql/15/bin/* /usr/sbin/

6. Наконец, выполните следующие команды для проверки пути к двоичному файлу patroni и psql, а также установленной версии patroni с помощью опции –version.

which patroni
which psql
patroni --version

Ниже приведены пути к двоичным файлам patroni (/usr/bin/patroni) и psql (/usr/sbin/psql); установленная версия Patroni – 3.2.1.

Verifying binary paths for Patroni and psql

Настройка и конфигурация сервера etcd

Теперь, когда у вас установлены сервер PostgreSQL и Patroni, вам нужен инструмент, который обеспечит координацию между вашими серверами PostgreSQL для обеспечения безопасности и надежности. Вы настроите и сконфигурируете etcd, хранилище ключ-значение.

Это хранилище ключ-значение работает в фоновом режиме и обеспечивает безопасное хранение и эффективное управление данными, связанными с развертыванием вашего кластера PostgreSQL.

? ПРИМЕЧАНИЕ: Убедитесь, что etcd установлен на отдельном сервере. В этом примере etcd установлен на сервере etcd.

Для установки и настройки etcd выполните следующие шаги:

1. На вашем сервере etcd выполните следующую команду, чтобы обновить индекс репозитория и получить последнюю информацию о пакете.

apt update
Updating the Debian repository on the etcd server

2. Затем выполните следующую команду для установки etcd на вашем сервере.

apt install etcd-server
Installing etcd

3. После установки etcd откройте файл конфигурации по умолчанию /etc/default/etcd с помощью выбранного вами редактора и вставьте следующую конфигурацию.

Эта конфигурация настраивает один единственный кластер etcd, поэтому убедитесь, что вы заменяете IP-адрес 192.168.5.15 на свой внутренний IP-адрес.

ETCD_LISTEN_PEER_URLS="<http://192.168.5.15:2380>"
ETCD_LISTEN_CLIENT_URLS="<http://localhost:2379>,<http://192.168.5.15:2379>"
ETCD_INITIAL_ADVERTISE_PEER_URLS="<http://192.168.5.15:2380>"
ETCD_INITIAL_CLUSTER="default=http://192.168.5.15:2380,"
ETCD_ADVERTISE_CLIENT_URLS="<http://192.168.5.15:2379>"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new" 

Сохраните изменения и закройте редактор.

Configuring an etcd single cluster mode

4. Теперь выполните следующую команду systemctl для перезапуска etcd и применения ваших изменений.

Эта команда не выводит никакой информации, но вы проверите изменения на следующем шаге.

systemctl restart etcd

5. После перезапуска etcd убедитесь, что служба etcd запущена и включена.

systemctl is-enabled etcd
systemctl status etcd

Если служба etcd запущена, вы увидите вывод active (running). Если она включена, вы увидите вывод enabled, что также означает, что etcd будет автоматически запускаться при загрузке.

Checking the etcd service status

6. Наконец, выполните следующую команду etcdctl для проверки списка доступных серверов в кластере etcd.

etcdctl member list

В этом случае etcd работает как одноузловой кластер на локальном IP-адресе http://192.168.5.15:2379/.

Checking cluster members on etcd

Загрузка кластера PostgreSQL через Patroni

С установленным сервером etcd вы теперь на пороге следующей ключевой фазы. Инициируя процесс загрузки с использованием Patroni, вы повышаете конфигурацию PostgreSQL до надежного и устойчивого к сбоям кластера.

? Не забудьте сначала создать резервную копию своей базы данных, если вы разворачиваете кластер PostgreSQL на существующем сервере PostgreSQL.

Чтобы инициировать свой кластер PostgreSQL через Patroni, выполните следующее на каждом сервере PostgreSQL:

1. Откройте конфигурацию по умолчанию Patroni (/etc/patroni/config.yml) в вашем текстовом редакторе и добавьте следующую конфигурацию.

Обязательно замените значение опции name на имя вашего сервера PostgreSQL (например, postgres01), но еще не закрывайте редактор.

Эта конфигурация устанавливает ваш кластер PostgreSQL с именем postgres.

# Область действия PostgreSQL
scope: postgres
# Пространство имен для базы данных PostgreSQL
namespace: /db/
# Имя экземпляра PostgreSQL
name: postgres01

2. Затем добавьте следующую конфигурацию для настройки Patroni REST API для запуска по адресу 192.168.5.20:8008.

Обязательно убедитесь, что каждый из серверов PostgreSQL в кластере может подключаться через API. Таким образом, замените IP-адрес 192.168.5.20 на соответствующий IP-адрес каждого сервера PostgreSQL.

# Конфигурация REST API Patroni
restapi:
    # IP-адрес и порт, на котором должен слушать REST API
    listen: 192.168.5.20:8008

    # IP-адрес и порт, к которым должны подключаться клиенты
    connect_address: 192.168.5.20:8008

3. Добавьте следующую конфигурацию, чтобы включить интеграцию с etcd. В этом случае сервер etcd работает по IP-адресу 192.168.5.15.

# Конфигурация Etcd для Patroni
etcd3:
    # Адрес хоста и порт сервера Etcd
    host: 192.168.5.15:2379

4. Теперь добавьте следующую конфигурацию для bootstrap сервера PostgreSQL через initdb.

Эта конфигурация устанавливает правила и параметры по умолчанию для аутентификации клиента (pg_hba.conf) и нового пользователя admin с паролем admin.

Не забудьте указать IP-адреса кластера PostgreSQL в разделе pg_hba и изменить пароль admin по умолчанию в разделе users.

# Настройка запуска Patroni
bootstrap:
    # Параметры конфигурации для распределенного хранилища конфигурации (DCS)
    dcs:
        ttl: 30
        loop_wait: 10
        retry_timeout: 10
        maximum_lag_on_failover: 1048576
        postgresql:
            # Использовать pg_rewind во время начальной загрузки
            use_pg_rewind: true

    # Настройка initdb
    initdb:
        - auth: scram-sha-256
        - encoding: UTF8
        - data-checksums

    # Записи pg_hba.conf для репликации и общего доступа
    pg_hba:
        - host replication replicator 127.0.0.1/32 scram-sha-256
        - host replication replicator 192.168.5.20/0 scram-sha-256
        - host replication replicator 192.168.5.21/0 scram-sha-256
        - host replication replicator 192.168.5.22/0 scram-sha-256
        - host all all 0.0.0.0/0 scram-sha-256

		# Добавление пользователя по умолчанию admin с паролем admin
		users:
        admin:
            password: admin
            options:
                - createrole
                - createdb

5. После настройки способа запуска PostgreSQL вставьте следующую конфигурацию, чтобы настроить, как PostgreSQL работает на каждом сервере.

Что касается сервера postgres01, PostgreSQL будет работать по IP-адресу 192.168.5.20 с каталогом данных /var/lib/patroni.

Кроме того, эта конфигурация создает нового пользователя с именем replicator для операции репликации и пользователя postgres в качестве суперпользователя/администратора с паролем (secretpassword).

Убедитесь, что вы измените IP-адрес и пароль по умолчанию (secretpassword).

# Конфигурация Patroni PostgreSQL
postgresql:
    # Адрес и порт прослушивания сервера PostgreSQL
    listen: 192.168.5.20:5432
    # Адрес подключения для клиентов PostgreSQL
    connect_address: 192.168.5.20:5432
    # Каталог данных для PostgreSQL
    data_dir: /var/lib/patroni
    # Путь к файлу pgpass
    pgpass: /tmp/pgpass

    # Конфигурация аутентификации
    authentication:
        # Репликация учетных данных пользователя
        replication:
            username: replicator
            password: rep-pass
        # Учетные данные суперпользователя
        superuser:
            username: postgres
            password: secretpassword

    # Дополнительные параметры PostgreSQL
    parameters:
        # Каталог для Unix сокета
        unix_socket_directories: '.'
        # Метод шифрования пароля
        password_encryption: 'scram-sha-256'

6. Вставьте следующую конфигурацию для установки тегов для вашего сервера PostgreSQL, определяющих его поведение в кластере, сохраните изменения и закройте файл.

# Конфигурация тегов Patroni
tags:
    # Предотвращает продвижение узла в случае отказа
    nofailover: false
    # Предотвращает учет узла балансировщиком нагрузки
    noloadbalance: false
    # Предотвращает создание реплики путем клонирования
    clonefrom: false
    # Предотвращает принудительное включение синхронной репликации
    nosync: false

7. Сохраните конфигурации и выполните следующие команды, чтобы совместно подготовить каталог данных Patroni, убедившись, что он правильно принадлежит и защищен для использования PostgreSQL.

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

# Создать каталог данных Patroni
mkdir -p /var/lib/patroni

# Установить владельца каталога данных Patroni на пользователя PostgreSQL
chown -R postgres:postgres /var/lib/patroni

# Установить права доступа к каталогу данных Patroni для обеспечения безопасности
chmod 700 /var/lib/patroni

8. Затем выполните следующие команды systemctl для запуска и проверки службы patroni.

systemctl start patroni
systemctl status patroni

На сервере postgres01 запускается сервер PostgreSQL, и кластер инициализируется. Кроме того, сервер postgres01 выбран в качестве лидера кластера.

Checking the Patroni service and verifying PostgreSQL cluster initialization

На сервере postgres02 сервер PostgreSQL запускается через Patroni и присоединяется к кластеру PostgreSQL через REST API.

Если все прошло успешно, вы увидите следующее сообщение:

Checking the Patroni service on the postgres02 server

На сервере postgres03 вывод будет аналогичен выводу сервера postgres02.

Checking the Patroni service on the postgres03 server

9. С инициализированным кластером PostgreSQL выполните следующую команду patronictl, чтобы отобразить список экземпляров PostgreSQL, управляемых Patroni.

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

В следующем выводе вы увидите, что ваш кластер PostgreSQL (postgres) запущен.

Обратите внимание, что ваш кластер работает с тремя участниками: postgres01 как кластерный Leader, postgres02, и postgres03 в роли Replica с режимом/состоянием streaming.

Checking the list of servers in the PostgreSQL Cluster

10. Наконец, выполните следующую команду systemctl, чтобы отключить автоматический запуск службы postgresql при загрузке системы.

Эта команда не выводит ничего в случае успеха, но является важной, так как Patroni контролирует новый сервер PostgreSQL.

sudo systemctl disable --now postgresql

Установка и настройка HAProxy в качестве балансировщика нагрузки

После развертывания кластера PostgreSQL, как сделать его доступным для клиентов и обеспечить аварийное восстановление при возникновении проблем? Решением является HAProxy в качестве балансировщика нагрузки перед вашим кластером PostgreSQL.

HAProxy – ваш главный инструмент, который позволяет вашему кластеру PostgreSQL обрабатывать различные нагрузки, интеллектуально распределять запросы и поддерживать высокую доступность.

? ПРИМЕЧАНИЕ: Установите HAProxy на отдельный сервер. В данном случае сервер HAProxy устанавливается на сервере haproxy с IP-адресом 192.168.5.16.

Чтобы установить и настроить HAProxy в качестве балансировщика нагрузки для кластера PostgreSQL, выполните следующие действия:

1. Откройте файл /etc/hosts с помощью выбранного вами текстового редактора, вставьте IP-адреса и имена хостов ваших серверов PostgreSQL, сохраните изменения и закройте файл.

192.168.5.20    postgres01
192.168.5.21    postgres02
192.168.5.22    postgres03

2. Затем выполните следующую команду, чтобы обновить свой индекс пакетов.

apt update
Updating the repository on the HAProxy server

3. После обновления выполните следующую команду для установки пакета haproxy на вашу систему.

apt install haproxy
Installing HAProxy via APT

4. Теперь выполните следующую команду, чтобы создать резервную копию конфигурации HARPOXY по умолчанию в /etc/haproxy/haproxy.cfg.orig.

Эта команда не выводит результаты, но является предосторожнонй мерой перед внесением изменений.

mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.orig

5. Затем создайте новый файл с названием /etc/haproxy/haproxy.cfg с помощью вашего предпочтительного редактора и вставьте следующую конфигурацию. Убедитесь, что вы заменяете каждый IP-адрес сервера PostgreSQL на свой собственный, сохраните файл и закройте редактор.

Эта конфигурация HAProxy настраивает HAProxy в качестве балансировщика нагрузки для вашего кластера PostgreSQL с двумя прокси, следующим образом:

  • stats – Этот блок работает на порту 8080 и отслеживает производительность сервера HAProxy и его бэкэндов.
  • postgres – Этот блок содержит конфигурацию балансировщика нагрузки для кластера PostgreSQL.
# Глобальные настройки конфигурации
global
    # Максимальное количество одновременных соединений
    maxconn 100      
    # Настройки ведения журнала      
    log 127.0.0.1 local2

# Настройки по умолчанию
defaults
    # Глобальная конфигурация журнала
    log global
    # Устанавливаем режим TCP
    mode tcp
    # Количество попыток
    retries 2
    # Таймаут клиента
    timeout client 30m
    # Таймаут соединения
    timeout connect 4s
    # Таймаут сервера
    timeout server 30m
    # Таймаут проверки
    timeout check 5s

# Конфигурация статистики
listen stats
    # Устанавливаем режим HTTP
    mode http
    # Привязываемся к порту 8080
    bind *:8080
    # Включаем статистику
    stats enable
    # URI статистики
    stats uri /

# Конфигурация PostgreSQL
listen postgres
    # Привязываемся к порту 5432
    bind *:5432
    # Включаем проверку HTTP
    option httpchk
    # Ожидаемый статус 200
    http-check expect status 200
    # Настройки сервера
    default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions
    # Определяем серверы PostgreSQL
    server postgres01 192.168.5.20:5432 maxconn 100 check port 8008
    server postgres02 192.168.5.21:5432 maxconn 100 check port 8008
    server postgres03 192.168.5.22:5432 maxconn 100 check port 8008

6. После настройки HAProxy выполните следующие команды systemctl, чтобы перезапустить и проверить (status) службу haproxy.

systemctl restart haproxy
systemctl status haproxy
Checking the HAProxy service status

7. Наконец, откройте выбранный веб-браузер и посетите IP-адрес HAProxy с портом 8080 (например, http://192.168.5.16:8080/). В выводе ниже вы увидите следующее:

В выводе ниже вы увидите следующее:

  • Прокси stats для мониторинга состояния HAProxy.
  • Прокси postgres является балансировщиком нагрузки для кластера PostgreSQL.
    Обратите внимание, что серверы postgres02 и postgres03 помечены как недоступные, так как оба работают в режиме streaming.
Checking HAProxy performance and information

Тестирование отказоустойчивости кластера PostgreSQL

После настройки HAProxy в качестве вашего надежного балансировщика нагрузки настало время протестировать ваш кластер PostgreSQL. Этот важный шаг позволит выявить устойчивость вашей системы высокой доступности. Вы должны обеспечить, чтобы ваш кластер PostgreSQL оставался надежным и отзывчивым даже в случае возможных отказов.

Для тестирования отказоустойчивости кластера PostgreSQL подключитесь к кластеру с вашего клиентского компьютера и проверьте операции по отказу, следуя этим шагам:

1. Войдите на ваш клиентский компьютер, откройте терминал и выполните нижеприведенную команду psql, чтобы подключиться к PostgreSQL через балансировщик нагрузки HAProxy.

psql -h 192.168.5.16 -p 5432 -U postgres

Введите ваш пароль от PostgreSQL, когда будет запрос. Необходимую информацию о пароле вы найдете в файле /etc/patroni/config.yml.

Connecting to PostgreSQL cluster via HAProxy load balancer

2. После установления соединения выполните следующий запрос, чтобы узнать, к какому серверу PostgreSQL вы подключены, и завершите текущую сессию PostgreSQL с помощью команды quit.

SELECT inet_server_addr() AS hostname;
quit

Если ваша установка PostgreSQL успешна, вы будете подключены к серверу postgres01.

Checking the IP address of the PostgreSQL server

3. Теперь переключитесь на сервер postgres01, выполните следующие команды для остановки службы patroni и list для проверки статуса кластеров PostgreSQL.

Этот шаг позволяет вам протестировать отказоустойчивость PostgreSQL.

systemctl stop patroni
patronictl -c /etc/patroni/config.yml list

Вы увидите, что состояние сервера postgres01 изменится на stopped, а новый лидер кластера будет делегирован серверу postgres03.

Stopping the Patroni service to test the failover

4. Вернитесь к мониторингу статистики HAProxy, и вы увидите, что сервер postgres01 недоступен, в то время как postgres03 теперь находится в состоянии UP.

Verifying the failover works in the HAProxy monitoring stats report

В качестве альтернативы выполните следующую команду patronictl, чтобы проверить состояние кластера PostgreSQL.

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

Как видно ниже, сервер postgres01 больше не является частью кластера.

Checking the PostgreSQL Cluster members via patronictl

5. Вернитесь на клиентскую машину и выполните следующую команду psql, чтобы подключиться к серверу PostgreSQL через HAProxy.

psql -h 192.168.5.16 -p 5432 -U postgres
Connecting to the PostgreSQL server via HAProxy

6. После подключения выполните следующий запрос, чтобы проверить текущий сервер PostgreSQL, к которому вы подключены.

SELECT inet_server_addr() AS hostname;
quit

Если автоматическое переключение прошло успешно, вы будете подключены к одному из запущенных серверов, который в данном случае является postgres03.

Checking the PostgreSQL server IP address

Заключение

Пройдя этот путь, вы погрузились в сложности обеспечения высокой доступности вашей базы данных PostgreSQL, используя мощную комбинацию Patroni и HAProxy. Легко справляясь с настройкой PostgreSQL и Patroni, вы искусно обрабатывали тонкости настройки сервера etcd.

Ваши навыки оркестрации проявились, когда вы создали устойчивый кластер PostgreSQL с Patroni и настроили балансировку нагрузки с использованием HAProxy. Кульминацией этого высоконапряженного приключения стало тщательное тестирование возможностей аварийного восстановления вашего кластера PostgreSQL.

Рассмотрите возможность расширения своих навыков, когда вы обдумываете свои достижения в создании надежной и устойчивой среды PostgreSQL. Почему бы не исследовать внедрение Patroni с Kubernetes для более динамичной среды? Или изучить тонкости настройки высокой доступности PostgreSQL в нескольких центрах обработки данных?

Source:
https://adamtheautomator.com/patroni/