OSEN-НИЙ SAAALEСкидка 50% на виртуальный хостинг и VDS
до 30.11.2025 Подробнее
Выберите продукт

PostgreSQL HA на VDS с Patroni: кластер, DCS и безопасный failover

Разбираем построение отказоустойчивого кластера PostgreSQL на VDS с Patroni: выбор и развёртывание DCS (etcd/Consul), сетевые правила, конфиг Patroni/Postgres, репликация, switchover и failover, безопасные таймауты, подключение клиентов, тестирование, бэкапы и мониторинг.
PostgreSQL HA на VDS с Patroni: кластер, DCS и безопасный failover

Зачем Patroni и когда он нужен

Если приложению необходима высокая доступность (HA) PostgreSQL и сокращение RTO/RPO до секунд, Patroni — один из самых зрелых и понятных инструментов. Он управляет экземплярами PostgreSQL, ведёт их состояние во внешнем DCS (Distributed Configuration Store) и автоматически выполняет failover при отказе лидера. Для небольших и средних продакшенов Patroni отлично чувствует себя на VDS, обеспечивая быстрый старт и прозрачную эксплуатацию.

Важная мысль: Patroni не заменяет резервные копии, дисциплину обновлений и мониторинг. Он лишь автоматизирует управляемый переход роли лидер/реплика, предотвращает split-brain и снижает время простоя. Всё остальное — ваша архитектура, инфраструктура и процедуры.

Архитектура кластера: роли, DCS, кворум

Минимальная живая схема — три узла PostgreSQL (1 лидер, 2 реплики) и отказоустойчивый DCS. Допускается запуск DCS на тех же узлах для экономии ресурсов, но для серьёзных нагрузок лучше выделить его отдельно. DCS хранит метаданные кластера (кто лидер, TTL, кандидаты), а Patroni на узлах конкурирует за лидерство, опираясь на эти данные.

Типовые DCS для Patroni: etcd, Consul и ZooKeeper. На практике чаще берут etcd или Consul из-за простоты и богатой операционной базы. Кворум DCS — нечётное число узлов (3, 5). Два узла в DCS — антипаттерн: при сетевой сегментации легко потерять кворум.

Выбор DCS: etcd vs Consul кратко

etcd — минималистичный key-value с сильной консистентностью, простой моделью и хорошей операционной базой. Consul — богаче по функционалу (DNS, Service Discovery, Health-checks), но это лишняя сложность, если вам нужен только реестр для Patroni. Если команда уже эксплуатирует Consul — берите его. Начинаете с нуля — чаще проще etcd.

Сетевые порты и безопасность

Откройте только необходимое и фильтруйте источники:

  • PostgreSQL: 5432/tcp (клиенты и репликация).
  • Patroni REST API: 8008/tcp (управление и здоровье; ограничьте доступом по сети и/или базовой аутентификацией).
  • etcd: 2379/tcp (client API), 2380/tcp (peer); шифруйте и аутентифицируйте.

Не публикуйте эти порты в Интернет без нужды. Используйте файрвол, шифрование на уровне DCS и PostgreSQL, независимую опорную синхронизацию времени. Для TLS-подключений используйте корпоративный PKI или оформите SSL-сертификаты.

Подготовка узлов VDS

Предположим три узла VDS с современной ОС (например, Debian/Ubuntu LTS), одинаковыми версиями PostgreSQL, временем (chrony) и системной локалью. На всех узлах создайте пользователя postgres, настройте SSH-доступ администратора и включите файрвол с минимально необходимыми правилами.

Установите пакеты PostgreSQL, Patroni и выбранный DCS. На Debian/Ubuntu это часто делается стандартными репозиториями. Версия PostgreSQL на всех узлах должна совпадать. Проверьте дисковые параметры (fsync, write cache, scheduler) и убедитесь, что каталоги данных и WAL на надёжном хранилище.

Состояние кластера etcd и базовая конфигурация на серверах Linux

Разворачиваем DCS (пример — etcd)

Для учебного стенда можно поднять 3 экземпляра etcd на тех же узлах. Для продакшена лучше выделить отдельные малые узлы. Включите TLS между участниками и клиентами, настройте аутентификацию и роли. Ниже — упрощённый пример без TLS для локальной сети (для реального продакшена обязательно включайте шифрование и авторизацию).

# Установка (пример для Debian/Ubuntu)
sudo apt update
sudo apt install etcd

# Базовая проверка версии
etcd --version

Сконфигурируйте каждый узел, указав уникальные имя/адрес и общий список участников. Пример для узла node1 (адаптируйте IP):

# /etc/default/etcd (или аналогичный файл окружения)
ETCD_NAME="node1"
ETCD_DATA_DIR="/var/lib/etcd"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
ETCD_ADVERTISE_CLIENT_URLS="http://10.0.0.11:2379"
ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://10.0.0.11:2380"
ETCD_INITIAL_CLUSTER="node1=http://10.0.0.11:2380,node2=http://10.0.0.12:2380,node3=http://10.0.0.13:2380"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="pg-ha-token"

Повторите для node2/node3 с их адресами. Запустите и проверьте кластер etcd:

sudo systemctl enable --now etcd
etcdctl endpoint status --write-out=json

Убедитесь, что все 3 участника видят друг друга и кворум есть. В продакшене дополнительно включите TLS и задайте пользователи/роли в etcd.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Конфигурация Patroni и PostgreSQL

Patroni запускает PostgreSQL, следит за здоровьем, управляет репликацией и переключениями. Базовый сценарий: один файл YAML на узел с общим блоком dcs и индивидуальными параметрами (имя узла, адреса). В bootstrap задаются опции initdb, а также первичный pg_hba.conf.

# /etc/patroni/node1.yml
scope: pg-ha
namespace: "/service/"
name: node1
restapi:
  listen: 0.0.0.0:8008
  connect_address: 10.0.0.11:8008
dcs:
  ttl: 10
  loop_wait: 5
  retry_timeout: 10
  maximum_lag_on_failover: 16MB
  postgresql:
    use_pg_rewind: true
    use_slots: true
    parameters:
      wal_level: replica
      hot_standby: on
      max_wal_senders: 10
      max_replication_slots: 10
      wal_keep_size: 256MB
      synchronous_commit: off
etcd:
  host: 10.0.0.11:2379,10.0.0.12:2379,10.0.0.13:2379
bootstrap:
  dcs:
    synchronous_mode: false
  initdb:
    - encoding: UTF8
    - data-checksums
  pg_hba:
    - host replication repl 10.0.0.0/24 md5
    - host all all 10.0.0.0/24 md5
postgresql:
  listen: 0.0.0.0:5432
  connect_address: 10.0.0.11:5432
  data_dir: /var/lib/postgresql/16/main
  bin_dir: /usr/lib/postgresql/16/bin
  authentication:
    replication:
      username: repl
      password: STRONG_REPL_PASSWORD
    superuser:
      username: postgres
      password: STRONG_POSTGRES_PASSWORD
tags:
  nofailover: false
  noloadbalance: false
  clonefrom: false
  nosync: false

На остальных узлах меняются только name, connect_address, пути и адреса. Убедитесь, что каталог данных пуст на старте первого кластера, либо используйте механизмы join/rewind.

Ключевые моменты:

  • ttl/loop_wait/retry_timeout определяют скорость детекции отказа и переизбрания лидера. Чем агрессивнее — тем выше риск ложных срабатываний при jitter. Начните с консервативных значений и тестируйте.
  • maximum_lag_on_failover ограничивает отставание кандидата при аварийном failover. Это ваш RPO-ограничитель.
  • use_pg_rewind помогает безопасно возвращать бывшего лидера в реплики после failover, если включены data-checksums и есть нужные WAL.
  • use_slots держит репликационные слоты, чтобы WAL не удалялись преждевременно. Следите за ростом WAL при недоступных репликах.
  • Синхронная репликация: включите synchronous_mode: true, если критично нулевое RPO, но учтите задержки и риски стопора при потере синхронного стендбая. Режим synchronous_mode_strict ещё жёстче — применяйте осознанно.

Запуск и порядок включения

Порядок: сначала DCS (etcd), затем Patroni на каждом узле. На первом запуске Patroni инициализирует кластер, поднимет лидера, остальные узлы склонируются и станут репликами. Проверьте REST-статусы и список узлов.

sudo systemctl enable --now patroni
patronictl -c /etc/patroni/node1.yml list

Репликация и сценарии переключений

Patroni управляет потоковой репликацией PostgreSQL и переключениями ролей:

  • Switchover — плановая смена лидера без потери данных. Используется для обновлений, обслуживания и балансировки.
  • Failover — аварийное переключение при недоступности лидера (по TTL на DCS). Возможна потеря последних транзакций в асинхронном режиме.

Команды администратора:

# Плановая смена лидера на указанный узел
patronictl -c /etc/patroni/node1.yml switchover --master node1 --candidate node2

# Принудительный failover (когда лидер недоступен)
patronictl -c /etc/patroni/node2.yml failover --candidate node2

# Снятие с узла права участвовать в failover
patronictl -c /etc/patroni/node3.yml edit-config

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

Подключение клиентов: виртуальный адрес или прокси

Клиенты должны всегда попадать на текущего лидера. Типовые варианты:

  • Виртуальный IP (VRRP/keepalived) — простой способ, когда сеть позволяет перемещать адрес между узлами.
  • TCP-прокси (HAProxy, nginx stream) — проксирование на активного лидера. Узнать лидера можно по REST Patroni или меткам DCS.
  • Пулеры (PgBouncer) — актуально для большого числа соединений; пулинг совмещают с логикой выбора лидера.

Если используете прокси, предусмотрите health-check к REST Patroni (порт 8008) с проверкой, что узел лидер. При VRRP гарантируйте быстрый перенос IP при switchover. По пулерам см. практики из материала «Руководство по PgBouncer и пулингу соединений» — это помогает снизить нагрузку на Postgres и ускорить переключения: PgBouncer: пулинг соединений для PostgreSQL.

Схема проксирования HAProxy на лидера PostgreSQL с проверкой статуса Patroni

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

Не выводите в прод без дотошных испытаний. Прогоны, которые надо сделать:

  • Остановка PostgreSQL на лидере и проверка автоматического failover.
  • Обрыв сети между лидером и DCS (симуляция изоляции лидера).
  • Потеря узла DCS и проверка поведения при деградации кворума.
  • Плановый switchover под нагрузкой и оценка паузы для клиента.

Настройте логирование Patroni и PostgreSQL так, чтобы видеть детальные причины переключения. Отдельно измерьте суммарное время: детекция отказа (TTL), выбор кандидата, запуск/поднятие ролей, перестройка прокси/VIP.

Производительность и типичные ловушки

Несколько практических советов:

  • WAL и задержки. Убедитесь, что хранилище держит нужный IOPS для WAL и что wal_keep_size хватает на окна недоступности реплик. Следите за ростом каталога WAL при отвалившихся репликах с включёнными слотами.
  • Синхрон против асинхрон. Синхронная репликация даёт минимальное RPO ценой латентности и риском стопора при потере синхронного участника. Взвесьте требования SLA и бюджет.
  • Таймауты Patroni. Слишком агрессивные значения ttl и loop_wait при нестабильной сети приводят к ложным failover. Начинайте с 10/5/10 и снижайте только после тестов.
  • Split-brain. Не запускайте DCS в 2 узла. Следите за временем: без корректной синхронизации часов TTL теряет смысл.
  • pg_rewind. Работает не всегда: если окно WAL слишком узкое или реплика сильно отставала. Иметь проверенный план re-provision реплики быстрее и надёжнее.

Обновления и обслуживание

Минорные обновления PostgreSQL и конфигурационные изменения делайте покаскадно: switchover на реплику, обновление бывшего лидера, возврат роли — и так по кругу. Patroni поддерживает rolling restart с контролируемыми паузами.

Мажорные апгрейды планируйте заранее: pg_upgrade с недолгой паузой или логическая репликация между кластерами разных версий. До начала — полный бэкап, валидация восстановления и тестовый апгрейд «в песочнице».

Безопасность: от DCS до клиентов

Минимальные требования:

  • Шифруйте трафик DCS (TLS) и включайте аутентификацию пользователей/ролей.
  • Ограничьте Patroni REST API по сети и используйте базовую аутентификацию.
  • В PostgreSQL настройте pg_hba.conf только на нужные подсети, применяйте SCRAM, разделяйте роли (репликация, приложения, администрирование).
  • Храните секреты вне репозиториев, применяйте ротацию паролей и аудит соединений.
  • Журналируйте доступы к DCS и Postgres, храните логи в централизованной системе.

Резервное копирование

HA — не замена бэкапам. Настройте регулярные горячие резервные копии и архивирование WAL (например, в объектное хранилище), периодически проводите восстановление на выделённом стенде. В кластере с Patroni удобно запускать бэкапы с реплики, чтобы снизить влияние на лидера, но восстановление тестируйте на той версии и с теми параметрами, что в проде. Подробности по PITR и архивированию WAL — в материале PITR, WAL и восстановление PostgreSQL.

Наблюдаемость и эксплуатация

Набор наблюдаемости:

  • Список узлов и роли: patronictl list.
  • REST Patroni: статусы, роль, lag — для health-check и дашбордов.
  • Метрики PostgreSQL: экспортёр, лаг репликации, чекпойнты, бэкграунд-автовакуум.
  • Мониторинг DCS: состояние кворума, задержки, лидер.

Заведите алерты на: потерю кворума DCS, отставание реплик выше порога, частые переключения лидера, переполнение WAL, отказ бэкапов.

Мини-чеклист перед релизом

Продублируйте этот список в runbook и отработайте на тестовом кластере до автоматизма.
  • DCS в 3 узла, проверен кворум, включены TLS и аутентификация.
  • Patroni: адекватные ttl, loop_wait, maximum_lag_on_failover, включён use_pg_rewind.
  • Репликация стабильна, lag в норме, слоты управляются, WAL не растут без контроля.
  • Путь клиента к лидеру оттестирован (VIP/прокси), health-check корректен.
  • Есть валидированные бэкапы, PITR проверен, есть план re-provision реплики.
  • Ограничены порты, настроены роли, аудит и экспорт метрик.
  • Отработаны сценарии switchover/failover под нагрузкой.

Итоги

Patroni с DCS (etcd или Consul) даёт предсказуемую, управляемую HA для PostgreSQL на VDS. Ключ к успеху — трезвые настройки таймаутов, аккуратная сеть, дисциплина бэкапов и мониторинга, а также регулярные тренировки сценариев отказа. Начните с трёх узлов, держите конфигурации под управлением, валидируйте каждый шаг и вы получите кластер, который действительно выдерживает сбои без сюрпризов.

Поделиться статьей

Вам будет интересно

etcd на VDS: практический гайд по snapshot, defrag и restore (в т.ч. для Kubernetes) OpenAI Статья написана AI (GPT 5)

etcd на VDS: практический гайд по snapshot, defrag и restore (в т.ч. для Kubernetes)

Надёжный backup для etcd — основа живучести Kubernetes и сервисов конфигурации. Разбираем, как снимать snapshot, когда делать comp ...
NGINX OpenTelemetry: otel‑модуль и OTLP‑exporter для трассировок и метрик OpenAI Статья написана AI (GPT 5)

NGINX OpenTelemetry: otel‑модуль и OTLP‑exporter для трассировок и метрик

Разбираем, как подружить NGINX с OpenTelemetry на проде: варианты установки otel‑модуля, настройка OTLP exporter (gRPC и HTTP), ин ...
Tailscale на VDS: ACL, exit node и стабильный внешний IP OpenAI Статья написана AI (GPT 5)

Tailscale на VDS: ACL, exit node и стабильный внешний IP

Разворачиваем Tailscale на VDS и превращаем его в управляемый exit node со строгими ACL и стабильным внешним IP. Пошагово разберём ...