This project includes dockerfiles for postgresql cluster and example of docker-compose file to start this cluster. Directory k8s contains information for building this cluster in kubernetes
Also this example of cluster setup suitable for production environment as it has fault protection with auto failover system.
Two docker images were produced:
pgmaster (primary node1) --|
|- pgslave1 (node2) --|
| |- pgslave2 (node3) --|----pgpool (master_slave_mode stream)
|- pgslave3 (node4) --|
|- pgslave4 (node5) --|
Each postgres node (pgmaster, pgslaveX) is managed by repmgr/repmgrd. It allows to use automatic failover and
To start cluster run it as normal docker-compose application docker-compose up
Please check comments for each ENV variable in docker-compose file to understand related parameter of cluster's node
To make it easier repository contains scripts for starting cluster using docker-machine and services' objects under k8s dir
Requires software: docker-machine and kubectl
./k8s/scripts/cluster/up.sh and wait until all pods up (to check it you acn use command kubectl get pod --all-namespaces)
Sometimes you can have problem with auto installation of DNS (after message Unable to connect to the server: EOF)
So do it manually with commands docker-machine ssh $(docker-machine active) -N -L 8080:localhost:8080(in separate terminal), kubectl create namespace kube-system && kubectl create -f ./build/skydns.yaml./k8s/scripts/up.sh and check all pods are ready kubectl get pod./k8s/scripts/setup_context.sh && kubectl create ns app (check namespace exists kubectl get ns)kubectl create -f ./k8s/database-service/node1-master.yamlkubectl create -f ./k8s/database-service/node2.yaml && kubectl create -f ./k8s/database-service/node4.yaml (node2 and node4 need around 4 minutes to start daemon)kubectl create -f ./k8s/database-service/node3.yaml && kubectl create -f ./k8s/database-service/node5.yaml (node3 and node5 need around 6 minutes to start daemon)kubectl create -f ./k8s/database-service/pgpool.yaml (need around 3 minutes to start service)>>> Registering node with initial role master|standby>>> Starting repmgr daemon...PGPASSWORD=monkey_pass psql -Umonkey_user -h192.168.99.100 -p5430 monkey_dbdocker exec -it "$(docker ps | grep 'postgresql-cluster-pgsql' | grep node1 | awk '{print $1}')" gosu postgres repmgr cluster showInitial topology:
Role | Name | Upstream | Connection String
----------+-------|----------|------------------------------------------------------------------------------------------------------------
* master | node1 | | user=replication_user password=replication_pass host=database-node1-service dbname=replication_db port=5432
standby | node2 | node1 | user=replication_user password=replication_pass host=database-node2-service dbname=replication_db port=5432
standby | node4 | node1 | user=replication_user password=replication_pass host=database-node4-service dbname=replication_db port=5432
standby | node3 | node2 | user=replication_user password=replication_pass host=database-node3-service dbname=replication_db port=5432
standby | node5 | node4 | user=replication_user password=replication_pass host=database-node5-service dbname=replication_db port=5432
Topology after master death (kubectl delete service database-node1-service)
Role | Name | Upstream | Connection String
----------+-------|----------|------------------------------------------------------------------------------------------------------------
standby | node3 | node2 | user=replication_user password=replication_pass host=database-node3-service dbname=replication_db port=5432
standby | node5 | node4 | user=replication_user password=replication_pass host=database-node5-service dbname=replication_db port=5432
FAILED | node1 | | user=replication_user password=replication_pass host=database-node1-service dbname=replication_db port=5432
* master | node2 | | user=replication_user password=replication_pass host=database-node2-service dbname=replication_db port=5432
standby | node4 | node2 | user=replication_user password=replication_pass host=database-node4-service dbname=replication_db port=5432
Don't try restart docker-compose without cleaning volumes after any failover (unless you use env variable FORCE_CLEAN=1 in each container) You should update cluster with new topology manually because second start of initial master will bring inconsistent in the cluster. Optionally you can reconfigure your pgpool to ignore initial master before second start
Abnormal but possible situation in cluster:
Role | Name | Upstream | Connection String
----------+-------|----------|----------------------------------------------------------------------------------------------
standby | node3 | node2 | user=replication_user password=replication_pass host=pgslave2 dbname=replication_db port=5432
standby | node5 | node4 | user=replication_user password=replication_pass host=pgslave4 dbname=replication_db port=5432
* master | node1 | | user=replication_user password=replication_pass host=pgmaster dbname=replication_db port=5432
* master | node2 | | user=replication_user password=replication_pass host=pgslave1 dbname=replication_db port=5432
standby | node4 | node2 | user=replication_user password=replication_pass host=pgslave3 dbname=replication_db port=5432
You should take care about delays of starts for different parts of the cluster.
Pgpool should be the last one to start, standbys servers should start after upstreams, etc
In docker-compose you can find example of _DELAY-s but it still can be wrong.
According your system and it's performance you should adjust those env variables.
gosu postgres repmgr cluster showKill master container and in a few moments cluster will define new master node, and Pgpool will try to detect new primary node for write access automatically.
Instead of one pgpool node you can have as many as you wish and balance load on them. It's possible because pgpool does'not control cluster and does dummy balancing with primary server detection.
Content type
Image
Digest
Size
311 MB
Last updated
about 10 years ago
docker pull solsson/pgadmin:insecure