Patroni
Patroni — это Python-приложение для создания высокодоступных кластеров QHB на основе потоковой репликации. Оно используется такими компаниями, как Red Hat, IBM Compose, Zalando и многие другие. С его помощью можно преобразовать систему из основного и резервного серверов в высокодоступный кластер с поддержкой автоматического контролируемого и аварийного переключения. Patroni позволяет легко добавлять новые реплики в существующий кластер, поддерживает динамическое изменение конфигурации QHB одновременно на всех серверах кластера, а также множество других возможностей, таких как синхронная репликация, настраиваемые действия при переключении узлов, REST API, возможность запуска пользовательских команд для создания реплики.
Одна из возможных комбинаций стека технологий для организации высокодоступных кластеров:
- QHB в качестве СУБД;
- Patroni в качестве решения для кластеризации;
- etcd или consul в качестве распределенного хранилища для Patroni.
Patroni является приложением с открытым исходным кодом, поэтому для удобства использования и для совместимости с QHB мы вносим изменения в исходные пакеты. Совместимые пакеты Patroni находятся в репозиториях QHB.
Установка компонентов
Установка etcd
Пример установки на CentOS 7:
yum install etcd
Также возможна установка через пакеты или исходный код по документации на установку etcd.
Рекомендуется устанавливать etcd на отдельных машинах, где не будут установлены узлы Patroni и QHB, так как для etcd очень важна нагрузка на диски. Для штатной работы кластера etcd минимальное количество узлов — три. Для разработки и тестирования можно использовать один узел.
Установка Consul
В связи с ограничениями Hashicorp на данный момент установка возможна только с использованием VPN.
Установка выполняется через пакеты с ресурса pkgs.org, либо по документации на установку Consul.
Серверы Consul — это место, где хранятся и реплицируются данные Patroni. Поэтому рекомендованное минимальное количество узлов — три. Для разработки и тестирования можно использовать один узел. Для продуктивных высоконагруженных систем следует разворачивать сервисы Consul на отдельных от Patroni и QHB машинах.
Клиент Consul также является членом системы и может подключаться к кластеру серверов Consul для получения информации об инфраструктуре. Клиента можно расположить на сервере с Patroni и QHB для подключения к кластеру серверов Consul через локального клиента Consul.
Установка QHB
Для установки обратитесь к документации по установке QHB.
Создание и запуск сервиса QHB, а также инициализация кластера базы данных не требуется. Все управление кластером СУБД осуществляется через Patroni.
Установка Patroni
Patroni требуется установить на тех же машинах, где уже установлены серверы QHB.
Имя пакета для установки qhb-patroni
Для установки обратитесь к документации по установке QHB.
Обращаем внимание, что для работы с QHB выпущен специализированный пакет qhb-patroni. Стандартный Patroni для PostgreSQL не может использоваться совместно с QHB.
Проверьте версию qhb-patroni:
patroni --version
Результат: Patroni 3.0.2
Настройка компонентов
Настройка etcd
Выполняется независимо от Patroni и QHB, может быть выполнена предварительно (подробнее см. в официальной документации etcd). Для конфигурации каждого узла etcd нужно внести необходимые для запуска параметры в файл /etc/etcd/etcd.conf. Также предварительно на каждом из узлов необходимо создать каталог под данные etcd, например /var/lib/etcd/default.etcd. Ниже представлен пример минимальной конфигурации узлов на 3 машинах с адресами: X.X.X.101, X.X.X.102, X.X.X.103.
Для первого узла:
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="http://X.X.X.101:2380"
ETCD_LISTEN_CLIENT_URLS="http://X.X.X.101:2379,http://127.0.0.1:2379"
ETCD_NAME="etcd0"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://X.X.X.101:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://X.X.X.101:2379"
ETCD_INITIAL_CLUSTER="etcd0=http://X.X.X.101:2380,etcd1=http://X.X.X.102:2380,etcd2=http://X.X.X.103:2380"
ETCD_INITIAL_CLUSTER_TOKEN="qhb_token"
Для второго узла:
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="http://X.X.X.102:2380"
ETCD_LISTEN_CLIENT_URLS="http://X.X.X.102:2379,http://127.0.0.1:2379"
ETCD_NAME="etcd1"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://X.X.X.102:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://X.X.X..102:2379"
ETCD_INITIAL_CLUSTER="etcd0=http://X.X.X.101:2380,etcd1=http://X.X.X.102:2380,etcd2=http://X.X.X.103:2380"
ETCD_INITIAL_CLUSTER_TOKEN="qhb_token"
Для третьего узла:
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="http://X.X.X.103:2380"
ETCD_LISTEN_CLIENT_URLS="http://X.X.X.103:2379,http://127.0.0.1:2379"
ETCD_NAME="etcd2"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://X.X.X.103:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://X.X.X.103:2379"
ETCD_INITIAL_CLUSTER="etcd0=http://X.X.X.101:2380,etcd1=http://X.X.X.102:2380,etcd2=http://X.X.X.103:2380"
ETCD_INITIAL_CLUSTER_TOKEN="qhb_token"
Базу данных etcd при пересоздании кластера нужно переинициализировать, удаляя данные в каталоге /var/lib/etcd/default.etcd.
Создайте сервис etcd на каждом из узлов для удобного управления кластером:
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
WorkingDirectory=/var/lib/etcd/
EnvironmentFile=-/etc/etcd/etcd.conf
User=etcd
# установить в GOMAXPROCS число процессоров
ExecStart=/bin/bash -c "GOMAXPROCS=$(nproc) /usr/bin/etcd --name=\"${ETCD_NAME}\" --data-dir=\"${ETCD_DATA_DIR}\" --listen-client-urls=\"${ETCD_LISTEN_CLIENT_URLS}\""
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
Настройка Consul
Выполняется независимо от Patroni и QHB, может быть выполнена предварительно (подробнее см. в официальной документации Consul). Для конфигурации каждого узла кластера серверов consul нужно внести необходимые для запуска параметры в файл /etc/consul.d/config.json.
Ниже представлен пример минимальной конфигурации узлов на 3 машинах. Адреса и доменные имена:
X.X.X.101, qhb-srv-01.quantom.local;
X.X.X.102, qhb-srv-02.quantom.local;
X.X.X.103, qhb-srv-03.quantom.local.
Для первого узла кластера серверов consul (для второго и третьего узла изменить bind_addr и client_addr):
{
"bind_addr": "X.X.X.101",
"bootstrap_expect": 3,
"client_addr": "X.X.X.101",
"datacenter": "dc1",
"data_dir": "/opt/consul",
"domain": "consul",
"enable_script_checks": true,
"dns_config": {
"enable_truncate": true,
"only_passing": true
},
"enable_syslog": true,
"encrypt": "v6+HtK6JQ6kX2XgYkSFQM9KFXF1YeGyFHcRo6hWZbjI=",
"leave_on_terminate": true,
"log_level": "INFO",
"rejoin_after_leave": true,
"retry_join": [
"qhb-srv-01.quantom.local",
"qhb-srv-02.quantom.local",
"qhb-srv-03.quantom.local"
],
"server": true,
"start_join": [
"qhb-srv-01.quantom.local",
"qhb-srv-02.quantom.local",
"qhb-srv-03.quantom.local"
],
"ui_config": { "enabled": true }
}
Для подключения к кластеру серверов consul можно создать клиента consul (например, разместить на серверах с Patroni). При такой конфигурации Patroni подключается к локальному клиенту consul, который обращается ко всему кластеру серверов consul.
Для конфигурации клиента consul необходимо внести необходимые для запуска параметры в файл /etc/consul.d/config.json.
Пример минимальной конфигурации клиента:
{
"bind_addr": "X.X.X.104",
"client_addr": "X.X.X.104",
"datacenter": "dc1",
"node_name": "client01",
"data_dir": "/opt/consul",
"domain": "consul",
"enable_script_checks": true,
"dns_config": {
"enable_truncate": true,
"only_passing": true
},
"enable_syslog": true,
"encrypt": "v6+HtK6JQ6kX2XgYkSFQM9KFXF1YeGyFHcRo6hWZbjI=",
"leave_on_terminate": true,
"log_level": "INFO",
"rejoin_after_leave": true,
"retry_join": [
"qhb-srv-01.quantom.local",
"qhb-srv-02.quantom.local",
"qhb-srv-03.quantom.local"
],
"server": false,
"start_join": [
"qhb-srv-01.quantom.local",
"qhb-srv-02.quantom.local",
"qhb-srv-03.quantom.local"
],
"ui_config": { "enabled": true }
}
Каждую конфигурацию необходимо проверить на допустимость:
consul validate /etc/consul.d/config.json
Создайте сервис consul на каждом из узлов для удобного управления кластером:
[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 \
-node=qhb-srv-01.quantom.local \
-config-dir=/etc/consul.d
ExecReload=/bin/kill -HUP $MAINPID
KillSignal=SIGINT
TimeoutStopSec=5
Restart=on-failure
SyslogIdentifier=consul
[Install]
WantedBy=multi-user.target
Настройка Patroni
На каждом хосте с qhb-patroni необходимо создать директорию под кластер баз данных QHB и раздать необходимые права пользователю qhb, например, /mnt/patroni:
mkdir -p /mnt/patroni
chown qhb:qhb /mnt/patroni
chmod 700 /mnt/patroni
Создайте конфигурационный файл с расширением .yml на каждом хосте с qhb-patroni. Можете скопировать примеры конфигурационных файлов в rpm системах /usr/share/doc/patroni-3.0.2/qhb1.yml (qhb2.yml) и в deb системах /usr/share/doc/patroni/qhb1.yml (qhb2.yml) Подробнее параметры конфигурации описаны в документации Patroni.
Кроме основных параметров конфигурации, указанных в документации Patroni, в реализации qhb-patroni добавлены дополнительные параметры для управления QHB:
# параметры QHB
hba_file: qhb_hba.conf
ident_file: qhb_ident.conf
database: qhb
config_base_name: qhb
Ниже представлен пример минимальной конфигурации кластера qhb-patroni на 2 хостах с адресами: X.X.X.104, X.X.X.105.
Примечание
В примере указаны параметры подключения к etcd, для работы с consul раскомментируйте и добавьте необходимые строки.
qhb0.yml
для первого узла кластера qhb-patroni:
scope: cluster
# пространство имен: /служба/
name: qhb0
restapi:
listen: 127.0.0.1:8008
connect_address: 127.0.0.1:8008
etcd:
# Использовать «хосты» для предоставления нескольких рабочих станций
hosts:
- X.X.X.101:2379
- X.X.X.102:2379
- X.X.X.103:2379
#consul:
#хост: X.X.X.104:8500
bootstrap:
# этот раздел будет записан в etcd/Consul:/<пространство_имен>/<область_применения>/config
# после инициализации нового кластера, и все остальные члены кластера будут
# использовать его в качестве «общих настроек»
dcs:
ttl: 30
loop_wait: 10
retry_timeout: 10
maximum_lag_on_failover: 1048576
postgresql:
use_pg_rewind: true
# некоторые желаемые параметры для 'initdb'
initdb: # Примечание: Это должен быть список (для некоторых параметров
# нужны значения, а другие являются флагами)
- encoding: UTF8
- data-checksums
pg_hba: # Добавить следующие строки в qhb_hba.conf после запуска 'initdb'
- host replication replicator 127.0.0.1/32 md5
- host replication replicator X.X.X.0/24 md5
- host all all 0.0.0.0/0 md5
# Некоторые дополнительные пользователи, которых нужно создать после
# инициализации нового кластера
users:
admin:
password: admin
options:
- createrole
- createdb
postgresql:
listen: 127.0.0.1,X.X.X.104,::1:5432
connect_address: X.X.X.104:5432
data_dir: /mnt/patroni
bin_dir: /usr/local/qhb/bin
pgpass: /tmp/pgpass0
authentication:
replication:
username: replicator
password: rep-pass
superuser:
username: qhb
password: qhb
rewind:
username: rewind_user
password: rewind_password
parameters:
unix_socket_directories: '.'
# параметры QHB
hba_file: qhb_hba.conf
ident_file: qhb_ident.conf
database: qhb
config_base_name: qhb
tags:
nofailover: false
noloadbalance: false
clonefrom: false
qhb1.yml
для второго узла кластера qhb-patroni:
scope: cluster
# пространство имен: /служба/
name: qhb1
restapi:
listen: 127.0.0.1:8008
connect_address: 127.0.0.1:8008
etcd:
# Использовать «хосты» для предоставления нескольких рабочих станций
hosts:
- X.X.X.101:2379
- X.X.X.102:2379
- X.X.X.103:2379
#consul:
#хост: X.X.X.105:8500
bootstrap:
# этот раздел будет записан в etcd/Consul:/<пространство_имен>/<область_применения>/config
# после инициализации нового кластера, и все остальные члены кластера будут
# использовать его в качестве «общих настроек»
dcs:
ttl: 30
loop_wait: 10
retry_timeout: 10
maximum_lag_on_failover: 1048576
postgresql:
use_pg_rewind: true
# некоторые желаемые параметры для 'initdb'
initdb: # Примечание: Это должен быть список (для некоторых параметров
# нужны значения, а другие являются флагами)
- encoding: UTF8
- data-checksums
pg_hba: # Добавить следующие строки в qhb_hba.conf после запуска 'initdb'
- host replication replicator 127.0.0.1/32 md5
- host replication replicator X.X.X.0/24 md5
- host all all 0.0.0.0/0 md5
# Некоторые дополнительные пользователи, которых нужно создать после инициализации нового кластера
users:
admin:
password: admin
options:
- createrole
- createdb
postgresql:
listen: 127.0.0.1,X.X.X.105,::1:5432
connect_address: X.X.X.105:5432
data_dir: /mnt/patroni
bin_dir: /usr/local/qhb/bin
pgpass: /tmp/pgpass0
authentication:
replication:
username: replicator
password: rep-pass
superuser:
username: qhb
password: qhb
rewind:
username: rewind_user
password: rewind_password
parameters:
unix_socket_directories: '.'
# параметры QHB
hba_file: qhb_hba.conf
ident_file: qhb_ident.conf
database: qhb
config_base_name: qhb
tags:
nofailover: false
noloadbalance: false
clonefrom: false
Для проверки работоспособности необходимо провести проверку конфигурации и при необходимости исправить все ошибки, например, если конфигурация первого узла кластера расположена в /opt/patroni/:
patroni --validate-config /opt/patroni/qhb0.yml
При необходимости создайте сервис qhb-patroni на каждом из узлов для удобного управления кластером qhb-patroni. Сервис располагается в /usr/lib/systemd/system/qhb-patroni.service.
# Это пример файла конфигурации systemd для Patroni
# Вы можете скопировать его в "/etc/systemd/system/patroni.service",
[Unit]
Description=Runners to orchestrate a high-availability QHB
After=syslog.target network.target
[Service]
Type=simple
User=qhb
Group=qhb
# Прочитать в файле конфигурации, если таковой существует, иначе продолжить
EnvironmentFile=-/etc/patroni_env.conf
# WorkingDirectory = /var/lib/pgsql
# Куда отправлять сообщения о раннем запуске от сервера
# Обычно это определяется общей настройкой в systemd
#StandardOutput=syslog
# Прекоманды для запуска устройства наблюдения
# Конвертировать комментарий, если устройство наблюдения является частью вашей установки patroni
#ExecStartPre=-/usr/bin/sudo /sbin/modprobe softdog
#ExecStartPre=-/usr/bin/sudo /bin/chown qhb /dev/watchdog
# Запустить процесс patroni
# См. примеры файлов конфигурации для QHB в /usr/share/doc/patroni-3.0.2/qhb*.yml
ExecStart=/usr/bin/patroni /opt/qhb1.yml
# Переслать HUP для загрузки с patroni.yml
ExecReload=/usr/bin/kill -s HUP $MAINPID
# приостановить процесс patroni, но не его дочерние процессы, чтобы он постепенно остановил qhb
KillMode=process
# Выждать достаточное время, чтобы сервер запустился/остановился
TimeoutSec=30
# Не перезапускать службу в случае сбоя; мы хотим вручную проверить базу данных на ошибки
Restart=no
[Install]
WantedBy=multi-user.target
Запуск компонентов
Запуск etcd
Предварительно убедитесь, что у вас добавлены необходимые правила в firewall.
Для запуска etcd через сервис на всех узлах необходимо выполнить
systemctl start etcd
. Команда на всех узлах завершится, когда узлы найдут друг
друга, т. е. когда команда будет выполнена на втором и третьем хосте. При
пересоздании кластера нужно предварительно очистить базы etcd.
Состав кластера etcd можно посмотреть командой etcdctl member list
.
Запуск Consul
Предварительно убедитесь, что у вас добавлены необходимые правила в firewall.
Для запуска etcd через сервис на всех узлах серверов и клиентах необходимо выполнить
systemctl start consul
.
По адресу http(s) любого участника кластера, например http://X.X.X.101:8500, можно посмотреть состав кластера (сервера и клиенты) и текущего лидера. Подробнее в официальной документации Consul.
Запуск Patroni
Предварительно убедитесь, что у вас добавлены необходимые правила в firewall.
Запуск необходимо производить только после запуска распределенного хранилища — etcd или consul.
Для запуска первого узла qhb-patroni необходимо из под пользователя qhb
выполнить patroni /opt/qhb0.yml
. При успешном запуске первого узла также
запустите остальные узлы, указав соответствующие файлы конфигурации.
Для запуска qhb-patroni через сервис на всех узлах необходимо выполнить
systemctl start qhb-patroni
.
Состояние и состав кластера qhb-patroni можно посмотреть на любом узле, например
patronictl -c /opt/qhb0.yml list
.
При штатной работе вы увидите State — running
у всех участников кластера.
Работа, переключение
При остановке работы СУБД на хосте 104 СУБД на хосте 105 становится основной.
При включении в работу СУБД на хосте 104 она становится резервной.
Если останавливается работа мастера на хосте 105 основным становится хост 104.