本文共 7400 字,大约阅读时间需要 24 分钟。
作者:王志斌,曾获得中国PostgreSQL数据库管理工程师(PGCE),是PostgreSQL官方认证讲师,盘古云课堂特邀金牌讲师。
上一篇文章向大家介绍了一个容器主从复制的整个过程,关于构建的过程主要是从之前单机的脚本层面进行扩展,今天将带领大家进入一个新的话题,即如何在容器环境下,搭建Repmgr集群环境,实现流复制以及故障自动切换。本文将介绍搭建repmgr的一主一从架构,系统架构如图所示:
Repmgr环境搭建需要两个容器,分别为master和slave,配置流程如下:
定义创建镜像文件,最后通过本文件在本地docker仓库中创建镜像。
注:这部分内容与之前单机构建镜像文件没有差别。
FROM centos:sshMAINTAINER wangzhibinENV USER="postgresql" \ PASSWORD=123456 \ GROUP=postgresqlRUN useradd ${USER} \ && chown -R ${USER}:${GROUP} /home/${USER} \ && yum -y update && yum install -y iptables sudo net-tools iproute openssh-server openssh-clients which vim sudo crontabs \&& echo ${USER}:${PASSWORD} | chpasswdCOPY runtime/ /home/${USER}/runtimeCOPY entrypoint.sh /sbin/entrypoint.shCOPY bin/ /home/${USER}/binCOPY lib/ /home/${USER}/libCOPY include/ /home/${USER}/includeCOPY conf/ /home/${USER}/confCOPY share/ /home/${USER}/shareCOPY entrypoint.sh /sbin/entrypoint.shCOPY tmp/ /home/${USER}/tmpCOPY pgarch/ /home/${USER}/pgarchRUN chmod 755 /sbin/entrypoint.sh && chown -R ${USER}:${GROUP} /home/${USER} && echo 'root:root123456' | chpasswdENV LD_LIBRARY_PATH /home/${USER}/libENV PATH /home/${USER}/bin:$PATHUSER ${USER}WORKDIR /home/${USER}CMD ["/bin/bash", "/sbin/entrypoint.sh"]
#!/bin/bashset -e# shellcheck source=runtime/functionssource "/home/${USER}/runtime/function"#启动sshdsudo /usr/sbin/sshd#运行repmgrconfigure_repmgr
容器调用入口函数,根据传入命令不同,执行注册或启动主库、注册或启动备库,从新加入集群的操作。
configure_repmgr(){ case ${NODE_ROLE} in master) echo 'master' initialize_master ;; slave) echo 'slave' initialize_slave ;; rejoin) echo 'rejoin' rejoin_node ;;esac }
注册和执行主库操作,包括修改配置文件、创建用户、数据库及插件等,并设置守护进程用于自动故障转移。
init_database(){ if [[ ! -f ${PG_DATADIR}/PG_VERSION ]]; then initdb -D /home/${USER}/pgdata -m ${PG_MODE} -U${USER} write_postgresql_config write_pg_hba_conf write_pgpass pg_ctl -D /home/${USER}/pgdata -w start >/dev/null psql -U ${USER} -d postgres -h localhost -u -c "alter instance user ${USER} password '${PG_PASSWORD}';" >/dev/null psql -U ${USER} -d postgres -h localhost -u -c "create database repmgr;" >/dev/null psql -U ${USER} -d postgres -h localhost -u -c "create extension repmgr;" >/dev/null psql -U ${USER} -d repmgr -h localhost -u -c "create user repmgr with superuser;" >/dev/null psql -U ${USER} -d repmgr -h localhost -u -c "alter user repmgr password '${PG_PASSWORD}';" >/dev/null repmgr -f ${PG_REPMGR_CONF} primary register else pg_ctl -D /home/${USER}/pgdata -w start >/dev/null fi repmgrd -f ${PG_REPMGR_CONF} --pid-file /tmp/repmgrd.pid --daemonize=false }
注册和执行备库操作,克隆主库,加入repmgr集群,并设置守护进程用于自动故障转移。
initialize_slave(){ if [[ ! -f ${PG_DATADIR}/PG_VERSION ]]; then write_repmgr_conf write_pgpass IP=`ping ${ MASTER_NAME} -c 1 -w 1 | sed '1{s/[^(]*(//;s/).*//;q}'` repmgr -h ${IP} -U repmgr -d repmgr -f ${PG_REPMGR_CONF} standby clone --dry-run repmgr -h ${IP} -U repmgr -d repmgr -f ${PG_REPMGR_CONF} standby clone pg_ctl -D ${PG_DATADIR} -w start >/dev/null repmgr -f ${PG_REPMGR_CONF} standby register repmgrd -f ${PG_REPMGR_CONF} --pid-file /tmp/repmgrd.pid --daemonize=false else pg_ctl -D ${PG_DATADIR} -w start >/dev/null repmgrd -f ${PG_REPMGR_CONF} --pid-file /tmp/repmgrd.pid --daemonize=false fi}
将已有节点重新加入到集群,启动守护进行用于自动切换。
rejoin_node(){ if [[ -f ${PG_DATADIR}/PG_VERSION ]]; then IP=`ping ${ MASTER_NAME} -c 1 -w 1 | sed '1{s/[^(]*(//;s/).*//;q}'` repmgr node rejoin -d 'host=${IP} dbname=repmgr user=repmgr' --force-rewind --config-files=postgresql.conf,postgresql.auto.conf -f ${PG_REPMGR_CONF} --verbose --dry-run repmgr node rejoin -d 'host=${IP} dbname=repmgr user=repmgr' --force-rewind --config-files=postgresql.conf,postgresql.auto.conf -f ${PG_REPMGR_CONF} --verbose fi}
write_postgresql_config(){ set_postgresql_param "wal_log_hints" "on" set_postgresql_param "archive_mode" "on" set_postgresql_param "archive_command" "test ! -f /home/${USER}/pgarch/%f && cp %p /home/${USER}/pgarch/%f" set_postgresql_param "wal_level" "hot_standby" set_postgresql_param "listen_addresses" "*" set_postgresql_param "hot_standby" "on" set_postgresql_param "max_wal_senders" "10" set_postgresql_param "wal_keep_segments" "10" set_postgresql_param "port" "5432" set_postgresql_param "max_connections " "100" set_postgresql_param "superuser_reserved_connections" "10" set_postgresql_param "full_page_writes" "on" set_postgresql_param "max_replication_slots" "10" set_postgresql_param "synchronous_commit" "on" set_postgresql_param "shared_preload_libraries" "repmgr" set_postgresql_param "log_destination" "csvlog" set_postgresql_param "logging_collector" "on" set_postgresql_param "log_directory" "on" set_postgresql_param "log_filename" "postgresql-%Y-%m-%d_%H%M%S" set_postgresql_param "log_rotation_age" "1d" set_postgresql_param "log_rotation_size" "10MB" set_postgresql_param "log_statement " "mod"}
write_pg_hba_conf(){ set_hba_param " local replication ${USER} trust " set_hba_param " host replication ${USER} 127.0.0.1/32 trust " set_hba_param " local repmgr ${USER} trust " set_hba_param " host repmgr ${USER} 127.0.0.1/32 trust " #for i in ${NODE_COUNT} #do # IP=`ping wzb2 -c 1 -w 1 | sed '1{s/[^(]*(//;s/).*//;q}'` # set_hba_param " host replication repmgr $IP/32 trust " # set_hba_param " host repmgr repmgr $IP/32 trust " #done set_hba_param " host replication ${USER} ${NET_SEGMENT}/24 md5 " set_hba_param " host repmgr ${USER} ${NET_SEGMENT}/24 md5 " set_hba_param " host repmgr repmgr ${NET_SEGMENT}/24 md5 "}
write_pgpass(){ if [ -f ~/.pgpass ] then rm -f ~/.pgpass fi echo "*:*:*:${USER}:${PG_PASSWORD}" >> ~/.pgpass echo "*:*:repmgr:repmgr:${PG_PASSWORD}" >> ~/.pgpass chmod 600 ~/.pgpass}
docker run --name node1 -itd --hostname node1 --net my_net3 --restart always --env ‘NODE_ID=1’ --env ‘NODE_ROLE=master’ --env ‘NET_SEGMENT=172.22.1.0’ --env ‘MASTER_NAME=node1’ --env ‘PG_PASSWORD=123456’ repmgr
docker run --name node2 -itd --hostname node2 --net my_net3 --restart always --env ‘NODE_ID=2’ --env ‘NODE_ROLE=slave’ --env ‘NET_SEGMENT=172.22.1.0’ --env ‘MASTER_NAME=node1’ --env ‘PG_PASSWORD=123456’ repmgr
当然也可以支持多个SLAVE节点。
执行以下命令,进入容器:
[root@localhost ~]# docker exec -it node1 /bin/sh
sh-4.2$repmgr -f conf/repmgr.conf cluster show到目前为止,已经带领大家从零搭建数据库单机、数据库主从、repmgr主从,采用搭积木的方法,每一步都具有衔接性。希望通过本文能给大家一些启发和帮助,使您能够了解、制作和搭建在容器下的repmgr架构。
[1]https://docs.docker.com/engine/reference/builder/
[2]https://repmgr.org/了解更多PostgreSQL热点资讯、新闻动态、精彩活动,请访问中国PostgreSQL官方网站:
解决更多PostgreSQL相关知识、技术、工作问题,请访问中国PostgreSQL官方问答社区:
下载更多PostgreSQL相关资料、工具、插件问题,请访问中国PostgreSQL官方下载网站:
转载地址:http://hmmxf.baihongyu.com/