Cấu hình Postgresql High Availability on premises full setup
Hướng Dẫn Cấu Hình PostgreSQL High Availability (HA) Với Patroni, etcd và HAProxy
Bài viết này hướng dẫn chi tiết cách thiết lập một cụm PostgreSQL High Availability (HA) sử dụng PostgreSQL 17, Patroni để quản lý cụm, etcd để lưu trữ trạng thái, và HAProxy để cân bằng tải. Cụm bao gồm ba máy chủ: một máy chủ chính (leader) và hai máy chủ phụ (replica). Các bước bao gồm cấu hình mạng, cài đặt phần mềm, thiết lập etcd, Patroni, và HAProxy, cùng với kiểm tra kết quả.
Khái niệm
Patroni - template để cấu hình cụm PostgreSQL.
Etcd - kho lưu trữ cấu hình phân tán, trạng thái của cụm PostgreSQL.
HAProxy - cân bằng tải cho cụm và điểm xử lí tín hiệu đọc ghi trên Database vào Cluster.
PgBackRest - giải pháp sao lưu và khôi phục cho PostgreSQL.
Percona Monitoring - theo dõi tình trạng cụm của bạn
Thông tin hệ thống
- Hệ điều hành: Ubuntu 22.04
- Máy chủ:
server-1
: 192.168.65.11 (Leader)server-2
: 192.168.65.12 (Replica)server-3
: 192.168.65.13 (Replica)
- Cấu hình:
- PostgreSQL 17 (Percona distribution)
- Patroni để quản lý cụm HA
- etcd để lưu trạng thái cụm
- HAProxy để cân bằng tải (port 5000 cho primary, 5001 cho replica)
Bước 1: Cấu hình SSH và mạng
1.1. Cấu hình IP tĩnh
Cấu hình địa chỉ IP tĩnh cho từng máy chủ bằng cách chỉnh sửa file cấu hình mạng /etc/netplan/...
.
Trên mỗi máy chủ, chỉnh sửa file Netplan:
sudo vi /etc/netplan/01-netcfg.yaml
Nội dung file Netplan:
network:
ethernets:
ens33:
dhcp4: false
addresses:
- 192.168.65.11/24 # server-1
# server-2: 192.168.65.12/24
# server-3: 192.168.65.13/24
gateway4: 192.168.65.2
nameservers:
addresses: [8.8.8.8, 8.8.4.4]
version: 2
Áp dụng cấu hình:
sudo netplan apply
1.2. Cấu hình SSH
Cho phép đăng nhập root qua SSH để dễ dàng quản lý.
Chỉnh sửa file SSH:
sudo vi /etc/ssh/sshd_config
Sửa dòng:
PermitRootLogin yes
Khởi động lại dịch vụ SSH:
sudo systemctl restart ssh
sudo systemctl restart sshd
Đặt mật khẩu cho root:
sudo passwd
1.3. Cấu hình hostname và hosts
Thêm thông tin vào file /etc/hosts
:
sudo vi /etc/hosts
Nội dung:
192.168.65.11 server-1
192.168.65.12 server-2
192.168.65.13 server-3
Cấu hình hostname trên từng máy chủ:
sudo vi /etc/hostname
- server-1:
server-1
- server-2:
server-2
- server-3:
server-3
Khởi động lại để áp dụng hostname:
sudo reboot
Bước 2: Cài đặt PostgreSQL và các gói liên quan
Thực hiện trên cả ba máy chủ để cài đặt PostgreSQL 17, Patroni, etcd, và các công cụ liên quan.
2.1. Cài đặt các gói
sudo apt update
sudo apt install curl
sudo apt install jq
curl -O https://repo.percona.com/apt/percona-release_latest.generic_all.deb
sudo apt install gnupg2 lsb-release ./percona-release_latest.generic_all.deb
sudo apt update
sudo percona-release setup ppg17
sudo apt install percona-postgresql-17
sudo apt install python3-pip python3-dev binutils
sudo apt install percona-patroni etcd etcd-server etcd-client percona-pgbackrest
2.2. Tắt các dịch vụ tạm thời
sudo systemctl stop etcd patroni postgresql
sudo systemctl disable etcd patroni postgresql
2.3. Cấu hình thư mục và quyền
Tạo thư mục cho mật khẩu:
sudo mkdir /opt/secretpg
sudo chown -R postgres:postgres /opt/secretpg
sudo chmod -R 700 /opt/secretpg
Tạo thư mục dữ liệu PostgreSQL:
sudo mkdir -p /var/run/postgresql/
sudo chown -R postgres:postgres /var/run/postgresql/
sudo chmod 2775 /var/run/postgresql/
2.4. Thiết lập biến môi trường cho Patroni
export NODE_NAME=$(hostname -f)
export NODE_IP=$(hostname -i | awk '{print $1}')
export DATA_DIR="/var/lib/postgresql/17/main"
export PG_BIN_DIR="/usr/lib/postgresql/17/bin"
export NAMESPACE="percona_lab_truongitt"
export SCOPE="clusterdevops_truongitt"
Bước 3: Cấu hình etcd
Cấu hình etcd để quản lý trạng thái cụm PostgreSQL. Bắt đầu từ server-1, sau đó thêm server-2 và server-3.
3.1. Cấu hình etcd trên server-1
Chỉnh sửa file /etc/etcd/etcd.conf.yaml
:
sudo vi /etc/etcd/etcd.conf.yaml
Nội dung:
name: server-1
initial-cluster-token: pgcluster_truongitt
initial-cluster-state: new
initial-cluster: server-1=http://192.168.65.11:2380
data-dir: /var/lib/etcd
initial-advertise-peer-urls: http://192.168.65.11:2380
listen-peer-urls: http://192.168.65.11:2380
advertise-client-urls: http://192.168.65.11:2379
listen-client-urls: http://192.168.65.11:2379
3.2. Cấu hình etcd trên server-2
sudo vi /etc/etcd/etcd.conf.yaml
Nội dung:
name: server-2
initial-cluster-token: pgcluster_truongitt
initial-cluster-state: existing
initial-cluster: server-1=http://192.168.65.11:2380,server-2=http://192.168.65.12:2380
data-dir: /var/lib/etcd
initial-advertise-peer-urls: http://192.168.65.12:2380
listen-peer-urls: http://192.168.65.12:2380
advertise-client-urls: http://192.168.65.12:2379
listen-client-urls: http://192.168.65.12:2379,http://127.0.0.1:2379
3.3. Cấu hình etcd trên server-3
sudo vi /etc/etcd/etcd.conf.yaml
Nội dung:
name: server-3
initial-cluster-token: pgcluster_truongitt
initial-cluster-state: existing
initial-cluster: server-1=http://192.168.65.11:2380,server-2=http://192.168.65.12:2380,server-3=http://192.168.65.13:2380
data-dir: /var/lib/etcd
initial-advertise-peer-urls: http://192.168.65.13:2380
listen-peer-urls: http://192.168.65.13:2380
advertise-client-urls: http://192.168.65.13:2379
listen-client-urls: http://192.168.65.13:2379,http://127.0.0.1:2379
3.4. Kích hoạt và kiểm tra etcd
Trên server-1:
sudo systemctl start etcd
sudo systemctl enable etcd
etcdctl --endpoints=http://192.168.65.11:2379 member list
Thêm server-2:
etcdctl --endpoints=http://192.168.65.11:2379 member add server-2 --peer-urls=http://192.168.65.12:2380
sudo systemctl start etcd
sudo systemctl enable etcd
Thêm server-3:
etcdctl --endpoints=http://192.168.65.11:2379 member add server-3 --peer-urls=http://192.168.65.13:2380
sudo systemctl start etcd
sudo systemctl enable etcd
Kiểm tra cụm etcd:
etcdctl --endpoints=http://192.168.65.11:2379 member list
Kết quả mong đợi:
52f270512d6f415, started, server-2, http://192.168.65.12:2380, http://192.168.65.12:2379, false
8940bcc160088537, started, server-3, http://192.168.65.13:2380, http://192.168.65.13:2379, false
fd8150fd7a16b9ac, started, server-1, http://192.168.65.11:2380, http://192.168.65.11:2379, false
Bước 4: Cấu hình Patroni
Cấu hình Patroni trên cả ba máy chủ để quản lý cụm PostgreSQL HA.
4.1. Cấu hình Patroni trên server-1
Chỉnh sửa file /etc/patroni/patroni.yml
:
sudo vi /etc/patroni/patroni.yml
Nội dung:
namespace: percona_lab_truongitt
scope: clusterdevops_truongitt
name: core-1
restapi:
listen: 0.0.0.0:8008
connect_address: 192.168.65.11:8008
etcd3:
host: 192.168.65.11: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:
wal_level: replica
hot_standby: on
wal_keep_segments: 10
max_wal_senders: 5
max_replication_slots: 10
wal_log_hints: on
logging_collector: 'on'
max_wal_size: '10GB'
archive_mode: on
archive_timeout: 600s
archive_command: cp -f %p /home/postgres/archived/%f
timezone: 'Asia/Ho_Chi_Minh'
work_mem: 4MB
pg_hba:
- local all all peer
- host replication replicator 127.0.0.1/32 trust
- host replication replicator 192.0.0.0/8 scram-sha-256
- host all all 0.0.0.0/0 scram-sha-256
recovery_conf:
restore_command: cp /home/postgres/archived/%f %p
initdb:
- encoding: UTF8
- data-checksums
postgresql:
cluster_name: cluster_1
listen: 0.0.0.0:5432
connect_address: 192.168.65.11:5432
data_dir: /var/lib/postgresql/17/main
bin_dir: /usr/lib/postgresql/17/bin
pgpass: /opt/secretpg/pgpass
authentication:
replication:
username: replicator
password: replPasswd
superuser:
username: postgres
password: truongitt123
parameters:
unix_socket_directories: /var/run/postgresql/
create_replica_methods:
- basebackup
basebackup:
checkpoint: 'fast'
pg_hba:
- local all all peer
- host replication replicator 127.0.0.1/32 trust
- host replication replicator 192.0.0.0/8 scram-sha-256
- host all all 0.0.0.0/0 scram-sha-256
watchdog:
mode: off
tags:
nofailover: false
noloadbalance: false
clonefrom: false
nosync: false
4.2. Cấu hình Patroni trên server-2 và server-3
Trên server-2:
namespace: percona_lab_truongitt
scope: clusterdevops_truongitt
name: core-2
restapi:
listen: 0.0.0.0:8008
connect_address: 192.168.65.12:8008
etcd3:
host: 192.168.65.11: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:
wal_level: replica
hot_standby: on
wal_keep_segments: 10
max_wal_senders: 5
max_replication_slots: 10
wal_log_hints: on
logging_collector: 'on'
max_wal_size: '10GB'
archive_mode: on
archive_timeout: 600s
archive_command: cp -f %p /home/postgres/archived/%f
timezone: 'Asia/Ho_Chi_Minh'
work_mem: 4MB
pg_hba:
- local all all peer
- host replication replicator 127.0.0.1/32 trust
- host replication replicator 192.0.0.0/8 scram-sha-256
- host all all 0.0.0.0/0 scram-sha-256
recovery_conf:
restore_command: cp /home/postgres/archived/%f %p
initdb:
- encoding: UTF8
- data-checksums
postgresql:
cluster_name: cluster_1
listen: 0.0.0.0:5432
connect_address: 192.168.65.12:5432
data_dir: /var/lib/postgresql/17/main
bin_dir: /usr/lib/postgresql/17/bin
pgpass: /opt/secretpg/pgpass
authentication:
replication:
username: replicator
password: replPasswd
superuser:
username: postgres
password: truongitt123
parameters:
unix_socket_directories: /var/run/postgresql/
create_replica_methods:
- basebackup
basebackup:
checkpoint: 'fast'
pg_hba:
- local all all peer
- host replication replicator 127.0.0.1/32 trust
- host replication replicator 192.0.0.0/8 scram-sha-256
- host all all 0.0.0.0/0 scram-sha-256
watchdog:
mode: off
tags:
nofailover: false
noloadbalance: false
clonefrom: false
nosync: false
Trên server-3:
namespace: percona_lab_truongitt
scope: clusterdevops_truongitt
name: server-3
restapi:
listen: 0.0.0.0:8008
connect_address: 192.168.65.13:8008
etcd3:
host: 192.168.65.11: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:
wal_level: replica
hot_standby: on
wal_keep_segments: 10
max_wal_senders: 5
max_replication_slots: 10
wal_log_hints: on
logging_collector: 'on'
max_wal_size: '10GB'
archive_mode: on
archive_timeout: 600s
archive_command: cp -f %p /home/postgres/archived/%f
timezone: 'Asia/Ho_Chi_Minh'
work_mem: 4MB
pg_hba:
- local all all peer
- host replication replicator 127.0.0.1/32 trust
- host replication replicator 192.0.0.0/8 scram-sha-256
- host all all 0.0.0.0/0 scram-sha-256
recovery_conf:
restore_command: cp /home/postgres/archived/%f %p
initdb:
- encoding: UTF8
- data-checksums
postgresql:
cluster_name: cluster_1
listen: 0.0.0.0:5432
connect_address: 192.168.65.13:5432
data_dir: /var/lib/postgresql/17/main
bin_dir: /usr/lib/postgresql/17/bin
pgpass: /opt/secretpg/pgpass
authentication:
replication:
username: replicator
password: replPasswd
superuser:
username: postgres
password: truongitt123
parameters:
unix_socket_directories: /var/run/postgresql/
create_replica_methods:
- basebackup
basebackup:
checkpoint: 'fast'
pg_hba:
- local all all peer
- host replication replicator 127.0.0.1/32 trust
- host replication replicator 192.0.0.0/8 scram-sha-256
- host all all 0.0.0.0/0 scram-sha-256
watchdog:
mode: off
tags:
nofailover: false
noloadbalance: false
clonefrom: false
nosync: false
4.3. Kích hoạt Patroni
Trên mỗi máy chủ, bắt đầu từ server-1, sau đó server-2 và server-3:
sudo systemctl daemon-reload
sudo systemctl start patroni
sudo systemctl status patroni
4.4. Kiểm tra cụm Patroni
Kiểm tra file pg_hba.conf:
sudo cat /var/lib/postgresql/17/main/pg_hba.conf
Kiểm tra lỗi trong file YAML:
sudo nano -ET4 /etc/patroni/patroni.yml
Kiểm tra trạng thái cụm:
patronictl -c /etc/patroni/patroni.yml list $SCOPE
Kết quả mong đợi:
+ Cluster: clusterdevops_truongitt (7517526875326604092) ---------+
| Member | Host | Role | State | TL | Lag in MB |
+----------+---------------+---------+-----------+----+-----------+
| server-1 | 192.168.65.11 | Leader | running | 3 | |
| server-2 | 192.168.65.12 | Replica | streaming | 3 | 0 |
| server-3 | 192.168.65.13 | Replica | streaming | 3 | 0 |
+----------+---------------+---------+-----------+----+-----------+
Bước 5: Cấu hình HAProxy
Cài đặt và cấu hình HAProxy để cân bằng tải cho primary (port 5000) và replica (port 5001).
5.1. Cài đặt HAProxy
sudo apt install -y haproxy
sudo mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.org
sudo vi /etc/haproxy/haproxy.cfg
Nội dung file /etc/haproxy/haproxy.cfg
:
global
maxconn 100
defaults
log global
mode tcp
retries 2
timeout client 30m
timeout connect 4s
timeout server 30m
timeout check 5s
listen stats
mode http
bind *:7000
stats enable
stats uri /
listen primary
bind *:5000
option httpchk /primary
http-check expect status 200
default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions
server core-1 192.168.65.11:5432 maxconn 100 check port 8008
server core-2 192.168.65.12:5432 maxconn 100 check port 8008
server core-3 192.168.65.13:5432 maxconn 100 check port 8008
listen standbys
balance roundrobin
bind *:5001
option httpchk /replica
http-check expect status 200
default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions
server core-1 192.168.65.11:5432 maxconn 100 check port 8008
server core-2 192.168.65.12:5432 maxconn 100 check port 8008
server core-3 192.168.65.13:5432 maxconn 100 check port 8008
5.2. Khởi động lại HAProxy
sudo systemctl restart haproxy
Bước 6: Kiểm tra kết quả
Kiểm tra kết nối và hoạt động của cụm PostgreSQL qua HAProxy.
6.1. Kiểm tra trên server-1 (primary)
curl -s localhost:8008/primary | jq
sudo -u postgres psql
select * from pg_replication_slots;
or
sudo -u postgres psql -c "select * from pg_replication_slots;"
Kết nối và tạo database:
psql -U postgres -h 192.168.65.11 -p 5000
Nhập mật khẩu:
truongitt123
Tạo database:
create database truongthongthai;
\l
Kết quả: Database được tạo thành công trên primary.
6.2. Kiểm tra trên server-2 và server-3 (replica)
sudo -u postgres psql
SELECT * FROM pg_stat_wal_receiver;
Thử tạo database trên replica:
create database truongthongthai;
Kết quả mong đợi:
ERROR: cannot execute CREATE DATABASE in a read-only transaction
Điều này xác nhận replica chỉ cho phép đọc, không cho phép ghi.
Hoàn thành
Chúc mừng bạn đã hoàn thành thiết lập cụm PostgreSQL HA với Patroni, etcd và HAProxy. Cụm này đảm bảo tính sẵn sàng cao với một primary server (server-1) và hai replica server (server-2, server-3) hiệu quả trong việc điều phối giảm tải và sự cố hạ tầng.
All rights reserved