+7 495 230 03 03 8 800 222 50 03
DevOps

Настройка PostgreSQL Patroni Cluster

Patroni — это автоматическая система аварийного переключения для PostgreSQL. Patroni обеспечивает автоматическое и ручное переключение при отказе и хранит все важные данные в распределенном хранилище конфигурации (DCS) на базе систем ETCD, Consul и т.д.. Соединения приложения и базы данных не осуществляются напрямую, а маршрутизируются через прокси-сервер соединения, такой как HAProxy. Прокси определяет активный/главный узел, который в данный момент времени готов обрабатывать соединения. Использования прокси-сервера сводит к 0 шансы встретить split-brain в кластере баз данных.

Для развертывания сервиса потребуется создать инфраструктуру из 3-х виртуальных машин. 2 ВМ для кластера Postgresql и 1 для организации точки входа в кластер на базе HAproxy. На все ВМ устанавливаем ОС Ubuntu 20.04 Server.

Для решения задачи потребуется предварительная подготовка:

  1. ВМ для ReverseProxy RAM: 1 GB CPU: 2 Core HDD: 20 GB
  2. ВМ для PostgreSQL RAM: 8 GB CPU: 4 Core HDD: 40 GB

Установка ETCD

ETCD — это отказоустойчивое распределенное хранилище ключей/значений, используемое для хранения состояния кластера Postgres. Используя Patroni все узлы Postgres обмениваются данными с etcd для поддержания работоспособности кластера Postgres. На момент составления инструкции актуальная версия ETCD 3.5.5.

ETCD_VER=v3.5.5
 
# URL для загрузки диструбутива
GOOGLE_URL=https://storage.googleapis.com/etcd
GITHUB_URL=https://github.com/etcd-io/etcd/releases/download
DOWNLOAD_URL=${GITHUB_URL}
 
# Удаляем прошлые установки если не первая попытка, и создаем новую папку для установки.
rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
rm -rf /tmp/etcd-download-test && mkdir -p /tmp/etcd-download-test
 
# Скачиваем и распаковываем файлы приложения, удаляем временные файлы
curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
tar xzvf /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz -C /tmp/etcd-download-test --strip-components=1
rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
 
# Проверяем корректность установки
/tmp/etcd-download-test/etcd --version
/tmp/etcd-download-test/etcdctl version
mv /tmp/etcd-download-test/etcd* /usr/local/bin/

Настраиваем службу ETCD

Создаем пользователя для работы со службой.

sudo groupadd --system etcd
sudo useradd -s /sbin/nologin --system -g etcd etcd

Создаем и предоставляем права на каталога /var/lib/etcd пользователю etcd.

sudo mkdir -p /var/lib/etcd/
sudo mkdir /etc/etcd
sudo chown -R etcd:etcd /var/lib/etcd/
sudo chmod -R 700 /var/lib/etcd/

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

INT_NAME="eth1"
ETCD_HOST_IP=$(ip-адрес show $INT_NAME | grep "inetb" | awk '{print $2}' | cut -d/ -f1)
ETCD_NAME=$(hostname -s)
  1. INT_NAME — имя сетевого интерфейса, который будет использоваться для трафика кластера. У каждого сервера он может быть свой.
  2. ETCD_HOST_IP — внутренний IP-адрес указанного сетевого интерфейса. Он используется для обслуживания клиентских запросов и связи с узлами кластера etcd.
  3. ETCD_NAME — каждый элемент etcd должен иметь уникальное имя в пределах кластера etcd. Используемая команда установит имя etcd в соответствии с именем хоста текущего сервера.

Проверяем значения переменных. Если у какой-то из переменной не будет значения, служба автозапуска работать не будет.

echo $INT_NAME
echo $ETCD_HOST_IP
echo $ETCD_NAME

Создаем файл службы для сервиса ETCD.

cat << EOF > /etc/systemd/system/etcd.service
[Unit]
Description=etcd service
Documentation=https://github.com/coreos/etcd
  
[Service]
User=etcd
Type=notify
ExecStart=/usr/local/bin/etcd \
 --name ${ETCD_NAME} \
 --enable-v2=true \
 --data-dir /var/lib/etcd \
 --initial-advertise-peer-urls http://${ETCD_HOST_IP}:2380 \
 --listen-peer-urls http://${ETCD_HOST_IP}:2380 \
 --listen-client-urls http://${ETCD_HOST_IP}:2379,http://127.0.0.1:2379 \
 --advertise-client-urls http://${ETCD_HOST_IP}:2379 \
 --initial-cluster-token etcd-cluster-1 \
 --initial-cluster revproxy=http://10.15.73.170:2380,postgresql1=http://10.15.73.176:2380,postgresql2=http://10.15.73.177:2380 \
 --initial-cluster-state new \
 --heartbeat-interval 1000 \
 --election-timeout 5000
Restart=on-failure
RestartSec=5
  
[Install]
WantedBy=multi-user.target
EOF

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

systemctl daemon-reload
systemctl enable etcd
systemctl start etcd.service

Проверить состояние кластера после запуска.

systemctl status -l etcd.service
etcdctl member list
etcdctl endpoint status --write-out=table
etcdctl endpoint health

Установка PostgreSQL

Подключаем дополнительный репозиторий с дистрибутивами PostgreSQL и добавляем ключ шифрования. Обновляем кеш пакетов:

wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
echo "deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main" | sudo tee /etc/apt/sources.list.d/postgresql-pgdg.list > /dev/null
sudo apt update

Устанавливаем PostgreSQL, проверяем наличие установленных пакетов.

sudo apt install postgresql-14
dpkg -l | grep postgresql

Останавливаем службу PostgreSQL если она сама запустилась. Управлением сервисом PostgreSQL будет заниматься Patroni.

sudo systemctl stop postgresql
sudo systemctl disable postgresql

Установка Patroni

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

sudo apt -y install python3 python3-pip
sudo -H pip install --upgrade testresources
sudo -H pip install --upgrade setuptools
sudo -H pip install psycopg2
sudo -H pip install patroni
sudo -H pip install python-etcd

Создаем файл конфигурации для кластера Patroni /etc/patroni.yml. Конфигурационный файл необходимо создать на всех ВМ с PostgreSQL.

scope: postgres
name: postgresql2
 
restapi:
    listen: 0.0.0.0:8008
    connect_address: 10.15.73.177:8008
 
etcd:
    host: revproxy:2379
 
bootstrap:
  dcs:
    ttl: 30
    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"
        logging_collector: "on"
        max_wal_senders: 5
        max_replication_slots: 5
 
  initdb:
  - encoding: UTF8
  - data-checksums
 
  pg_hba:
  - host replication replicator 127.0.0.1/32 trust
  - host replication replicator 10.15.73.177/24 md5
  - host all all 10.15.73.1/24 md5
  - host all all 0.0.0.0/0 md5
 
  users:
    admin:
      password: ********************
      options:
        - createrole
        - createdb
 
postgresql:
  listen: 0.0.0.0:5432
  connect_address: 10.15.73.177:5432
  data_dir: "/data/patroni"
  pgpass: /tmp/pgpass
  authentication:
    replication:
      username: replicator
      password: ********************
    superuser:
      username: postgres
      password: ********************
  parameters:
    unix_socket_directories: '/var/run/postgresql'
 
tags:
    nofailover: false
    noloadbalance: false
    clonefrom: false
    nosync: false

Проверяем конфигурацию. На всех ВМ с PostgreSQL.

patroni --validate-config /etc/patroni.yml

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

sudo mkdir -p /data/patroni
sudo chown postgres:postgres /data/patroni
sudo chmod 700 /data/patroni

Создаем файл службы для автозапуска Patroni. На всех ВМ с PostgreSQL.

sudo nano /etc/systemd/system/patroni.service

Содержание.

[Unit]
Description=High availability PostgreSQL Cluster
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.target

Запускаем Patroni. Проверяем состояние службы. На всех ВМ с PostgreSQL.

sudo systemctl start patroni
sudo systemctl status patroni

Установка HAproxy

HAproxy предоставляет единую точку, к которой подключатся приложения работающие с базой данных. Контроль за узлами входа в кластер баз данных осуществляет HAProxy на основе информации от Patroni. Установка HAProxy.

sudo apt -y install haproxy

Настройка конфигурации для HAproxy

Создаем копии конфигурационного файла для изменения. Редактируем базовый конфигурационный файл под наши требованиями.

sudo cp -p /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg-orig
sudo nano /etc/haproxy/haproxy.cfg

Содержимое файла конфигурации. IP-адреса используем свои.

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 patroni1 10.15.73.176:5432 maxconn 100 check port 8008
    server patroni2 10.15.73.177:5432 maxconn 100 check port 8008

Проверяем конфигурационный файл на наличие ошибок.

sudo /usr/sbin/haproxy -c -V -f /etc/haproxy/haproxy.cfg

Запускаем службу. Проверяем состояние.

sudo systemctl restart haproxy
sudo systemctl status haproxy

Переходим на WEB-интерфейс и проверяем корректность работы. WEB-интерфейс доступен по IP-адресу или имени ВМ на порту 7000.

Настройка кластера Postgresql Patroni завершена, для доступа в кластер используется прокси-сервер HAproxy, для хранения состояние кластера Patroni используется ETCD-хранилище, состоящее из 3-х нод. Patroni полностью управляет переключением и работой кластера Postgresql.

Мы можем помочь в настройке Patroni PostgreSQL кластера, а также его поддержке в рамках DevOps-аутсорсинга!

Дата публикации: 1 августа 2023
Не нашли ответа на свой вопрос?

Смотрите также

Обсуждение материала

  • Аноним

    при попытке запустить сервис etcd выдает ошибку
    Jun 07 16:45:40 vm3 systemd[5512]: etcd.service: Failed to execute command: Permission denied
    Jun 07 16:45:40 vm3 systemd[5512]: etcd.service: Failed at step EXEC spawning /usr/local/bin/etcd: Permission denied

Содержание

Заказать звонок

Оставьте свои данные для того, чтобы специалист с вами связался.

*нажимая на кнопку, Вы даете согласие на обработку персональных данных
Быстрое внедрение включает:
На сервере установлено следующее ПО (доступно при подключении по протоколу RDP):
Также настроено:
Перед внедрением клиент предоставляет информацию о пользователях (логины и пароли). После завершения работ, клиенту высылается инструкция и ярлык для подключения.
Индивидуальное внедрение по ТЗ клиента обсуждается отдельно.