三台虚拟机部署 PostgreSQL 主从集群(含自动故障转移)指南

三台虚拟机部署 PostgreSQL 主从集群(含自动故障转移)指南

在单机 Docker 环境下搭建的 PostgreSQL 主从集群虽能满足测试需求,但生产级场景更需要跨主机高可用架构—— 通过多台虚拟机分散风险,避免单点故障导致整个集群不可用。本文将详细讲解如何在三台虚拟机(一主两备)上部署 PostgreSQL 主从集群,并集成 Pgpool 实现负载均衡与自动故障转移,确保数据同步可靠、业务无感知切换。

一、架构设计与环境准备

1.1 集群架构概览

本次部署采用 “1 主 2 备 + 独立 Pgpool” 架构,将数据库节点与负载均衡节点分离部署,各节点职责清晰,架构图如下:

[应用系统] → [Pgpool节点(192.168.1.103)] → 「主库节点(192.168.1.100,写操作)」
                                          → 「备库1节点(192.168.1.101,读操作)」
                                          → 「备库2节点(192.168.1.102,读操作)」

1.2 节点规划

节点角色 虚拟机 IP 核心功能 需开放端口 部署软件
PostgreSQL 主库 192.168.1.100 处理写请求,同步数据到备库 5432 Docker、Docker ***pose
PostgreSQL 备库 1 192.168.1.101 只读节点,同步主库数据,故障时可晋升主库 5432 Docker、Docker ***pose
PostgreSQL 备库 2 192.168.1.102 与备库 1 功能一致,提升读性能与冗余度 5432 Docker、Docker ***pose
Pgpool(负载均衡) 192.168.1.103 路由读写请求,自动故障转移,应用唯一入口 5432 Docker、Docker ***pose

1.3 基础环境准备(所有节点通用)

CentOS 7/8 或 Ubuntu 20.04+ 为例:为例,所有虚拟机需先完成以下环境配置,确保跨主机通信正常。

步骤 1:安装 Docker 与 Docker ***pose
# 1. 安装依赖包
yum install -y yum-utils device-mapper-persistent-data lvm2

# 2. 添加Docker官方源
yum-config-manager --add-repo https://download.docker.***/linux/centos/docker-ce.repo

# 3. 安装Docker(最新稳定版)
yum install -y docker-ce docker-ce-cli containerd.io

# 4. 启动Docker并设置开机自启
systemctl start docker && systemctl enable docker

# 5. 安装Docker ***pose(v2版本,需替换为最新版链接)
curl -SL https://github.***/docker/***pose/releases/download/v2.27.0/docker-***pose-linux-x86_64 -o /usr/local/bin/docker-***pose
chmod +x /usr/local/bin/docker-***pose

# 验证安装(出现版本号即成功)
docker --version && docker-***pose --version
步骤 2:配置跨主机通信(关键)

跨主机部署的核心前提是 “节点间能互相访问”,需关闭防火墙拦截、禁用 SELinux,并验证网络连通性:

# 1. 临时关闭防火墙(测试环境;生产环境建议开放指定端口,见下文补充)
systemctl stop firewalld && systemctl disable firewalld

# 2. 禁用SELinux(避免权限拦截容器网络)
setenforce 0  # 临时生效
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config  # 永久生效

# 3. 验证网络连通性(以主库为例,备库和Pgpool节点需互相ping通)
ping 192.168.1.100 -c 3  # 备库1执行,测试主库可达性
ping 192.168.1.101 -c 3  # 主库执行,测试备库1可达性

二、核心配置文件编写(分节点)

跨主机部署与单机最大的差异是 “用虚拟机 IP 替代容器服务名通信”—— 原单机中通过pg-0这类服务名访问节点,跨主机需改为虚拟机 IP(如192.168.1.100),同时固定数据库端口(5432),确保节点间能精准连接。

2.1 主库节点(192.168.1.100)配置

在主库虚拟机新建目录(如/opt/pg-master),创建docker-***pose.yml文件,核心配置repmgr伙伴节点为 IP 地址:

version: '3.8'
services:
  pg-master:
    image: docker.io/bitnami/postgresql-repmgr:17  # 含repmgr的PostgreSQL镜像
    ports:
      - "5432:5432"  # 固定宿主机5432端口,备库需通过此端口同步数据
    volumes:
      - pg_master_data:/bitnami/postgresql  # 本地数据卷,持久化主库数据
    environment:
      # 1. 超级用户配置(postgres,用于权限管理)
      - POSTGRESQL_POSTGRES_PASSWORD=adminpassword
      # 2. 业务用户配置(应用连接使用,需与备库一致)
      - POSTGRESQL_USERNAME=repmgrodoo
      - POSTGRESQL_PASSWORD=dwda000409
      - POSTGRESQL_DATABASE=customdatabase  # 初始业务数据库,自动创建
      # 3. repmgr复制配置(核心:跨主机需用IP)
      - REPMGR_PASSWORD=repmgrpassword  # repmgr工具专用密码
      - REPMGR_PRIMARY_HOST=192.168.1.100  # 主库虚拟机IP(自身)
      - REPMGR_PRIMARY_PORT=5432
      - REPMGR_PARTNER_NODES=192.168.1.100:5432,192.168.1.101:5432,192.168.1.102:5432  # 所有节点IP:端口
      - REPMGR_NODE_NAME=pg-master  # 节点唯一名称(自定义)
      - REPMGR_NODE_***WORK_NAME=192.168.1.100  # 跨主机通信IP
      - REPMGR_PORT_NUMBER=5432
      - REPMGR_RECONNECT_ATTEMPTS=3  # 断开后重试次数
      - REPMGR_RECONNECT_INTERVAL=5  # 重试间隔(秒)
    healthcheck:
      # 健康检查:确保PostgreSQL服务正常
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  pg_master_data:
    driver: local  # 本地存储(生产环境建议替换为共享存储)

2.2 备库 1 节点(192.168.1.101)配置

在备库 1 虚拟机新建目录(如/opt/pg-standby1),创建docker-***pose.yml,核心是指向主库 IP,确保数据同步:

version: '3.8'
services:
  pg-standby1:
    image: docker.io/bitnami/postgresql-repmgr:17  # 与主库镜像版本一致
    ports:
      - "5432:5432"  # 固定5432端口,Pgpool需连接
    volumes:
      - pg_standby1_data:/bitnami/postgresql
    environment:
      # 1. 超级用户/业务用户配置:与主库完全一致(确保用户同步)
      - POSTGRESQL_POSTGRES_PASSWORD=adminpassword
      - POSTGRESQL_USERNAME=repmgrodoo
      - POSTGRESQL_PASSWORD=dwda000409
      - POSTGRESQL_DATABASE=customdatabase
      # 2. repmgr复制配置:指向主库IP
      - REPMGR_PASSWORD=repmgrpassword
      - REPMGR_PRIMARY_HOST=192.168.1.100  # 主库IP(关键,而非服务名)
      - REPMGR_PRIMARY_PORT=5432
      - REPMGR_PARTNER_NODES=192.168.1.100:5432,192.168.1.101:5432,192.168.1.102:5432
      - REPMGR_NODE_NAME=pg-standby1  # 唯一节点名
      - REPMGR_NODE_***WORK_NAME=192.168.1.101  # 备库1自身IP
      - REPMGR_PORT_NUMBER=5432
      - REPMGR_RECONNECT_ATTEMPTS=3
      - REPMGR_RECONNECT_INTERVAL=5
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  pg_standby1_data:
    driver: local

2.3 备库 2 节点(192.168.1.102)配置

与备库 1 配置几乎一致,仅需修改自身 IP 和节点名,在备库 2 虚拟机新建目录(如/opt/pg-standby2),docker-***pose.yml如下:

version: '3.8'
services:
  pg-standby2:
    image: docker.io/bitnami/postgresql-repmgr:17
    ports:
      - "5432:5432"
    volumes:
      - pg_standby2_data:/bitnami/postgresql
    environment:
      - POSTGRESQL_POSTGRES_PASSWORD=adminpassword
      - POSTGRESQL_USERNAME=repmgrodoo
      - POSTGRESQL_PASSWORD=dwda000409
      - POSTGRESQL_DATABASE=customdatabase
      # repmgr配置:仅修改节点名和IP
      - REPMGR_PASSWORD=repmgrpassword
      - REPMGR_PRIMARY_HOST=192.168.1.100
      - REPMGR_PRIMARY_PORT=5432
      - REPMGR_PARTNER_NODES=192.168.1.100:5432,192.168.1.101:5432,192.168.1.102:5432
      - REPMGR_NODE_NAME=pg-standby2
      - REPMGR_NODE_***WORK_NAME=192.168.1.102  # 备库2自身IP
      - REPMGR_PORT_NUMBER=5432
      - REPMGR_RECONNECT_ATTEMPTS=3
      - REPMGR_RECONNECT_INTERVAL=5
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  pg_standby2_data:
    driver: local

2.4 Pgpool 节点(192.168.1.103)配置

Pgpool 是应用的唯一入口,需配置所有数据库节点的 IP,确保能路由请求。在 Pgpool 虚拟机新建目录(如/opt/pgpool),docker-***pose.yml如下:

version: '3.8'
services:
  pgpool:
    image: bitnami/pgpool:4  # Pgpool官方镜像,与PostgreSQL兼容
    ports:
      - "5432:5432"  # 固定宿主机5432端口,应用仅需连接此地址
    environment:
      # 1. 后端数据库节点配置(核心:用虚拟机IP)
      - PGPOOL_BACKEND_NODES=0:192.168.1.100:5432,1:192.168.1.101:5432,2:192.168.1.102:5432  # 序号:IP:端口
      - PGPOOL_BACKEND_APPLICATION_NAMES=pg-master,pg-standby1,pg-standby2  # 与节点名一一对应
      # 2. 主从状态检查配置(用repmgr用户)
      - PGPOOL_SR_CHECK_USER=repmgr
      - PGPOOL_SR_CHECK_PASSWORD=repmgrpassword
      - PGPOOL_ENABLE_LDAP=no  # 关闭LDAP,简化配置
      # 3. 应用连接配置(与数据库业务用户一致)
      - PGPOOL_POSTGRES_USERNAME=repmgrodoo
      - PGPOOL_POSTGRES_PASSWORD=dwda000409
      # 4. Pgpool管理员配置(用于管理Pgpool自身)
      - PGPOOL_ADMIN_USERNAME=pgpool_admin
      - PGPOOL_ADMIN_PASSWORD=pgpool_password
      # 5. 自动故障转移配置(核心功能)
      - PGPOOL_FAILOVER_ON_BACKEND_ERROR=yes  # 后端故障时自动触发转移
      - PGPOOL_AUTO_FAILBACK=yes  # 原主库恢复后自动变为备库
      - PGPOOL_NUM_INIT_CHILDREN=32  # 初始子进程数(对应并发连接数)
      - PGPOOL_MAX_POOL=4  # 每个后端节点的最大连接池数
    healthcheck:
      # Pgpool健康检查(用官方脚本)
      test: ["CMD", "/opt/bitnami/scripts/pgpool/healthcheck.sh"]
      interval: 10s
      timeout: 5s
      retries: 5

三、集群启动与功能验证

跨主机集群需严格按 “主库 → 备库 1 → 备库 2 → Pgpool” 的顺序启动,避免备库启动时主库未就绪导致同步失败。

3.1 启动主库(192.168.1.100)

# 进入主库配置目录
cd /opt/pg-master

# 后台启动主库(首次启动会初始化数据库和repmgr主节点)
docker-***pose up -d

# 查看主库日志,确认启动成功(关键日志:“repmgr primary register su***essful”)
docker-***pose logs -f pg-master

当日志出现repmgr: su***essfully registered primary node,说明主库初始化完成。

3.2 启动备库 1(192.168.1.101)

# 进入备库1配置目录
cd /opt/pg-standby1

# 启动备库1
docker-***pose up -d

# 查看备库1日志,确认同步成功(关键日志:“repmgr standby register su***essful”)
docker-***pose logs -f pg-standby1

日志出现repmgr: standby registration ***plete,且无connection refused错误,说明备库 1 已成功同步主库数据。

3.3 启动备库 2(192.168.1.102)

操作与备库 1 一致:

cd /opt/pg-standby2
docker-***pose up -d
docker-***pose logs -f pg-standby2

确认日志出现同步成功信息后,再启动 Pgpool。

3.4 启动 Pgpool(192.168.1.103)

# 进入Pgpool配置目录
cd /opt/pgpool

# 启动Pgpool
docker-***pose up -d

# 查看Pgpool日志,确认识别所有节点(关键日志:“backend node 0/1/2 is up”)
docker-***pose logs -f pgpool

当日志出现backend node 0 is upbackend node 1 is upbackend node 2 is up,说明 Pgpool 已成功连接所有数据库节点。

3.5 核心功能验证

验证 1:主从数据同步
  • 步骤 1:主库写入数据

    在主库虚拟机执行命令,连接主库并插入测试数据:

    # 进入主库容器,连接数据库
    docker-***pose exec pg-master psql -U repmgrodoo -d customdatabase
    
    # 执行SQL:创建表并插入数据
    CREATE TABLE test_sync (id INT PRIMARY KEY, content TEXT);
    INSERT INTO test_sync (id, content) VALUES (1, '跨主机同步测试');
    
转载请说明出处内容投诉
CSS教程网 » 三台虚拟机部署 PostgreSQL 主从集群(含自动故障转移)指南

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买