+1

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

model setup HA

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

setup server network vm

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

setup etcd

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 |
+----------+---------------+---------+-----------+----+-----------+

setup patroni

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;"

setup haproxy

query replica check

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.

test core 1

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

test core 2 3

Đ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

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí