Как использовать repmgr с Dockerized Postgresql?
Я пытаюсь создать установку Postgresql с репликацией и автоматическим переключением при сбое. Я хотел, чтобы он был многоразовым, масштабируемым и переносимым, поэтому я попытался использовать Docker для запуска Postgres. Я также не хотел изобретать велосипед, поэтому я попытался использовать repmgr, как это рекомендуется при настройке репликации postgres.
На первой машине я запустил мастер-узел, используя docker-compose и простой Dockerfile. Затем я добавил bash-скрипт для запуска после запуска контейнера. Похоже, мастер был настроен правильно.
Затем на второй машине я попытался запустить в режиме ожидания. Я начал postgres в докере и экспериментировал. Как мы можем прочитать в repmgr github repo, чтобы запустить режим ожидания, мне нужно клонировать master с помощью команды repmgr, которая использует pg_basebackup для внутреннего использования. Pg_basebackup не позволяет мне клонировать db в непустую директорию (pgdata), поэтому мне нужно удалить pgdata, созданную dockerized postgres, перед клонированием. Когда я это делаю, контейнер умирает, потому что, конечно, единственный сервис postgres умирает без файлов. Поэтому я не могу запустить команду repmgr после этого, потому что нет контейнера для его запуска:)
Поэтому я попытался создать еще один Dockerfile только для резервного копирования. Внутри pgdata удаляется, затем repmgr клонирует master, затем postgres запускается правильно. Там нет ошибок. Но когда я захожу на главную машину и проверяю, работает ли репликация - это не так.
- Можно ли запустить repmgr для dockerized postgres?
- Если так, то как? Что я делаю неправильно?
- Если нет, как я могу создать репликацию кластера postgres без ручной настройки каждого сервера? Вы знаете, не рассматривая серверы как домашних животных, но как крупного рогатого скота и т.д.
Файлы, которые я использовал и создал: docker-compose.yml (как главный, так и резервный узел):
version: '3'
services:
db:
build:
context: .
volumes:
- ${DATABASE_STORAGE_PATH}:/var/lib/postgresql/data
env_file:
- .env
environment:
- PGDATA=/var/lib/postgresql/data/pgdata
ports:
- ${DB_PORT}:5432
Мастер Dockerfile:
FROM postgres:9.6.4
# install repmgr
RUN apt-get update \
&& apt-get install -y repmgr
# COPY conf files
COPY repmgr.conf .
COPY postgres.replication.conf /var/lib/postgresql/data/pgdata/
RUN echo "include '/var/lib/postgresql/data/pgdata/postgres.replication.conf'" >> /var/lib/postgresql/data/pgdata/postgresql.conf
CMD ["postgres"]
Скрипт Bash, запускаемый при работающем контейнере postgres (master):
#!/bin/bash
CONTAINER_ID="replicatest2_db_1"
docker exec -d $CONTAINER_ID createuser -s repmgr -U postgres
docker exec -d $CONTAINER_ID createdb repmgr -O repmgr -U postgres
docker exec -d $CONTAINER_ID su postgres -c 'repmgr -f repmgr.conf master register'
Резервный docker-compose такой же. Резервный Dockerfile:
FROM postgres:9.6.4
# install repmgr
RUN apt-get update \
&& apt-get install -y repmgr
# COPY repmgr conf
COPY repmgr.conf .
RUN rm -rf /var/lib/postgresql/data/pgdata
RUN su postgres -c "repmgr -h {master-host} -p {master-port} -U repmgr -d repmgr -D /var/lib/postgresql/data/pgdata -f repmgr.conf standby clone"
CMD ["postgres"]
1 ответ
Вы можете использовать pg-dock, с pg-dock вы можете запустить dockerized postgres cluster с repmgr, в противном случае вы можете изучить проект и понять, как все это работает.
Удачи.