1、bitnami/postgresql-repmgr:15 (鏡像名)
Bitnami 的?PostgreSQL-Repmgr?鏡像是一個預配置的 Docker 鏡像,集成了?PostgreSQL?數據庫和?repmgr(Replication Manager)工具,用于快速搭建高可用(HA)的 PostgreSQL 集群。
1. 核心組件
-
PostgreSQL:開源關系型數據庫,支持主從復制。
-
repmgr:用于管理 PostgreSQL 復制和自動故障轉移的工具,提供:
-
自動主從切換(failover)
-
節點監控
-
集群狀態管理
-
2. 鏡像特點
-
開箱即用:預配置主從復制和 repmgr 管理。
-
基于 Bitnami 標準化鏡像:
-
非 root 用戶運行(UID 1001),增強安全性。
-
數據卷掛載到?
/bitnami/postgresql
。 -
日志輸出到標準輸出(方便 Docker 日志收集)。
-
-
環境變量驅動:通過環境變量配置數據庫、復制和用戶權限。
docker-compose.yml (同機部署)
配置電腦的hosts文件,pg-0 和pg-1的ip地址
services:pg-0:image: bitnami/postgresql-repmgr:15container_name: pg-0environment:POSTGRESQL_POSTGRES_PASSWORD: 123***POSTGRESQL_USERNAME: frankPOSTGRESQL_PASSWORD: 123***POSTGRESQL_DATABASE: frank-devPOSTGRESQL_NUM_SYNCHRONOUS_REPLICAS: 0REPMGR_USERNAME: repmgrREPMGR_PASSWORD: 123***REPMGR_DATABASE: repmgrREPMGR_PRIMARY_HOST: pg-0REPMGR_PRIMARY_PORT: 5432REPMGR_PARTNER_NODES: "pg-0:5432,pg-1:5432" # 關鍵:使用容器內部端口REPMGR_NODE_NAME: pg-0REPMGR_NODE_NETWORK_NAME: pg-0REPMGR_PORT_NUMBER: 5432POSTGRESQL_INITDB_ARGS: "--data-checksums"REPMGR_GENERATE_PGHBA_CONF: "yes"REPMGR_PGHBA_TRUST_ALL: "yes"REPMGR_CREATE_DB: "yes"REPMGR_FAILOVER_MODE: automaticREPMGR_RECONNECT_ATTEMPTS: 10REPMGR_RECONNECT_INTERVAL: 5volumes:- postgres_data_pg0:/bitnami/postgresqlports:- "5432:5432"networks:- docker_postgres15_networkhealthcheck: # 可選:健康檢查test: ["CMD-SHELL", "pg_isready -U postgres -d repmgr"] # 直接檢測 repmgr 數據庫interval: 5stimeout: 3sretries: 3pg-1:image: bitnami/postgresql-repmgr:15container_name: pg-1environment:POSTGRESQL_POSTGRES_PASSWORD: 123***POSTGRESQL_USERNAME: frankPOSTGRESQL_PASSWORD: 123***POSTGRESQL_DATABASE: frank-devPOSTGRESQL_NUM_SYNCHRONOUS_REPLICAS: 0REPMGR_USERNAME: repmgrREPMGR_PASSWORD: 123***REPMGR_DATABASE: repmgrREPMGR_PRIMARY_HOST: pg-0REPMGR_PRIMARY_PORT: 5432REPMGR_PARTNER_NODES: "pg-0:5432,pg-1:5432" # 關鍵:使用容器內部端口REPMGR_NODE_NAME: pg-1REPMGR_NODE_NETWORK_NAME: pg-1REPMGR_PORT_NUMBER: 5432REPMGR_ROLE: standby # 明確聲明為備用節點POSTGRESQL_INITDB_ARGS: "--data-checksums"REPMGR_GENERATE_PGHBA_CONF: "yes"REPMGR_PGHBA_TRUST_ALL: "yes"REPMGR_CREATE_DB: "yes"REPMGR_FAILOVER_MODE: automaticREPMGR_RECONNECT_ATTEMPTS: 10REPMGR_RECONNECT_INTERVAL: 5volumes:- postgres_data_pg1:/bitnami/postgresqlports:- "15432:5432"networks:- docker_postgres15_networkdepends_on: # 確保 pg-0 先啟動pg-0:condition: service_healthynetworks:docker_postgres15_network:ipam:config:- subnet: 172.72.10.0/28driver: bridgevolumes:postgres_data_pg0:postgres_data_pg1:
2、bitnami/pgpool:4 (鏡像名)
1. 核心組件
-
Pgpool-II:高性能中間件,為 PostgreSQL 提供連接池、負載均衡、自動故障轉移等功能。
-
關鍵特性:
-
連接池:減少頻繁連接開銷。
-
負載均衡:讀操作分散到多個從節點。
-
自動故障轉移:主節點故障時提升從節點為新主。
-
Watchdog:多 Pgpool 節點間高可用(防止單點故障)。
-
2. 鏡像特點
-
版本:基于 Pgpool-II 4.x(支持 PostgreSQL 10+)。
-
安全:以非 root 用戶(UID 1001)運行。
-
配置驅動:通過環境變量或配置文件(
/opt/bitnami/pgpool/conf/
)管理。 -
集成健康檢查:內置對后端 PostgreSQL 節點的監控。
docker-compose.yml
創建掛載的目錄和文件
services:pgpool:image: bitnami/pgpool:4container_name: "my-pgpool"networks:- docker_postgres15_network # 與 PostgreSQL 容器同網絡ports:- 9999:5432volumes:- ./conf/myconf.conf:/config/myconf.confenvironment:- PGPOOL_BACKEND_NODES=0:pg-0:5432,1:pg-1:5432 # 使用容器內部端口 定義后端節點(主節點必須排在第一個)- PGPOOL_SR_CHECK_USER=repmgr- PGPOOL_SR_CHECK_PASSWORD=123***- PGPOOL_ENABLE_LDAP=no- PGPOOL_POSTGRES_USERNAME=postgres- PGPOOL_POSTGRES_PASSWORD=123***- PGPOOL_ADMIN_USERNAME=admin- PGPOOL_ADMIN_PASSWORD=123***- PGPOOL_ENABLE_LOAD_BALANCING=yes # 啟用讀寫分離- PGPOOL_POSTGRES_CUSTOM_USERS=frank- PGPOOL_POSTGRES_CUSTOM_PASSWORDS=123***- PGPOOL_HEALTH_CHECK_TIMEOUT=10- PGPOOL_HEALTH_CHECK_PERIOD=5- PGPOOL_FAILOVER_ON_BACKEND_ERROR=yesrestart: alwayshealthcheck:test: ["CMD", "/opt/bitnami/scripts/pgpool/healthcheck.sh"]interval: 10stimeout: 5sretries: 5
networks:docker_postgres15_network:ipam:config:- subnet: 172.72.10.0/28driver: bridge
3、實驗主從
1)鏈接pgpool,創建數據表和數據,數據會自動同步到pg-0和pg-1
2)操作pg-1從數據庫,只讀不可操作。
3)模擬pg-0故障
docker compose -f docker-compose-pg.yml down pg-0? (指定關閉對應的服務)
a)從日志中可以看到當pg-0掛掉后會再重試5次,如果還訪問不了會執行find_primary_node方法查找可以作為主節點的節點,然后把找到節點設置為新的主節點,所以現在pg-1是主節點,這個時候我們訪問pgpoll還是能訪問的,現在在users表里面再添加一行數據:?
?
?b)pgpool加了數據之后,pg-1已經成為了主節點,去pg-1把王五的年紀改完25成功,pgpool數據也同步修改
c)現在將pg-0啟動起來,也會自動加入集群,會發現就算pg-0重新啟動器來了,但是pg-1還是主節點不變,pg-0又會成為副節點。數據也會同步進去。
4、but:存在的問題:
1、pg-0 和 pg-1竟然都是主節點了!!!
注意,容器內部的端口問題,以上的配置都需要使用容器內部的5432端口,而非暴露出來的15432端口,后續驗證正常。pg-1還是主節點,pg-0成為了從節點,符合預期。
?2、第二次模擬失敗
[NOTICE] TERM signal received pg-0 | 2025-06-30 08:42:28.609 GMT [233] FATAL: could not receive data from WAL stream: server closed the connection unexpectedly pg-0 | This probably means the server terminated abnormally pg-0 | before or while processing the request. pg-0 | 2025-06-30 08:42:28.609 GMT [232] LOG: invalid record length at 0/8000FC0: wanted 24, got 0 pg-0 | 2025-06-30 08:42:28.613 GMT [403] FATAL: could not connect to the primary server: connection to server at "pg-1" (172.72.10.3), port 5432 failed: Connection refused pg-0 | Is the server running on that host and accepting TCP/IP connections? pg-0 | 2025-06-30 08:42:28.613 GMT [232] LOG: waiting for WAL to become available at 0/8000FD8 pg-1 exited with code 0 pg-0 | [2025-06-30 08:42:30] [ERROR] unable to determine if server is in recovery pg-0 | [2025-06-30 08:42:30] [DETAIL] pg-0 | server closed the connection unexpectedly pg-0 | This probably means the server terminated abnormally pg-0 | before or while processing the request. pg-0 | pg-0 | [2025-06-30 08:42:30] [DETAIL] query text is: pg-0 | SELECT pg_catalog.pg_is_in_recovery() pg-0 | [2025-06-30 08:42:32] [NOTICE] upstream is available but upstream connection has gone away, resetting pg-0 | [2025-06-30 08:42:32] [NOTICE] current upstream node "pg-1" (ID: 1001) is not primary, restarting monitoring pg-0 | [2025-06-30 08:42:32] [ERROR] unable to determine an active primary for this cluster, terminating pg-0
第一次啟動是主節點,pg-1是備份節點。模擬實驗pg-0故障,pgpool會自動將pg-1作為主節點。pg-0節點恢復后會成為備份節點。后續再將pg-1節點關閉掉,此時pgpool在處理事時,直接報上面的錯誤
原因:自從節點自我修復時,需要耗時3-5分鐘,等待修復好,再次down pg-1就可以了!!!
大功告成!?
彩蛋:多機版主需要將pg-0和pg-1的docker-compose分成兩個,保證他們在同一個網絡中間即可,注意也要配置hosts文件。還有端口問題,都使用外部暴露的端口,不使用內部容器的端口。