High Availability PostgreSQL Cluster Menggunakan Patroni dan HAProxy
Pada tutorial kali ini kita akan mencoba membuat high availabiliy postgresql, seperti yang telah diinformasikan pada tutorial – tutorial sebelumnya postgresql sendiri sebuah database server open source yang dapat digunakan karena postgresql sangat power full.
Kali ini kita akan membuat cluster postgresql tujuannya untuk high availability dan menunjang kebutuhan aplikasi tentunya.
Berikut topologi yang akan kami gunakan
Dari topologi diatas kita perlu 5 node server atau virtual machine atau instance yang dapat digunakan dengan detail sebagai berikut
Name/Hostname | IP Address Lokal / Public | Keterangan |
Hamim-pg01 /node01 | 192.168.10.21 | Postgresql, Patroni |
Hamim-pg02 /node02 | 192.168.10.24 | Postgresql, Patroni |
Hamim-pg03 /node03 | 192.168.10.28 | Postgresql, Patroni |
Hamim-etcd /node04 | 192.168.10.27 | Etcd |
Hamim-Haproxy /node05 | 192.168.10.23 / 103.93.52.117 | HAProxy |
Keterangan:
– Patroni: Digunakan untuk mengelola konfigurasi postgresql
– Etcd: Digunakan untuk cluster postgresql
– HAProxy: Digunakan untuk failover atau load balancing postgresql
Pertama yang harus di lakukan yaitu melakukan update sistem operasi CentOS 8 Anda di masing – masing node dan disini kami setup hostname masing – masing node seperti berikut
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#Node 01
[root@node01 ~]# hostnamectl |grep hostname
Static hostname: node01.nurhamim.my.id
[root@node01 ~]#
#Node02
[root@node02 ~]# hostnamectl |grep hostname
Static hostname: node02.nurhamim.my.id
[root@node02 ~]#
#Node03
[root@node03 ~]# hostnamectl |grep hostname
Static hostname: node03.nurhamim.my.id
[root@node03 ~]#
#Node04
[root@node04 ~]# hostnamectl |grep hostname
Static hostname: node04.nurhamim.my.id
[root@node04 ~]#
#Node05
[root@node05 ~]# hostnamectl |grep hostname
Static hostname: node05.nurhamim.my.id
[root@node05 ~]#
Selanjutnya menambahkan repository epel di node01, node02 dan node03 dan install repository paket manager seperti berikut
Node01
1
2
3
4
5
[root@node01 ~]#
[root@node01 ~]# dnf -y install epel-release -y
[root@node01 ~]# dnf config-manager --set-enabled PowerTools
[root@node01 ~]# dnf -y install yum-utils -y
Node02
1
2
3
4
5
[root@node02 ~]#
[root@node02 ~]# dnf -y install epel-release -y
[root@node02 ~]# dnf config-manager --set-enabled PowerTools
[root@node02 ~]# dnf -y install yum-utils -y
Node03
1
2
3
4
5
[root@node03 ~]#
[root@node03 ~]# dnf -y install epel-release -y
[root@node03 ~]# dnf config-manager --set-enabled PowerTools
[root@node03 ~]# dnf -y install yum-utils -y
Selanjutnya menambahkan repository postgresql 12 di node01, node02, node03 dan disable module postgresql default CentOS 8
Node01
1
2
3
4
5
6
[root@node01 ~]#
[root@node01 ~]# dnf -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm
[root@node01 ~]# yum-config-manager --enable pgdg12
[root@node01 ~]# dnf -qy module disable postgresql
[root@node01 ~]#
Node02
1
2
3
4
5
6
[root@node02 ~]#
[root@node02 ~]# dnf -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm
[root@node02 ~]# yum-config-manager --enable pgdg12
[root@node02 ~]# dnf -qy module disable postgresql
[root@node02 ~]#
Node03
1
2
3
4
5
[root@node03 ~]# dnf -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm
[root@node03 ~]# yum-config-manager --enable pgdg12
[root@node03 ~]# dnf -qy module disable postgresql
[root@node03 ~]#
Selanjutnya install postgresql12 di node01, nod02 dan node03
1
2
3
4
5
6
7
8
[root@node01 ~]#
[root@node01 ~]# dnf -y install postgresql12-server postgresql12 postgresql12-devel
[root@node02 ~]#
[root@node02 ~]# dnf -y install postgresql12-server postgresql12 postgresql12-devel
[root@node03 ~]#
[root@node03 ~]# dnf -y install postgresql12-server postgresql12 postgresql12-devel
Selanjutnya melakukan instalasi patroni. Patroni sendiri merupakan paket python dan open source yang dapat digunakan untuk mengelola konfigurasi Postgres. Selain itu dengan patroni Anda dapat melakukan konfigurasi yang komplek misalnya menangani tugas-tugas seperti replikasi, backup, dan restorasi.
Silakan install patroni di node01, node02 dan node03
Node01
1
2
3
4
5
[root@node01 ~]#
[root@node01 ~]# dnf -y install https://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/p/python3-psycopg2-2.7.7-2.el7.x86_64.rpm
[root@node01 ~]#
[root@node01 ~]# dnf -y install https://github.com/cybertec-postgresql/patroni-packaging/releases/download/1.6.0-1/patroni-1.6.0-1.rhel7.x86_64.rpm
Node02
1
2
3
4
5
[root@node02 ~]#
[root@node02 ~]# dnf -y install https://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/p/python3-psycopg2-2.7.7-2.el7.x86_64.rpm
[root@node02 ~]#
[root@node02 ~]# dnf -y install https://github.com/cybertec-postgresql/patroni-packaging/releases/download/1.6.0-1/patroni-1.6.0-1.rhel7.x86_64.rpm
Node03
1
2
3
4
5
[root@node03 ~]#
[root@node03 ~]# dnf -y install https://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/p/python3-psycopg2-2.7.7-2.el7.x86_64.rpm
[root@node03 ~]#
[root@node03 ~]# dnf -y install https://github.com/cybertec-postgresql/patroni-packaging/releases/download/1.6.0-1/patroni-1.6.0-1.rhel7.x86_64.rpm
Sebelum melakukan konfigurasi patroni ada baiknya kita simpan default konfigurasi patroni tujuannya untuk jaga – jaga jika dikemudian hari membutuhkannya.
Silakan copy file konfigurasi patroni di nod01, node02 dan node03
1
2
3
4
5
6
7
8
[root@node01 ~]# cp -p /opt/app/patroni/etc/postgresql.yml.sample /opt/app/patroni/etc/postgresql.yml
[root@node01 ~]#
[root@node02 ~]# cp -p /opt/app/patroni/etc/postgresql.yml.sample /opt/app/patroni/etc/postgresql.yml
[root@node02 ~]#
[root@node03 ~]# cp -p /opt/app/patroni/etc/postgresql.yml.sample /opt/app/patroni/etc/postgresql.yml
[root@node03 ~]#
Langkah selanjutnya melakukan konfigurasi patroni di node01, node02 dan node03
Buka file konfigurasi patroni yang beradi di /opt/app/patroni/etc/postgresql.yml di masing – masing node postgresql
Berikut full konfigurasinya
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
scope: postgres
namespace: /pg_cluster/
name: node1
restapi:
listen: 192.168.10.21:8008
connect_address: 192.168.10.21:8008
etcd:
host: 192.168.10.27:2379
bootstrap:
dcs:
ttl: 30
loop_wait: 10
retry_timeout: 10
maximum_lag_on_failover: 1048576
postgresql:
use_pg_rewind: true
use_slots: true
parameters:
initdb:
- encoding: UTF8
- data-checksums
pg_hba:
- host replication replicator 127.0.0.1/32 md5
- host replication replicator 192.168.10.21/27 md5
- host replication replicator 192.168.10.24/27 md5
- host replication replicator 192.168.10.28/27 md5
- host all all 0.0.0.0/0 md5
users:
admin:
password: admin
options:
- createrole
- createdb
postgresql:
listen: 192.168.10.21:5432
connect_address: 192.168.10.21:5432
data_dir: /var/lib/pgsql/12/data
bin_dir: /usr/pgsql-12/bin
pgpass: /tmp/pgpass
authentication:
replication:
username: replicator
password: reppassword
superuser:
username: postgres
password: postgrespassword
categories:
nofailover: false
noloadbalance: false
clonefrom: false
nosync: false
Noted: Silakan sesuaikan penamaan dan ip di setiap node – node postgresql dan serta pastikan input ip node04 etcd karena nantinya patroni akan berkomunikasi atau terhubung dengan etcd sebagai cluster.
Berikut contoh di konfigurasi patroni di node01, node02 dan node03
Node01
1
2
[root@node01 ~]#
[root@node01 ~]# vim /opt/app/patroni/etc/postgresql.yml
Node02
1
2
[root@node02 ~]#
[root@node02 ~]# vim /opt/app/patroni/etc/postgresql.yml
Node03
1
2
[root@node03 ~]#
[root@node03 ~]# vim /opt/app/patroni/etc/postgresql.yml
Jika patroni digunakan sebagai pengelola si postgresql maka si etcd digunakan sebagai cluster patroni dan postgresql
Etcd adalah salah satu dari beberapa solusi untuk masalah yang dihadapi oleh banyak program yang berjalan secara terdistribusi pada sekumpulan host, yang masing-masing mungkin gagal atau perlu di-boot ulang kapan saja.
Etcd cluster juga dapat memonitoring dan menentukan streaming replication postgresql node mana yang akan menjadi sebagai primary dan node mana yang akan menjadi standby.
Dari beberapa referensi untuk lebih powerfull dan jika sudah masuk ke production sangat disarankan menggunakan etcd di masing – masing node patroni dan untuk tutorial kali ini kita hanya menggunakan satu node saja. Kenapa menggunakan banyak node etcd?. Tujuannya jika terdapat salah satu node etcd down maka tidak akan memngaruhi node postgresql Anda.
Etcd Cluster disini kami akan diinstall di Node04 dan berikut cara instalasinya
1
2
[root@node04 ~]#
[root@node04 ~]# dnf -y install http://mirror.centos.org/centos/7/extras/x86_64/Packages/etcd-3.3.11-2.el7.centos.x86_64.rpm
Konfigurasi etcd
1
2
[root@node04 ~]#
[root@node04 ~]# vim /etc/etcd/etcd.conf
Berikut full konfigurasi etcd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#[Member]
#ETCD_CORS=""
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
#ETCD_WAL_DIR=""
ETCD_LISTEN_PEER_URLS="http://192.168.10.27:2380"
ETCD_LISTEN_CLIENT_URLS="http://192.168.10.27:2379"
#ETCD_MAX_SNAPSHOTS="5"
#ETCD_MAX_WALS="5"
ETCD_NAME="default"
#ETCD_SNAPSHOT_COUNT="100000"
#ETCD_HEARTBEAT_INTERVAL="100"
#ETCD_ELECTION_TIMEOUT="1000"
#ETCD_QUOTA_BACKEND_BYTES="0"
#ETCD_MAX_REQUEST_BYTES="1572864"
#ETCD_GRPC_KEEPALIVE_MIN_TIME="5s"
#ETCD_GRPC_KEEPALIVE_INTERVAL="2h0m0s"
#ETCD_GRPC_KEEPALIVE_TIMEOUT="20s"
#
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.10.27:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.10.27:2379"
#ETCD_DISCOVERY=""
#ETCD_DISCOVERY_FALLBACK="proxy"
#ETCD_DISCOVERY_PROXY=""
#ETCD_DISCOVERY_SRV=""
ETCD_INITIAL_CLUSTER="default=http://192.168.10.27:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
#ETCD_STRICT_RECONFIG_CHECK="true"
#ETCD_ENABLE_V2="true"
#
#[Proxy]
#ETCD_PROXY="off"
#ETCD_PROXY_FAILURE_WAIT="5000"
#ETCD_PROXY_REFRESH_INTERVAL="30000"
#ETCD_PROXY_DIAL_TIMEOUT="1000"
#ETCD_PROXY_WRITE_TIMEOUT="5000"
#ETCD_PROXY_READ_TIMEOUT="0"
#
#[Security]
#ETCD_CERT_FILE=""
#ETCD_KEY_FILE=""
#ETCD_CLIENT_CERT_AUTH="false"
#ETCD_TRUSTED_CA_FILE=""
#ETCD_AUTO_TLS="false"
#ETCD_PEER_CERT_FILE=""
#ETCD_PEER_KEY_FILE=""
#ETCD_PEER_CLIENT_CERT_AUTH="false"
#ETCD_PEER_TRUSTED_CA_FILE=""
#ETCD_PEER_AUTO_TLS="false"
#
#[Logging]
#ETCD_DEBUG="false"
#ETCD_LOG_PACKAGE_LEVELS=""
#ETCD_LOG_OUTPUT="default"
#
#[Unsafe]
#ETCD_FORCE_NEW_CLUSTER="false"
#
#[Version]
#ETCD_VERSION="false"
#ETCD_AUTO_COMPACTION_RETENTION="0"
#
#[Profiling]
#ETCD_ENABLE_PPROF="false"
#ETCD_METRICS="basic"
#
#[Auth]
#ETCD_AUTH_TOKEN="simple"
Noted: Silakan sesuaikan IP dengan IP Node04 dan uncoment rule yang dibutuhkan seperti diatas.
Selanjutnya, enable dan start etcd cluster
1
2
3
4
5
[root@node04 ~]#
[root@node04 ~]# systemctl enable etcd
Created symlink /etc/systemd/system/multi-user.target.wants/etcd.service → /usr/lib/systemd/system/etcd.service.
[root@node04 ~]# systemctl start etcd
[root@node04 ~]# systemctl status etcd
Berikutnya enable dan start service patroni di node01, node02 dan node03
Node01
1
2
3
4
5
[root@node01 ~]#
[root@node01 ~]# systemctl enable patroni
Created symlink /etc/systemd/system/multi-user.target.wants/patroni.service → /usr/lib/systemd/system/patroni.service.
[root@node01 ~]# systemctl start patroni
[root@node01 ~]# systemctl status patroni -l
Node02
1
2
3
4
5
[root@node02 ~]#
[root@node02 ~]# systemctl enable patroni
Created symlink /etc/systemd/system/multi-user.target.wants/patroni.service → /usr/lib/systemd/system/patroni.service.
[root@node02 ~]# systemctl start patroni
[root@node02 ~]# systemctl status patroni -l
Node03
1
2
3
4
5
[root@node03 ~]#
[root@node03 ~]# systemctl enable patroni
Created symlink /etc/systemd/system/multi-user.target.wants/patroni.service → /usr/lib/systemd/system/patroni.service.
[root@node03 ~]# systemctl start patroni
[root@node03 ~]# systemctl status patroni -l
Selanjutnya kita akan install HAProxy. Buat apa HAProxy?
Saat mengembangkan aplikasi yang menggunakan database, mungkin sulit untuk melacak titik akhir database jika terus berubah. Menggunakan HAProxy akan menyederhanakan dengan dengan memberikan satu titik akhir atau jalur kemana Anda menghubungkan aplikasi ke database.
HAProxy juga akan sebagai failover atau load balancer tugasnya meneruskan koneksi ke node mana pun yang saat ini menjadi master atau primary (postgresql). Patroni sebagai manajemen postgresql akan memastikan bahwa, pada waktu tertentu, hanya node master postgresql yang akan muncul sebagai online, dan memaksa HAProxy untuk terhubung ke node yang benar.
Jalankan perintah berikut di Node05 untuk instalasi HAProxy
1
2
[root@node05 ~]#
[root@node05 ~]# dnf -y install haproxy
Konfigurasi HAProxy:
1
2
[root@node05 ~]#
[root@node05 ~]# vim /etc/haproxy/haproxy.cfg
Berikut full konfigurasi HAProxy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
global
maxconn 100
log 127.0.0.1 local2
defaults
log global
mode tcp
retries 2
timeout client 30m
timeout connect 4s
timeout server 30m
timeout check 5s
listen stats
mode http
bind *:2233
stats hide-version
stats refresh 30s
stats show-node
stats auth username:password
stats enable
stats uri /
listen postgres
bind *:5000
option httpchk
http-check expect status 200
default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions
server node1 192.168.10.21:5432 maxconn 100 check port 8008
server node2 192.168.10.24:5432 maxconn 100 check port 8008
server node3 192.168.10.28:5432 maxconn 100 check port 8008
Noted: Set default HAProxy menjadi tcp dan input node postgresql
Simpan pastikan tidak ada konfigurasi yang salah, lalu restart HAProxy dan pastikan statusnya running
1
2
3
4
5
[root@node05 ~]# haproxy -c -V -f /etc/haproxy/haproxy.cfg
Configuration file is valid
[root@node05 ~]#
[root@node05 ~]# systemctl restart haproxy
[root@node05 ~]# systemctl status haproxy -l
Langkah terakhir kita akan mencoba melakukan percobaan login ke postgresql menggunakan IP Load Balancer atau HAProxy dan menggunakan port 5000 yang sudah di set up di sisi HAProxy sebelumnya
Seperti yang Anda lihat pada gambar diatas saat ini client atau user dapat akses ke sisi database postgresql melalui IP HAProxy.
Silakan akses IP Public HAProxy Anda melalui browser menggunakan port 2233 sesuai konfigurasi HAProxy diatas dan hasilnya seperti berikut
Seperti yang Anda lihat pada gambar di atas, baris (node1) disorot dengan warna hijau. Ini menunjukkan bahwa (node1 192.168.10.21) saat ini bertindak sebagai master atau primary dan sisanya (node02, node03) bertindak sebagai standby.
Jika Anda mematikan node master dengan perintah systemctl stop patroni atau dengan mematikan server sepenuhnya, dashboard akan terlihat seperti di bawah ini:
Proses Load Balancing / Failover
Saat ini node02 bertindak sebagai master
Di bagian Postgres pada gambar di atas, baris (node1) sekarang berwarna merah dan baris (node2) disorot dengan warna hijau. Ini menunjukkan bahwa (node2 192.168.10.24) saat ini bertindak sebagai master.
Catatan: Dalam kasus ini, kebetulan server Postgres kedua dipromosikan menjadi master. Ini mungkin tidak selalu terjadi jika Anda memiliki lebih dari dua node di cluster. Kemungkinan yang sama bahwa server ketiga dapat dipromosikan menjadi master, contoh seperti gambar dibawah ini
Dimaan node01 dan node03 dipromosikan sebagai master.
Selamat mencoba 😁