说明:
不使用docker hub上的offical postgresql镜像,有几个原因:
1,官方的镜像是基于debian:jessie或者alpine这些操作系统的,而我们最好用公司目前统一的操作系统ubuntu,便于统一技术栈,统一管理。
2,我们在自己创建pg image的过程中可以自定义客户化的配置、参数等。
3, Dockerfile没有办法mount宿主机器的卷到容器内,所以没有办法将initdb创建数据库时生成的文件放到宿主机器卷上。
------创建PG库镜像、搭建主库
1,以下步骤在宿主机器(pg的主库所在机器)操作:
建立PG的bulid image的环境
Dockerfile: FROM ubuntu:latest docker build -t ubuntu:utf8 . mkdir -p /backup/postgresql |
---|
如下操作为容器内部的操作:
docker exec -it build_pg_img /bin/bash apt-get update && apt-get install -y vim wget vi /etc/apt/sources.list.d/pgdg.list: |
---|
说明:目前默认Ubuntu的源还是pg 9.5,所以要先更新apt的源,然后才能安装pg 9.6。
2,查看pg已经安装完毕
root@1c558c35fae8:/# dpkg -l |grep postgre ii pgdg-keyring 2017.1 all keyring for apt.postgresql.org |
---|
3,切换到postgres用户
root@3fd84ba76393:~# more /etc/passwd |grep post root@3fd84ba76393:~# su - postgres |
---|
4,编辑postgres用户的profile
vi .bash_profile
postgres用户加载环境变量: . ./.bash_profile |
---|
5,初始化PG数据库目录
cd /var/lib/postgresql/ mv postgresql.conf postgresql.conf.old |
---|
6,配置postgresql.conf参数
vi $PGDATA/postgresql.conf :
postgresql.conf
7,配置pg_hba.conf (按需修改)
vi $PGDATA/pg_hba.conf host all all 192.168.0.0/16 md5 host replication repuser 192.168.0.0/16 md5 |
---|
8,启动数据库
pg_ctl start -D /var/lib/postgresql/data |
---|
9,创建扩展
create extension pg_stat_statements; |
---|
10,停止数据库,退出容器
pg_ctl stop -D /var/lib/postgresql/data -m fast exit exit |
---|
11,以下在宿主机器操作:
从上述初始化完毕的container来创建基础镜像:
docker ps -a |grep build_pg_img docker stop build_pg_img docker commit build_pg_img pg9.6_template |
---|
12,创建最终PG镜像的Dockerfile:
vi Dockerfile : FROM pg9.6_template USER postgres ENV PGHOME /usr/lib/postgresql/9.6 ENV PGPORT 5432 ENV PGDATA /var/lib/postgresql/data ENV PATH $PGHOME/bin:$PATH ENV LD_LIBRARY_PATH=$PGHOME/lib:$LD_LIBRARY_PATH EXPOSE 5432 WORKDIR /var/lib/postgresql/data CMD ["/usr/lib/postgresql/9.6/bin/postgres", "-D", "/var/lib/postgresql/data"] |
---|
13,基于该dockfile创建新镜像
docker build -t eg_postgresql:9.6 . |
---|
14,启动pg容器:
docker run --name pg_pri -v /storage/docker/postgresql:/var/lib/postgresql -v /backup/postgresql:/backup -p 5436:5432 -d eg_postgresql:9.6 docker ps |grep pg_pri 6ccecb527eaa eg_postgresql "/usr/lib/postgresql/" 9 seconds ago Up 9 seconds 5432/tcp pg_pri |
---|
15,以postgres用户进入容器
docker exec -it pg_pri /bin/bash 然后使用psql即可连接到pg库内部 postgres@6ccecb527eaa:/$ ps -ef|grep post postgres 1 0 0 07:42 ? 00:00:00 /usr/lib/postgresql/9.5/bin/postgres -D /var/lib/postgresql/data postgres 6 1 0 07:42 ? 00:00:00 postgres: logger process postgres 8 1 0 07:42 ? 00:00:00 postgres: checkpointer process postgres 9 1 0 07:42 ? 00:00:00 postgres: writer process postgres 10 1 0 07:42 ? 00:00:00 postgres: wal writer process postgres 11 1 0 07:42 ? 00:00:00 postgres: autovacuum launcher process postgres 12 1 0 07:42 ? 00:00:00 postgres: archiver process postgres 13 1 0 07:42 ? 00:00:00 postgres: stats collector process postgres 14 0 0 07:43 ? 00:00:00 /bin/bash postgres 22 14 0 07:43 ? 00:00:00 ps -ef postgres 23 14 0 07:43 ? 00:00:00 /bin/bash postgres@6ccecb527eaa:/$ |
---|
16,以root用户进入容器的方式如下:
docker exec -u root -it pg_pri /bin/bash |
---|
17,将镜像打包
docker stop pg_pri docker save -o eg_postgresql.tar eg_postgresql:9.6 |
---|
18,传输到pg从库所在的机器上
scp eg_postgresql.tar core@192.168.17.62:/tmp/. |
---|
19,在pg从库机器上load image
docker load -i /tmp/eg_postgresql.tar |
---|
------搭建流复制从库
1,使用psql登录pg主库操作
主库创建流复制用户: CREATE USER repuser replication LOGIN CONNECTION LIMIT 3 ENCRYPTED PASSWORD 'repuser'; 主库开启备份: select pg_start_backup('Replition work'); |
---|
2,在主库宿主机操作
cd /storage/docker/postgresql tar cvf data.tar data scp data.tar core@192.168.17.62:/tmp/. |
---|
3,使用psql登录pg主库操作
主库结束备份: select pg_stop_backup(), current_timestamp; |
---|
4,在pg从库宿主机器上操作
mkdir -p /backup/postgresql mkdir -p /storage/docker/postgresql cp /tmp/data.tar /storage/docker/postgresql/. tar xvf /storage/docker/postgresql/data.tar |
---|
5,在pg从库宿主机器上操作
cd /storage/docker/postgresql/data 删除slave端(从master端拷过来的)的pid文件(若有的话) rm -f $PGDATA/postmaster.pid |
---|
6,编辑recover配置文件
cd /storage/docker/postgresql/data vi recovery.conf standby_mode = 'on' primary_conninfo = 'host=192.168.17.61 port=5436 user=repuser password=repuser keepalives_idle=60' trigger_file = '/var/lib/postgresql/data/primary_down' |
---|
7,修改权限
对应容器内postgres用户的uid、gid是105、109 cd /storage/docker chown -R 105:109 postgresql |
---|
8,启动从库容器
docker run --name pg_slv -v /storage/docker/postgresql:/var/lib/postgresql -v /backup/postgresql:/backup -p 5436:5432 -d eg_postgresql:9.6 |
---|
9,进入从库容器
work2 data # docker ps |grep pg_slv docker exec -it pg_slv /bin/bash postgres@c46867d3d0f5:~/data$ ps -ef|grep pos
|
---|
现在可以在主库建表测试是否正常同步到从库了。
------手动主从库切换:
1,停止主库(模拟主库故障)
pg_ctl stop pg_pri |
---|
2,在从库容器内(pg_slv)执行touch trigger file,触发从库提升为新主库
touch /var/lib/postgresql/data/primary_down 2017-03-29 07:01:40 GMT::@:[7]: LOG: trigger file found: /var/lib/postgresql/primary_down |
---|
此时也会发现原从库的recovery.conf文件的名字变成了recovery.done。
3,在新主库进行一些操作,让其与原主库的数据不一致
postgres=# drop table t1; postgres=# \q |
---|
4,配置原主库的recovery.conf (要增加选项recovery_target_timeline = 'latest')
standby_mode = 'on' primary_conninfo = 'host=192.168.17.62 port=5436 user=repuser password=repuser keepalives_idle=60' trigger_file = '/var/lib/postgresql/data/primary_down' recovery_target_timeline = 'latest' |
---|
5,启动原主库为新主库的从库
docker start pg_pri
|
---|
6,要将新主库的pg_xlog路径下的最新的.history文件(newst timeline file)copy到主库的pg_xlog路径下
postgres@e9397096d23b:~/data/pg_xlog$ vi 00000003.history 1 0/10000420 no recovery target specified |
---|
7,再次启动原主库为从库
docker start pg_pri 日志正常: 2017-03-29 07:10:09 GMT::@:[7]: LOG: entering standby mode 2017-03-29 07:10:09 GMT::@:[7]: LOG: consistent recovery state reached at 0/10000420 2017-03-29 07:10:09 GMT::@:[7]: LOG: invalid record length at 0/10000420 2017-03-29 07:10:09 GMT::@:[1]: LOG: database system is ready to accept read only connections 2017-03-29 07:10:09 GMT::@:[11]: LOG: started streaming WAL from primary at 0/10000000 on timeline 3 2017-03-29 07:10:09 GMT::@:[7]: LOG: redo starts at 0/10000420 |
---|
8,登录到新从库里面,发现数据已经重新同步
postgres@e9397096d23b:/$ psql postgres=# select * from t2; postgres=# \q |
---|
所有评论(0)