Skip to content

Commit 9f5f61c

Browse files
committed
[#27,#28] swarm: add init-eg-swarm,docker-compose.swarm.yml
Per discussions in: - #27 - #28
1 parent 3f3dc2e commit 9f5f61c

File tree

3 files changed

+230
-0
lines changed

3 files changed

+230
-0
lines changed

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,27 @@ bin/init-eg
9696
```
9797

9898

99+
## Clustering (Swarm; Automatically)
100+
101+
If you're running on Docker Swarm, you can use the provided example
102+
`docker-compose.swarm.yml` as a starting point, deploying with
103+
`docker stack deploy`, along with the init script. Note that the example makes
104+
various assumptions, such as that the Swarm node is a manager, that it is tagged
105+
with `grp=dbxl`, and that `db_a` has a lower subnet than `db_b` (which might or
106+
might not happen automatically; create the networks manually, if you're having
107+
trouble).
108+
109+
```sh
110+
bin/init-eg-swarm STACK_NAME
111+
```
112+
113+
Note there are various caveats to using this, which you can read about in detail
114+
here:
115+
116+
- https://github.com/pavouk-0/postgres-xl-docker/issues/27
117+
- https://github.com/pavouk-0/postgres-xl-docker/pull/28
118+
119+
99120
## Clustering (Manually)
100121

101122
Prepare a clustering query, able to be executed on each node. Simplest is to use

bin/init-eg-swarm

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#!/bin/bash -u
2+
3+
stack=$1
4+
5+
nodes=(db_coord_1 db_coord_2 db_data_1 db_data_2)
6+
PG_USER_HEALTHCHECK=_healthcheck
7+
#-------------------------------------------------------------------------------
8+
function log() {
9+
local msg="$*"
10+
11+
echo "$(date -Is), $msg"
12+
}
13+
14+
function startup() {
15+
log "========================================"
16+
}
17+
18+
function shutdown() {
19+
log "----------------------------------------"
20+
}
21+
22+
function srv() {
23+
local node=$1
24+
shift
25+
26+
docker exec "$node" "$@"
27+
}
28+
29+
function cmd() {
30+
local node=$1
31+
shift
32+
33+
log "$@"
34+
srv "$node" psql -c "$@"
35+
}
36+
37+
function get_container() {
38+
local node=$1
39+
40+
id=$(docker service ps -f 'desired-state=running' -q "${stack}_${node}" |
41+
head -n1)
42+
echo "${stack}_${node}.1.${id}"
43+
}
44+
45+
function get_healthcheck() {
46+
local node=$1
47+
48+
docker service inspect "${stack}_${node}" \
49+
-f '{{ index .Spec.TaskTemplate.ContainerSpec.Healthcheck.Test 1 }}'
50+
}
51+
52+
trap shutdown EXIT
53+
#-------------------------------------------------------------------------------
54+
startup
55+
56+
for node in "${nodes[@]}" ; do
57+
ctnr=$(get_container "$node")
58+
59+
cmd "$ctnr" "CREATE NODE coord_1 WITH (TYPE = 'coordinator', HOST = 'db_coord_1', PORT = 5432);"
60+
cmd "$ctnr" "CREATE NODE coord_2 WITH (TYPE = 'coordinator', HOST = 'db_coord_2', PORT = 5432);"
61+
cmd "$ctnr" "CREATE NODE data_1 WITH (TYPE = 'datanode', HOST = 'db_data_1', PORT = 5432);"
62+
cmd "$ctnr" "CREATE NODE data_2 WITH (TYPE = 'datanode', HOST = 'db_data_2', PORT = 5432);"
63+
cmd "$ctnr" "ALTER NODE coord_1 WITH (TYPE = 'coordinator', HOST = 'db_coord_1', PORT = 5432);"
64+
cmd "$ctnr" "ALTER NODE coord_2 WITH (TYPE = 'coordinator', HOST = 'db_coord_2', PORT = 5432);"
65+
cmd "$ctnr" "ALTER NODE data_1 WITH (TYPE = 'datanode', HOST = 'db_data_1', PORT = 5432);"
66+
cmd "$ctnr" "ALTER NODE data_2 WITH (TYPE = 'datanode', HOST = 'db_data_2', PORT = 5432);"
67+
cmd "$ctnr" "SELECT pgxc_pool_reload();"
68+
cmd "$ctnr" "SELECT * FROM pgxc_node;"
69+
done
70+
71+
for node in "${nodes[@]}" ; do
72+
healthcheck=$(get_healthcheck "$node")
73+
74+
docker service update "${stack}_${node}" \
75+
--health-cmd "$healthcheck || true"
76+
done
77+
78+
while true ; do
79+
log "WAITING"
80+
81+
for node in "${nodes[@]}" ; do
82+
ctnr=$(get_container "$node")
83+
84+
srv "$ctnr" psql -tc "SELECT 1 FROM pg_database
85+
WHERE datname = '${PG_USER_HEALTHCHECK}'" |
86+
grep -q 1 && break 2
87+
done
88+
89+
sleep 1
90+
done
91+
92+
log "REDEPLOY stack now !" # to reset healthchecks, and reboot

docker-compose.swarm.yml

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
version: "3.7"
2+
services:
3+
#-----------------------------------------------------------------------------
4+
db_gtm_1:
5+
environment:
6+
- PG_HOST=0.0.0.0
7+
- PG_NODE=gtm_1
8+
- PG_PORT=6666
9+
image: pavouk0/postgres-xl:latest # pin for prod !
10+
command: docker-cmd-gtm
11+
entrypoint: docker-entrypoint-gtm
12+
volumes:
13+
- db_gtm_1:/var/lib/postgresql
14+
networks:
15+
- db_a
16+
healthcheck:
17+
test: ["CMD", "docker-healthcheck-gtm"]
18+
deploy:
19+
placement:
20+
constraints:
21+
- node.labels.grp == dbxl # assumes shared volume storage, or 1-node
22+
db_coord_1:
23+
environment:
24+
- PG_GTM_HOST=db_gtm_1
25+
- PG_GTM_PORT=6666
26+
- PG_HOST=0.0.0.0
27+
- PG_NODE=coord_1
28+
- PG_PORT=5432
29+
image: pavouk0/postgres-xl:latest # pin for prod !
30+
command: docker-cmd-coord
31+
entrypoint: docker-entrypoint-coord
32+
volumes:
33+
- db_coord_1:/var/lib/postgresql
34+
networks:
35+
- db_a
36+
- db_b
37+
healthcheck:
38+
test: ["CMD", "docker-healthcheck-coord"]
39+
deploy:
40+
placement:
41+
constraints:
42+
- node.labels.grp == dbxl # assumes shared volume storage, or 1-node
43+
db_coord_2:
44+
environment:
45+
- PG_GTM_HOST=db_gtm_1
46+
- PG_GTM_PORT=6666
47+
- PG_HOST=0.0.0.0
48+
- PG_NODE=coord_2
49+
- PG_PORT=5432
50+
image: pavouk0/postgres-xl:latest # pin for prod !
51+
command: docker-cmd-coord
52+
entrypoint: docker-entrypoint-coord
53+
volumes:
54+
- db_coord_2:/var/lib/postgresql
55+
networks:
56+
- db_a
57+
- db_b
58+
healthcheck:
59+
test: ["CMD", "docker-healthcheck-coord"]
60+
deploy:
61+
placement:
62+
constraints:
63+
- node.labels.grp == dbxl # assumes shared volume storage, or 1-node
64+
db_data_1:
65+
environment:
66+
- PG_GTM_HOST=db_gtm_1
67+
- PG_GTM_PORT=6666
68+
- PG_HOST=0.0.0.0
69+
- PG_NODE=data_1
70+
- PG_PORT=5432
71+
image: pavouk0/postgres-xl:latest # pin for prod !
72+
command: docker-cmd-data
73+
entrypoint: docker-entrypoint-data
74+
volumes:
75+
- db_data_1:/var/lib/postgresql
76+
networks:
77+
- db_a
78+
healthcheck:
79+
test: ["CMD", "docker-healthcheck-data"]
80+
deploy:
81+
placement:
82+
constraints:
83+
- node.labels.grp == dbxl # assumes shared volume storage, or 1-node
84+
db_data_2:
85+
environment:
86+
- PG_GTM_HOST=db_gtm_1
87+
- PG_GTM_PORT=6666
88+
- PG_HOST=0.0.0.0
89+
- PG_NODE=data_2
90+
- PG_PORT=5432
91+
image: pavouk0/postgres-xl:latest # pin for prod !
92+
command: docker-cmd-data
93+
entrypoint: docker-entrypoint-data
94+
volumes:
95+
- db_data_2:/var/lib/postgresql
96+
networks:
97+
- db_a
98+
healthcheck:
99+
test: ["CMD", "docker-healthcheck-data"]
100+
deploy:
101+
placement:
102+
constraints:
103+
- node.labels.grp == dbxl # assumes shared volume storage, or 1-node
104+
#-----------------------------------------------------------------------------
105+
volumes:
106+
db_gtm_1: {}
107+
db_coord_1: {}
108+
db_coord_2: {}
109+
db_data_1: {}
110+
db_data_2: {}
111+
networks:
112+
db_a:
113+
driver: overlay
114+
internal: true
115+
db_b:
116+
driver: overlay
117+
internal: true

0 commit comments

Comments
 (0)