本文记录了某项目中使用docker部署PostgreSQL集群的步骤和注意事项,使用的镜像是bitnami/postgresql-repmgr,其中与用户身份有关的内容在其他bitnami打包的镜像中也适用。
一、环境信息
CentOS 7.9
PostgreSQL 16
二、部署方案
PostgreSQL集群有多种方案,这里我们使用在项目中多次使用比较稳定的repmgr方案,repmgr能够在集群环境管理每个PostgreSQL节点的主从状态,官网介绍如下:
repmgr是一个开源的工具套件,用于管理PostgreSQL服务器集群中的复制和故障转移。它通过提供设置备用服务器、监控复制和执行故障转移或手动切换操作等管理任务的工具,增强了PostgreSQL内置的热备功能。
repmgr自从PostgreSQL 9.0引入内置的复制机制后,就提供了高级的支持。当前的repmgr系列,repmgr 5,支持了PostgreSQL 9.3引入的最新的复制功能,如级联复制、时间线切换和通过复制协议进行基础备份。
bitnami提供的postgresql-repmgr镜像是将PostgreSQL与repmgr打包在一起,形成一个集成的解决方案,以便用户能够快速搭建PostgreSQL集群服务,用户可以从dockerhub获取到这个镜像。
这个PostgreSQL集群解决方案包括PostgreSQL复制管理器,一个用于管理PostgreSQL集群上的复制和故障转移的开源工具。
三、部署步骤
首先确认集群环境各个服务器节点的状态:
关闭防火墙(如果docker已启动需要重启docker服务,否则关闭防火墙后启动容器会报iptables命令错):
systemctl stop firewalld
systemctl disable firewalld
确保服务器时钟准确:
ntpdate cn.ntp.org.cn
安装和启动docker服务和docker-compose工具:
yum install -y epel-release
yum install -y docker
yum install -y docker-compose
systemctl enable docker
systemctl start docker
安装postgresql-repmgr镜像:
docker pull bitnami/postgresql-repmgr
将各个服务器名称写入hosts文件,vi /etc/hosts
添加下面内容:
10.102.9.80 pg-0
10.102.9.81 pg-1
10.102.9.82 pg-2
四、配置
数据目录
bitnami的镜像使用非root用户身份,即容器里的root用户映射到宿主机的非root用户,此用户是ID为1001的无名称用户。要让容器的数据能够持久化到宿主机,需要准备一个数据目录(此例中为/mnt/sda/bitnami/postgresql
)并映射到容器内,此目录的owner是1001:
mkdir /mnt/sda/bitnami
mkdir /mnt/sda/bitnami/postgresql
chown 1001:root /mnt/sda/bitnami -R
网络
创建docker网络以便节点间能够通信:
docker network create --subnet=172.25.0.0/24 --gateway=172.25.0.1 pg-network
配置文件
在任意目录创建pg.yml
文件,内容如下:
version: '2'
networks:
default:
external:
name: pg-network
services:
pg:
container_name: "pg"
image: bitnami/postgresql-repmgr:latest
networks:
default:
ipv4_address: 172.25.0.110
ports:
- "5432:5432"
restart: always
volumes:
- /mnt/sda/bitnami/postgresql:/bitnami/postgresql
- /etc/hosts:/etc/hosts
environment:
- POSTGRESQL_POSTGRES_PASSWORD=adminpassword
- POSTGRESQL_USERNAME=myuser
- POSTGRESQL_PASSWORD=mypassword
- POSTGRESQL_DATABASE=mydatabase
- REPMGR_PASSWORD=adminpassword
- REPMGR_PRIMARY_HOST=pg-0
- REPMGR_PRIMARY_PORT=5432
- REPMGR_PARTNER_NODES=pg-0,pg-1,pg-2:5432
- REPMGR_NODE_NAME=pg-0
- REPMGR_NODE_NETWORK_NAME=pg-0
- REPMGR_PORT_NUMBER=5432
在第二个节点类似创建pg.yml
文件,修改其中的部分内容(ip地址、以及2处节点名称,见代码中的标注)如下所示:
version: '2'
networks:
default:
external:
name: pg-network
services:
pg:
container_name: "pg"
image: bitnami/postgresql-repmgr:latest
networks:
default:
ipv4_address: 172.25.0.111 <-- 修改了这里
ports:
- "5432:5432"
restart: always
volumes:
- /mnt/sda/bitnami/postgresql:/bitnami/postgresql
- /etc/hosts:/etc/hosts
environment:
- POSTGRESQL_POSTGRES_PASSWORD=adminpassword
- POSTGRESQL_USERNAME=myuser
- POSTGRESQL_PASSWORD=mypassword
- POSTGRESQL_DATABASE=mydatabase
- REPMGR_PASSWORD=adminpassword
- REPMGR_PRIMARY_HOST=pg-0
- REPMGR_PRIMARY_PORT=5432
- REPMGR_PARTNER_NODES=pg-0,pg-1,pg-2:5432
- REPMGR_NODE_NAME=pg-1 <-- 修改了这里
- REPMGR_NODE_NETWORK_NAME=pg-1 <-- 修改了这里
- REPMGR_PORT_NUMBER=5432
第三个节点的情况类似,为节约篇幅这里不再贴配置文件内容。
启动服务
在每个节点分别使用docker-compose命令启动服务:
docker-compose -f /root/pg-ha/pg.yml up -d
查看repmgr状态,例如当前primary节点是哪一个:
docker exec -ti pg /opt/bitnami/scripts/postgresql-repmgr/entrypoint.sh repmgr -f /opt/bitnami/repmgr/conf/repmgr.conf service status
ID | Name | Role | Status | Upstream | repmgrd | PID | Paused? | Upstream last seen
----+------+---------+-----------+----------+---------+-----+---------+--------------------
1000 | pg-0 | standby | running | pg-1 | running | 1 | no | 1 second(s) ago
1001 | pg-1 | primary | * running | | running | 1 | no | n/a
1002 | pg-2 | standby | running | pg-1 | running | 1 | no | 0 second(s) ago
尝试连接数据库,验证服务是否正常(-U参数很重要):
docker exec -ti pg psql -U myuser -d mydatabase
若需要手工切换standby节点为primary执行下面的命令,需要节点之间配置过免密:
docker exec -it pg /opt/bitnami/scripts/postgresql-repmgr/entrypoint.sh repmgr -f /opt/bitnami/repmgr/conf/repmgr.conf standby switchover