博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Docker容器之repmgr篇
阅读量:2019 次
发布时间:2019-04-28

本文共 7400 字,大约阅读时间需要 24 分钟。

作者:王志斌,曾获得中国PostgreSQL数据库管理工程师(PGCE),是PostgreSQL官方认证讲师,盘古云课堂特邀金牌讲师。

上一篇文章向大家介绍了一个容器主从复制的整个过程,关于构建的过程主要是从之前单机的脚本层面进行扩展,今天将带领大家进入一个新的话题,即如何在容器环境下,搭建Repmgr集群环境,实现流复制以及故障自动切换。本文将介绍搭建repmgr的一主一从架构,系统架构如图所示:

Repmgr主从架构图

Repmgr环境搭建需要两个容器,分别为master和slave,配置流程如下:

  1. 在master上初始化数据库,并启动数据库实例。
  2. 创建repmgr用户及对应数据库,用于保存集群中的元数据信息;同时创建repmgr插件,并且设置repmgr用户默认的search_path。
  3. 修改master的postgresql.conf、pg_hba.conf、repmgr.conf文件,并且重新启动数据库实例。
  4. master上的数据库实例注册为repmgr中的主库。
  5. 修改slave上的repmgr.conf文件。
  6. 执行克隆master上的主库操作,并且启动slave上的数据库实例。
  7. 将slave上的数据库实例注册为repmgr中的备库。
  8. 检查集群状态,此时主备状态正常。

创建镜像

Dockerfile

定义创建镜像文件,最后通过本文件在本地docker仓库中创建镜像。

注:这部分内容与之前单机构建镜像文件没有差别。

FROM centos:sshMAINTAINER wangzhibin 
ENV 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"]

entrypoint.sh

#!/bin/bashset -e# shellcheck source=runtime/functionssource "/home/${USER}/runtime/function"#启动sshdsudo /usr/sbin/sshd#运行repmgrconfigure_repmgr

functions

  • configure_repmgr()

容器调用入口函数,根据传入命令不同,执行注册或启动主库、注册或启动备库,从新加入集群的操作。

configure_repmgr(){
case ${NODE_ROLE} in master) echo 'master' initialize_master ;; slave) echo 'slave' initialize_slave ;; rejoin) echo 'rejoin' rejoin_node ;;esac }
  • initialize_master()

注册和执行主库操作,包括修改配置文件、创建用户、数据库及插件等,并设置守护进程用于自动故障转移。

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 }
  • initialize_slave()

注册和执行备库操作,克隆主库,加入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()

将已有节点重新加入到集群,启动守护进行用于自动切换。

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}
  • 修改postgresql.conf文件
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"}
  • 修改pg_hba.conf文件
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 "}
  • 修改.pgpass文件
write_pgpass(){
if [ -f ~/.pgpass ] then rm -f ~/.pgpass fi echo "*:*:*:${USER}:${PG_PASSWORD}" >> ~/.pgpass echo "*:*:repmgr:repmgr:${PG_PASSWORD}" >> ~/.pgpass chmod 600 ~/.pgpass}

运行镜像

  • 运行master

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

  • 运行slave

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/

你可能感兴趣的文章
oracle pde文件导入
查看>>
理解OAuth 2.0--转
查看>>
Top 10 Questions about Java Exceptions--reference
查看>>
Bash String Manipulation Examples – Length, Substring, Find and Replace--reference
查看>>
oracle 查看表属主和表空间sql
查看>>
linux shell执行方式
查看>>
常用工具之zabbix
查看>>
常用工具之stunnel
查看>>
linux cat 命令详解--转
查看>>
binary heap
查看>>
Load resources from classpath in Java--reference
查看>>
xmemcached user guide --存档
查看>>
Regular Expressions in Grep Command with 10 Examples --reference
查看>>
linux shell wc 命令
查看>>
深入分析 iBATIS 框架之系统架构与映射原理--转载
查看>>
Servlet 工作原理解析--转载
查看>>
JDK源码重新编译——支持eclipse调试JDK源码--转载
查看>>
Getting started with new I/O (NIO)--reference
查看>>
An NIO.2 primer--reference
查看>>
JAAS LOGIN IN WEBLOGIC SERVER--reference
查看>>