Skip to content

Commit dc39598

Browse files
authored
Review docs, Dockerfile, and tutorials. (#964)
The test image now contains more debugging tools. Improve our tutorial by not requiring an external docker volume in the environment, having the volume only available within the docker-compose context is all we need here. Small improvement: make the app image respect the SIGTERM that docker-compose down sends, by rewritting it using Python this time.
1 parent 4e9f485 commit dc39598

File tree

14 files changed

+262
-95
lines changed

14 files changed

+262
-95
lines changed

Dockerfile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,11 @@ RUN apt-get update \
5555
watch \
5656
lsof \
5757
psutils \
58-
valgrind \
58+
psmisc \
59+
htop \
60+
less \
61+
mg \
62+
valgrind \
5963
postgresql-common \
6064
&& rm -rf /var/lib/apt/lists/*
6165

docs/citus-quickstart.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,15 @@ node too:
455455
-------
456456
75
457457

458+
Cleanup
459+
-------
460+
461+
To dispose of the entire tutorial environment, just use the following command:
462+
463+
::
464+
465+
$ docker-compose down
466+
458467
Next steps
459468
----------
460469

docs/citus/Dockerfile.app

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ RUN apt-get update \
1313
watch \
1414
lsof \
1515
psutils \
16+
python3 \
1617
&& rm -rf /var/lib/apt/lists/*
1718

1819
# we use apt.postgresql.org
@@ -29,5 +30,7 @@ RUN adduser --disabled-password --gecos '' docker
2930
RUN adduser docker sudo
3031
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
3132

33+
COPY ./app.py /usr/src/app/app.py
34+
3235
USER docker
33-
ENTRYPOINT while true; do date -R; sleep 600; done
36+
ENTRYPOINT [ "/usr/src/app/app.py" ]

docs/citus/app.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#! /usr/bin/env python3
2+
3+
#
4+
# Write a Python application that knows how to exit gracefully when
5+
# receiving SIGTERM (at docker-compose down time), but doesn't know how to
6+
# do much else.
7+
#
8+
9+
import sys
10+
import time
11+
import signal
12+
from datetime import datetime
13+
14+
15+
def sigterm_handler(_signo, _stack_frame):
16+
sys.exit(0)
17+
18+
19+
signal.signal(signal.SIGTERM, sigterm_handler)
20+
21+
if __name__ == "__main__":
22+
try:
23+
while True:
24+
print("%s" % datetime.now())
25+
time.sleep(600)
26+
except BaseException:
27+
# Keyboard Interrupt or something
28+
pass

docs/install.rst

Lines changed: 41 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ To avoid automated creation of a Postgres data directory when installing the
4141
debian package, follow those steps:
4242

4343
::
44-
44+
4545
$ curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
4646
$ echo "deb http://apt.postgresql.org/pub/repos/apt buster-pgdg main" > /etc/apt/sources.list.d/pgdg.list
47-
47+
4848
# bypass initdb of a "main" cluster
4949
$ echo 'create_main_cluster = false' | sudo tee -a /etc/postgresql-common/createcluster.conf
5050
$ apt-get update
@@ -54,53 +54,19 @@ That way when it's time to :ref:`pg_autoctl_create_monitor` or
5454
:ref:`pg_autoctl_create_postgres` there is no confusion about how to handle
5555
the default Postgres service created by debian: it has not been created at
5656
all.
57-
57+
5858
Fedora, CentOS, or Red Hat
5959
--------------------------
6060

61-
Quick install
62-
~~~~~~~~~~~~~
63-
64-
The following installation method downloads a bash script that automates
65-
several steps. The full script is available for review at our `package cloud
66-
installation instructions page`__ url.
67-
68-
__ https://packagecloud.io/citusdata/community/install#bash
69-
70-
.. code-block:: bash
71-
72-
# add the required packages to your system
73-
curl https://install.citusdata.com/community/rpm.sh | sudo bash
74-
75-
# install pg_auto_failover
76-
sudo yum install -y pg-auto-failover14_12
77-
78-
# confirm installation
79-
/usr/pgsql-12/bin/pg_autoctl --version
80-
81-
Manual installation
82-
~~~~~~~~~~~~~~~~~~~
83-
84-
If you'd prefer to install your repo on your system manually, follow the
85-
instructions from `package cloud manual installation`__ page. This page will
86-
guide you with the specific details to achieve the 3 steps:
87-
88-
1. install the pygpgme yum-utils packages for your distribution
89-
2. install a new RPM reposiroty for CitusData packages
90-
3. update your local yum cache
91-
92-
Then when that's done, you can proceed with installing pg_auto_failover
93-
itself as in the previous case:
94-
95-
.. code-block:: bash
96-
97-
# install pg_auto_failover
98-
sudo yum install -y pg-auto-failover14_12
61+
The Postgres community packaging team for RPM based system has worked on
62+
supporting pg_auto_failover. Binary packages are available by following the
63+
documentation at `PostgreSQL Yum Repository`__.
9964

100-
# confirm installation
101-
/usr/pgsql-12/bin/pg_autoctl --version
65+
__ https://yum.postgresql.org
10266

103-
__ https://packagecloud.io/citusdata/community/install#manual-rpm
67+
A single package named ``pg_auto_failover`` is available on the RPM based
68+
systems, containing both the monitor Postgres extension and the pg_autoctl
69+
command line.
10470

10571
Installing a pgautofailover Systemd unit
10672
----------------------------------------
@@ -140,3 +106,34 @@ It is important that PostgreSQL is started by ``pg_autoctl`` rather than by
140106
systemd itself, as it might be that a failover has been done during a
141107
reboot, for instance, and that once the reboot complete we want the local
142108
Postgres to re-join as a secondary node where it used to be a primary node.
109+
110+
111+
Building pg_auto_failover from sources
112+
--------------------------------------
113+
114+
To build the project, make sure you have installed the build-dependencies,
115+
then just type `make`. You can install the resulting binary using `make
116+
install`.
117+
118+
For this to work please consider adding both the binary and the source
119+
repositories to your debian distribution by using the following apt sources,
120+
as an example targetting the debian bullseye distribution:
121+
122+
::
123+
124+
deb http://apt.postgresql.org/pub/repos/apt bullseye-pgdg main
125+
deb-src http://apt.postgresql.org/pub/repos/apt bullseye-pgdg main
126+
127+
Then we can install the build dependencies for Postgres, knowing that
128+
pg_auto_failover uses the same build dependencies:
129+
130+
::
131+
132+
$ sudo apt-get build-dep -y --no-install-recommends postgresql-14
133+
134+
Then build pg_auto_failover from sources with the following instructions:
135+
136+
::
137+
138+
$ make -s clean && make -s -j12 all
139+
$ sudo make -s install

docs/tutorial.rst

Lines changed: 102 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ or run the docker build command directly:
4343

4444
$ git clone https://github.com/citusdata/pg_auto_failover
4545
$ cd pg_auto_failover/docs/tutorial
46-
47-
$ docker build -t pg_auto_failover:tutorial -f Dockerfile ../..
4846
$ docker-compose build
4947

5048
Postgres failover with two nodes
@@ -74,7 +72,7 @@ following command:
7472

7573
::
7674

77-
$ docker-compose up
75+
$ docker-compose up app monitor node1 node2
7876

7977
The command above starts the services up. The first service is the monitor
8078
and is created with the command ``pg_autoctl create monitor``. The options
@@ -196,6 +194,107 @@ And we can verify that we still have the data available::
196194
75
197195
(1 row)
198196

197+
Multiple Standbys Architectures
198+
-------------------------------
199+
200+
The ``docker-compose.yml`` file comes with a third node that you can bring
201+
up to obtain the following architecture:
202+
203+
.. figure:: ./tikz/arch-multi-standby.svg
204+
:alt: pg_auto_failover Architecture for a standalone PostgreSQL service
205+
206+
pg_auto_failover architecture with a primary and two standby nodes
207+
208+
Adding a second standby node
209+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
210+
211+
To run a second standby node, or a third Postgres node, simply run the
212+
following command:
213+
214+
::
215+
216+
$ docker-compose up -d node3
217+
218+
We can see the resulting replication settings with the following command:
219+
220+
::
221+
222+
$ docker-compose exec monitor pg_autoctl show settings
223+
224+
Context | Name | Setting | Value
225+
----------+---------+---------------------------+-------------------------------------------------------------
226+
formation | default | number_sync_standbys | 1
227+
primary | node1 | synchronous_standby_names | 'ANY 1 (pgautofailover_standby_1, pgautofailover_standby_3)'
228+
node | node2 | candidate priority | 50
229+
node | node1 | candidate priority | 50
230+
node | node3 | candidate priority | 50
231+
node | node2 | replication quorum | true
232+
node | node1 | replication quorum | true
233+
node | node3 | replication quorum | true
234+
235+
Editing the replication settings while in production
236+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
237+
238+
It's then possible to change the production architecture obtained with
239+
playing with the :ref:`architecture_setup` commands. Specifically, try the
240+
following command to change the candidate_priority of the node3 to zero, in
241+
order for it to never be a candidate for failover:
242+
243+
::
244+
245+
$ docker-compose exec node3 pg_autoctl set candidate-priority 0 --name node3
246+
247+
To see the replication settings for all the nodes, the following command can
248+
be useful, and is described in more details in the :ref:`architecture_setup`
249+
section.
250+
251+
::
252+
253+
$ docker-compose exec monitor pg_autoctl show settings
254+
255+
Context | Name | Setting | Value
256+
----------+---------+---------------------------+-------------------------------------------------------------
257+
formation | default | number_sync_standbys | 1
258+
primary | node1 | synchronous_standby_names | 'ANY 1 (pgautofailover_standby_1, pgautofailover_standby_3)'
259+
node | node2 | candidate priority | 50
260+
node | node1 | candidate priority | 50
261+
node | node3 | candidate priority | 0
262+
node | node2 | replication quorum | true
263+
node | node1 | replication quorum | true
264+
node | node3 | replication quorum | true
265+
266+
Then in a separate terminal (but in the same directory, because of the way
267+
docker-compose works with projects), you can run the following watch
268+
command:
269+
270+
::
271+
272+
$ docker-compose exec monitor pg_autoctl watch
273+
274+
And in the main terminal, while the watch command output is visible, you can
275+
run a switchover operation:
276+
277+
::
278+
279+
$ docker-compose exec monitor pg_autoctl perform switchover
280+
281+
Getting familiar with those commands one of you next steps. The manual has
282+
coverage for them in the following links:
283+
284+
* :ref:`pg_autoctl_watch`
285+
* :ref:`pg_autoctl_show_state`
286+
* :ref:`pg_autoctl_show_settings`
287+
* :ref:`pg_autoctl_set_node_candidate_priority`
288+
289+
Cleanup
290+
-------
291+
292+
To dispose of the entire tutorial environment, just use the following command:
293+
294+
::
295+
296+
$ docker-compose down
297+
199298
Next steps
200299
----------
201300

docs/tutorial/Dockerfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,8 @@ COPY src/ ./src
4747
RUN make -s clean && make -s install -j8
4848
RUN cp /usr/lib/postgresql/${PGVERSION}/bin/pg_autoctl /usr/local/bin
4949

50+
RUN install -o docker -m 0755 -d /var/lib/postgres
51+
VOLUME /var/lib/postgres
52+
5053
USER docker
5154
ENV PG_AUTOCTL_DEBUG 1

docs/tutorial/Dockerfile.app

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ RUN apt-get update \
1313
watch \
1414
lsof \
1515
psutils \
16+
python3 \
1617
&& rm -rf /var/lib/apt/lists/*
1718

1819
# we use apt.postgresql.org
@@ -29,5 +30,7 @@ RUN adduser --disabled-password --gecos '' docker
2930
RUN adduser docker sudo
3031
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
3132

33+
COPY ./app.py /usr/src/app/app.py
34+
3235
USER docker
33-
ENTRYPOINT while true; do date -R; sleep 600; done
36+
ENTRYPOINT [ "/usr/src/app/app.py" ]

docs/tutorial/Makefile

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,22 @@ CONTAINER_NAME = pg_auto_failover:tutorial
33
all: build down up;
44

55
build:
6-
docker build -t $(CONTAINER_NAME) -f Dockerfile ../..
76
docker-compose build
87

98
up:
10-
docker-compose up
9+
docker-compose up app monitor node1 node2
10+
11+
node3:
12+
docker-compose up -d node3
1113

1214
down:
13-
docker-compose down --volumes --remove-orphans
14-
rm -rf {monitor,node1,node2,node3}/pgaf/
15+
docker-compose down
1516

1617
state:
1718
docker-compose exec monitor pg_autoctl show state
1819

1920
switchover:
2021
docker-compose exec monitor pg_autoctl perform switchover
22+
23+
watch:
24+
docker-compose exec monitor pg_autoctl watch

docs/tutorial/app.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#! /usr/bin/env python3
2+
3+
#
4+
# Write a Python application that knows how to exit gracefully when
5+
# receiving SIGTERM (at docker-compose down time), but doesn't know how to
6+
# do much else.
7+
#
8+
9+
import sys
10+
import time
11+
import signal
12+
from datetime import datetime
13+
14+
15+
def sigterm_handler(_signo, _stack_frame):
16+
sys.exit(0)
17+
18+
19+
signal.signal(signal.SIGTERM, sigterm_handler)
20+
21+
if __name__ == "__main__":
22+
try:
23+
while True:
24+
print("%s" % datetime.now())
25+
time.sleep(600)
26+
except BaseException:
27+
# Keyboard Interrupt or something
28+
pass

0 commit comments

Comments
 (0)