Подтвердить что ты не робот

Как смоделировать отказоустойчивый кластер PostgreSQL с помощью Docker/Kubernetes?

Я все еще обнимаю Кубернеса и как это должно работать. В настоящее время я пытаюсь понять, как моделировать что-то вроде кластера PostgreSQL с потоковой репликацией, масштабированием и автоматическим отказоустойчивостью/откатом (pgpool-II, repmgr, выбрать ваш яд).

Моя основная проблема с этим подходом - двойственная природа экземпляра PostgreSQL, конфигурация - это либо мастер, либо холодный/теплый/горячий режим ожидания. Если я увеличиваю количество реплик, я бы ожидал, что они все придут как standbys, поэтому я бы предположил создать контроллер репликации postgresql-standby отдельно от модуля postgresql-master. Однако я ожидаю, что один из этих standbys станет мастером в случае, если текущий мастер не работает, поэтому он является общим контроллером репликации postgresql.

Единственная идея, которую я имел до сих пор, - это установить конфигурацию репликации на внешний том и управлять изменениями состояния и состояния вне контейнеров.

(в случае PostgreSQL конфигурация, вероятно, уже будет находиться на томе внутри его каталога data, который сам, очевидно, будет мне нужен на томе, но это не так)

Правильно ли это соответствует, или есть ли другой более чистый способ?

4b9b3361

Ответ 1

Вот пример в OpenShift: https://github.com/openshift/postgresql/tree/master/examples/replica Принцип тот же в чистом Kube (он не использует ничего действительно OpenShift, и вы можете использовать изображения в простой докер)

Ответ 2

Kubernetes statefulset является хорошей базой для создания службы с сохранением состояния. Вам по-прежнему потребуется некоторая работа по настройке правильного членства в репликах PostgreSQL.

У Кубернете есть один пример. http://blog.kubernetes.io/2017/02/postgresql-clusters-kubernetes-statefulsets.html

Ответ 3

Вы можете дать PostDock попробовать либо с помощью docker-compose, либо с Kubernetes. В настоящее время я пробовал это в нашем проекте с помощью docker-compose со схемой, как показано ниже:

pgmaster (primary node1)  --|
|- pgslave1 (node2)       --|
|  |- pgslave2 (node3)    --|----pgpool (master_slave_mode stream)----client
|- pgslave3 (node4)       --|
   |- pgslave4 (node5)    --|

Я тестировал следующие сценарии, и все они работают очень хорошо:

  • Репликация: изменения, сделанные на основном (то есть главном) node, будут реплицированы во все резервные (т.е. подчиненные) узлы
  • Отказоустойчивость: останавливает основной node, а резервный node (например, node4) автоматически возьмет на себя основную роль.
  • Предотвращение двух первичных узлов: воскресить предыдущий первичный node (node1), node4 будет продолжаться как основной node, а node1 будет синхронизирован, но в режиме ожидания node.

Что касается клиентского приложения, все эти изменения прозрачны. Клиент просто указывает на pgpool node и сохраняет работоспособность во всех вышеперечисленных сценариях.

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

Pgpool-II с Watchdog

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

master (primary node1)  --\
|- slave1 (node2)       ---\     / pgpool1 (active)  \
|  |- slave2 (node3)    ----|---|                     |----client
|- slave3 (node4)       ---/     \ pgpool2 (standby) /
   |- slave4 (node5)    --/

Я тестировал следующие сценарии, и все они работают очень хорошо:

  • Обычный сценарий: запускаются оба pgpool, при этом виртуальный IP автоматически применяется к одному из них, в моем случае pgpool1
  • Отказоустойчивость: выключение pgpool1. Виртуальный IP будет автоматически применен к pgpool2, который, следовательно, станет активным.
  • Ошибка запуска pgpool: снова запустите pgpool1. Виртуальный IP будет храниться с pgpool2, а pgpool1 теперь работает как резервный.

Что касается клиентского приложения, все эти изменения прозрачны. Клиент просто указывает на виртуальный IP-адрес и продолжает работать нормально во всех вышеупомянутых сценариях.

Вы можете найти этот проект в мой репозиторий GitHub на ветке сторожевого пса.