База данных Postgres настраивается в режиме асинхронной репликации Master + Replica.
Настройка Postgres Master
На Master сервере запускается docker container с Postgres. К контейнеру с помощью volumes монтируются файлы конфигурации в директорию /etc/postgresql и скрипт настройки БД в директорию /docker-entrypoint-initdb.d/. Также к рабочей data-дирректории контейнера монтируется именованный том eccm_postgres
На рабочую директорию в контейнере указывает переменная окружения $PGDATA
docker exec -ti postgres env | grep PGDATA
PGDATA=/var/lib/postgresql/data
Пример docker-compose.yml
version: '3.7' services: postgres: image: hub.eltex-co.ru/eccm/timescaledb:pg14 ports: - 5432:5432 volumes: - postgres:/var/lib/postgresql/data - ./data/postgresql.conf:/etc/postgresql/postgresql.conf - ./data/pg_hba.conf:/etc/postgresql/pg_hba.conf environment: PGDATA: /var/lib/postgresql/data POSTGRES_DB: postgres POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} TZ: ${POSTGRES_TIMEZONE} PGTZ: ${POSTGRES_TIMEZONE} shm_size: ${POSTGRES_SHM_SIZE:-8gb} restart: always command: # файл конфигурации нельзя расположить по стандартному пути, т.к. entrypoint его перезапишет при старте - postgres - -c - config_file=/etc/postgresql/postgresql.conf - -c - hba_file=/etc/postgresql/pg_hba.conf labels: logger_type: postgres_default mem_limit: 2048m volumes: postgres:
После старта контейнера каталог PGDATA будет заполнен файлами и каталогами, которые можно также обнаружить в примонтированном к контейнеру именованном томе.
Узнать прямой путь смонтированного каталога именного тома на хостовой машине можно по команде:
docker volume inspect --format '{{ .Mountpoint }}' eccm_postgres
postgresql.conf - содержит основную конфигурацию Postgres, в которой нами производится тюнинг параметров для увеличения эффективности Postgres, а также информация по репликации Postgres.
Для тюнинга конфигурации Postgres рекомендуется использовать следующий сервис: https://pgtune.leopard.in.ua/#/
Пример postgresql.conf
max_connections = 200 shared_buffers = 2GB effective_cache_size = 4GB checkpoint_completion_target = 0.7 wal_buffers = 16MB default_statistics_target = 100 random_page_cost = 4 effective_io_concurrency = 1 work_mem = 10MB min_wal_size = 1GB max_wal_size = 4GB max_worker_processes = 16 timescaledb.max_background_workers = 16 max_parallel_workers_per_gather = 2 max_parallel_workers = 4 max_parallel_maintenance_workers = 2 maintenance_work_mem = 256MB synchronous_commit = off log_min_duration_statement = 3000 log_duration = off log_statement = 'none' listen_addresses = '*' datestyle = 'iso, mdy' default_text_search_config = 'pg_catalog.english' shared_preload_libraries = 'pg_stat_statements, timescaledb' timescaledb.telemetry_level = off password_encryption = md5 # Replication settings for master or slave wal_level = replica wal_log_hints = on max_wal_senders = 10 #wal_keep_segments = 8 max_replication_slots = 10 hot_standby = on
pg_hba.conf - содержит параметры доступа к Postgres
Пример pg_hba.conf
# TYPE DATABASE USER ADDRESS METHOD # "local" is for Unix domain socket connections only local all all trust # IPv4 local connections: host all all 127.0.0.1/32 trust # IPv6 local connections: host all all ::1/128 trust # Allow replication connections from localhost, by a user with the # replication privilege. local replication all trust host replication all 127.0.0.1/32 trust host replication all ::1/128 trust host replication replicator 0.0.0.0/0 trust host all all all md5 host all all all trust host replication postgres all md5 host replication postgres all trust
Старт контейнера с Postgres
docker-compose -up -d postgres-eccm
Postgres Master готов к работе.
Настройка Postgres Replica.
Файл docker-compose.yml для Postgres Replica не отличается от аналогичного файла для Postgres Master. Как и в Postgres Master требуется монтирование именованного тома на хост-машине в директорию PGDATA внутри Postgres контейнера. Все отличия от Master будут реализованы далее во время синхронизации рабочих каталогов. Перед запуском контейнера требуется создать вручную каталог именованного тома, который будет монтироваться в рабочую директорию контейнера, и скопировать туда дынные рабочего каталога с Master.
Создаем каталог именованного тома
mkdir /var/lib/docker/volumes/eccm_postgres/ mkdir /var/lib/docker/volumes/eccm_postgres/_data
Копируем данные с Master сервера:
pg_basebackup -P -R -X stream -c fast -h <IP Master сервера> -U postgres -D /var/lib/docker/volumes/eccm_postgres/_data
Установка утилиты pg_basebackup
sudo apt-get install curl ca-certificates gnupg
curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
sudo apt-get update
sudo apt install postgresql-client-12
Добавляем в конфигурацию триггер-файл для настройки failover
echo "promote_trigger_file = 'failover.log'" >> /var/lib/docker/volumes/eccm_postgres/_data/postgresql.conf
Запускаем контейнер с Postgres
docker-compose -up -d
Настройка Postgres Replica завершена. Чтобы убедиться, что репликация действительно заработала, можно подключиться с помощью psql к мастеру и выполнить запрос:
SELECT * FROM pg_stat_replication;
Запрос должен вернуть непустую таблицу вида
postgres=# SELECT * FROM pg_stat_replication; pid | usesysid | usename | application_name | client_addr | client_hostname | client_port | backend_start | backend_xmin | state | sent_lsn | write_lsn | flush_lsn | replay_lsn | write_lag | f lush_lag | replay_lag | sync_priority | sync_state | reply_time -----+----------+----------+------------------+---------------+-----------------+-------------+-------------------------------+--------------+-----------+-----------+-----------+-----------+------------+----------------+---- ------------+----------------+---------------+------------+------------------------------- 65 | 10 | postgres | walreceiver | 100.110.1.234 | | 53862 | 2021-03-18 12:22:01.882821+07 | | streaming | 0/3000060 | 0/3000060 | 0/3000060 | 0/3000060 | 00:00:00.00103 | 00: 00:00.00103 | 00:00:00.00103 | 0 | async | 2021-03-18 12:22:02.249558+07
Настройка PGPOOL
Pgpool осуществляет контроль работоспособности Postgres Master и Postgres Slave, проксирует Write запросы на Master, а Read запросы балансирует между Master и Slave. При падении Master Pgpool инициирует процедуру failover путем создания trigger file на Replica, чтобы перевести его в Master и перенаправить на него запросы.
Пример docker-compose.yml файла
version: '2.4' services: pgpool: image: eccm-pgpool container_name: pgpool healthcheck: test: [ "CMD-SHELL", "ls" ] interval: 10s timeout: 10s retries: 5 restart: always volumes: - ./pool_hba.conf:/tmp/pool_hba.conf - ./pgpool.conf:/tmp/pgpool.conf - ./failover.sh:/tmp/failover.sh networks: - eltex-internal command: pgpool -n -f tmp/pgpool.conf -a /tmp/pool_hba.conf
В контейнер пробрасываются через volume конфигурационные файлы pgpool.conf, pool_hba.conf и скрипт failover.sh.
Запускаем контейнер с Postgres
docker-compose -up -d
Проникаем внутрь контейнера
docker exec -ti <имя docker контейнера> /bin/bash
Генерируем ключи и с помощью ssh-copy-id копируем публичный ключ на Postgres Replica Server, к которому будем подключаться. После этого необходимо будет обязательно проверить, что подключение по ssh работает.
ssh-keygen ssh-copy-id <Username Postgres Replica Server>@<IP Postgres Replica Server> ssh root@100.110.1.228 (Enter "yes") exit exit
Конфигурационные файлы Pgpool
pool_hba.conf - содержит параметры доступа к БД. Должен содержать все те же настройки, что и pg_hba.conf, кроме настроек доступа для replication, которые здесь не нужны
local all all trust host all all 127.0.0.1/32 trust host all all ::1/128 trust host all all all trust
pgpool.conf
Очень большой
failover.sh
#!/bin/bash failed_id=$1 old_primary_id=$2 new_master_host_name=$3 new_database_path=$4 echo "FAILOVER IS WORK" echo $failed_id echo $old_primary_id echo $new_master_host_name echo $new_database_path if [ $failed_id = $old_primary_id ];then # master failed ssh root@100.110.1.234 touch /var/lib/docker/volumes/eccm_postgres/_data/failover.log fi
Dockerfile для сборки контейнера pgpool