Chuyển đến nội dung chính

Bài 5: Cài đặt PostgreSQL

Cài đặt PostgreSQL từ package repository hoặc source, cấu hình postgresql.conf và pg_hba.conf trên cả 3 nodes trong cluster.

🔒 DevSecOps — Bài 5 Bài 5: Cài đặt PostgreSQL

PostgreSQL High Availability với Patroni & etcd

Phần 2: Cài đặt & Cấu hình

xdev.asia

Mục tiêu

Sau bài học này, bạn sẽ:

  • Cài đặt PostgreSQL từ package repository
  • Hiểu cách cài đặt PostgreSQL từ source (optional)
  • Cấu hình postgresql.conf cơ bản cho HA
  • Hiểu về pg_hba.conf và authentication
  • Chuẩn bị PostgreSQL trên 3 nodes cho Patroni cluster

1. Cài đặt PostgreSQL từ Package Repository

1.1. Chuẩn bị

Trước khi cài đặt PostgreSQL, cần setup package repository chính thức của PostgreSQL (PGDG - PostgreSQL Global Development Group).

Ưu điểm của PGDG repository:

  • ✅ Phiên bản PostgreSQL mới nhất
  • ✅ Cập nhật bảo mật nhanh chóng
  • ✅ Nhiều extensions có sẵn
  • ✅ Support nhiều distros

1.2. Cài đặt trên Ubuntu/Debian

Bước 1: Thêm PGDG repository

# Import repository signing key
sudo apt install -y wget gnupg2

sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'

wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -

Update package list

sudo apt update

Bước 2: Cài đặt PostgreSQL

# Cài PostgreSQL 18 (khuyến nghị cho production)
sudo apt install -y postgresql-18 postgresql-contrib-15 postgresql-server-dev-15

Kiểm tra version

psql --version

Output: psql (PostgreSQL) 15.5

Bước 3: Kiểm tra service

# Kiểm tra status
sudo systemctl status postgresql

Output:

● postgresql.service - PostgreSQL RDBMS

Loaded: loaded (/lib/systemd/system/postgresql.service; enabled)

Active: active (exited) since ...

Bước 4: Dừng và disable PostgreSQL default cluster

# Patroni sẽ quản lý PostgreSQL, nên ta disable service mặc định
sudo systemctl stop postgresql
sudo systemctl disable postgresql

Xóa cluster mặc định (Patroni sẽ tạo cluster mới)

sudo pg_dropcluster 15 main --stop

Kiểm tra

pg_lsclusters

Output: (empty - no clusters)

1.3. Cài đặt trên CentOS/RHEL/Rocky Linux

Bước 1: Thêm PGDG repository

# Cài đặt EPEL (Extra Packages for Enterprise Linux)
sudo dnf install -y epel-release

Thêm PostgreSQL 18 repository

sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm

Disable built-in PostgreSQL module

sudo dnf -qy module disable postgresql

Bước 2: Cài đặt PostgreSQL

# Cài PostgreSQL 18
sudo dnf install -y postgresql15-server postgresql15-contrib postgresql15-devel

Kiểm tra

/usr/pgsql-15/bin/postgres --version

Output: postgres (PostgreSQL) 15.5

# Tạo symlink cho các binary vào PATH
sudo alternatives --install /usr/bin/psql psql /usr/pgsql-15/bin/psql 1
sudo alternatives --install /usr/bin/pg_config pg_config /usr/pgsql-15/bin/pg_config 1
sudo alternatives --install /usr/bin/pg_basebackup pg_basebackup /usr/pgsql-15/bin/pg_basebackup 1

Bước 4: Không khởi tạo database (Patroni sẽ làm)

# KHÔNG chạy:

sudo /usr/pgsql-15/bin/postgresql-18-setup initdb

KHÔNG enable service:

sudo systemctl enable postgresql-18

2. Cài đặt PostgreSQL từ Source (Optional - Advanced)

Cài từ source cho phép custom compile options, nhưng phức tạp hơn và khó maintain.

2.1. Khi nào cần cài từ source?

  • 🔧 Cần custom features không có trong binary package
  • 🔧 Testing với development version
  • 🔧 Tối ưu cho hardware cụ thể
  • 🔧 Apply custom patches

2.2. Quy trình cài từ source

Bước 1: Cài dependencies

# Ubuntu/Debian
sudo apt install -y build-essential libreadline-dev zlib1g-dev 
flex bison libxml2-dev libxslt-dev libssl-dev libxml2-utils
xsltproc libkrb5-dev libldap2-dev libpam0g-dev libperl-dev
python3-dev tcl-dev libsystemd-dev

CentOS/RHEL

sudo dnf install -y gcc make readline-devel zlib-devel openssl-devel
libxml2-devel libxslt-devel systemd-devel perl-ExtUtils-Embed
python3-devel

Bước 2: Download source

cd /usr/local/src
sudo wget https://ftp.postgresql.org/pub/source/v15.5/postgresql-18.5.tar.gz
sudo tar -xzf postgresql-18.5.tar.gz
cd postgresql-18.5

Bước 3: Configure và compile

# Configure với options
sudo ./configure 
--prefix=/usr/local/pgsql-15
--with-openssl
--with-libxml
--with-systemd
--with-readline
--enable-nls

Compile (sử dụng nhiều cores)

sudo make -j$(nproc)

Chạy tests (optional)

sudo make check

Install

sudo make install

Install contrib modules

cd contrib sudo make install

Bước 4: Setup environment

# Thêm vào ~/.bashrc
export PATH=/usr/local/pgsql-15/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/pgsql-15/lib:$LD_LIBRARY_PATH

source ~/.bashrc

Lưu ý: Cài từ source không tự động có systemd service, cần tạo manually.

3. Cấu hình postgresql.conf cơ bản

Patroni sẽ quản lý hầu hết cấu hình PostgreSQL thông qua DCS. Tuy nhiên, cần hiểu các parameters quan trọng.

3.1. Cấu trúc file postgresql.conf

# /etc/postgresql/18/main/postgresql.conf

hoặc: /var/lib/pgsql/15/data/postgresql.conf

#------------------------------------------------------------------------------

FILE LOCATIONS

#------------------------------------------------------------------------------ data_directory = '/var/lib/postgresql/18/main' hba_file = '/etc/postgresql/18/main/pg_hba.conf' ident_file = '/etc/postgresql/18/main/pg_ident.conf'

#------------------------------------------------------------------------------

CONNECTIONS AND AUTHENTICATION

#------------------------------------------------------------------------------ listen_addresses = '*' # Lắng nghe trên tất cả interfaces port = 5432 max_connections = 100 # Số connections tối đa

3.2. Parameters quan trọng cho HA

Replication Settings

#------------------------------------------------------------------------------

WRITE-AHEAD LOG (WAL)

#------------------------------------------------------------------------------ wal_level = replica # Mức độ thông tin trong WAL # minimal, replica, hoặc logical

fsync = on # Đảm bảo WAL được flush to disk synchronous_commit = on # Wait cho WAL write confirmation

wal_log_hints = on # Cần cho pg_rewind

#------------------------------------------------------------------------------

REPLICATION

#------------------------------------------------------------------------------ max_wal_senders = 10 # Số standby servers tối đa max_replication_slots = 10 # Số replication slots

WAL keep settings

wal_keep_size = 1GB # Giữ ít nhất 1GB WAL files # (PG 13+, thay thế wal_keep_segments)

Archive settings (để PITR)

archive_mode = on archive_command = 'cp %p /var/lib/postgresql/18/archive/%f' archive_timeout = 300 # Archive mỗi 5 phút

Memory Settings

#------------------------------------------------------------------------------

RESOURCE USAGE (MEMORY)

#------------------------------------------------------------------------------ shared_buffers = 2GB # RAM dành cho PostgreSQL cache # Khuyến nghị: 25% của RAM

effective_cache_size = 6GB # Ước tính tổng cache (OS + PG) # Khuyến nghị: 50-75% của RAM

work_mem = 16MB # RAM cho mỗi query operation # Tổng có thể dùng: work_mem × max_connections

maintenance_work_mem = 512MB # RAM cho maintenance operations # (VACUUM, CREATE INDEX, etc.)

Checkpoint Settings

#------------------------------------------------------------------------------

WRITE-AHEAD LOG (Checkpoints)

#------------------------------------------------------------------------------ checkpoint_timeout = 10min # Tần suất checkpoint tối đa max_wal_size = 2GB # WAL size trigger checkpoint min_wal_size = 1GB # Giữ ít nhất 1GB WAL

checkpoint_completion_target = 0.9 # Spread checkpoint I/O # (90% của checkpoint_timeout)

Logging Settings

#------------------------------------------------------------------------------

REPORTING AND LOGGING

#------------------------------------------------------------------------------ log_destination = 'stderr' logging_collector = on

log_directory = 'log' log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' log_rotation_age = 1d log_rotation_size = 100MB

log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h ' log_timezone = 'UTC'

Log slow queries

log_min_duration_statement = 1000 # Log queries > 1 second

Log connections/disconnections

log_connections = on log_disconnections = on

Log checkpoints (useful for tuning)

log_checkpoints = on

3.3. Patroni sẽ override các settings

Patroni quản lý các parameters sau thông qua DCS, KHÔNG nên set trong postgresql.conf:

# ❌ KHÔNG set trong postgresql.conf khi dùng Patroni

hot_standby = on

primary_conninfo = '...'

restore_command = '...'

recovery_target_timeline = 'latest'

Patroni sẽ tự động set chúng trong postgresql.auto.conf.

4. Hiểu về pg_hba.conf

pg_hba.conf (Host-Based Authentication) kiểm soát client authentication.

4.1. Cấu trúc của pg_hba.conf

# TYPE  DATABASE        USER            ADDRESS                 METHOD

"local" is for Unix domain socket connections only

local all all peer

IPv4 local connections:

host all all 127.0.0.1/32 scram-sha-256

IPv4 connections from anywhere (for replication)

host all all 0.0.0.0/0 scram-sha-256

Replication connections

host replication replicator 10.0.1.0/24 scram-sha-256

4.2. Các columns

  1. TYPE:
    • local: Unix socket connections
    • host: TCP/IP (clear text or SSL)
    • hostssl: TCP/IP with SSL only
    • hostnossl: TCP/IP without SSL
  2. DATABASE:
    • Database name
    • all: tất cả databases
    • replication: replication connections
  3. USER:
    • Username
    • all: tất cả users
  4. ADDRESS:
    • IP/netmask: 10.0.1.0/24
    • Hostname
    • 0.0.0.0/0: anywhere (không khuyến khích)
  5. METHOD:
    • trust: Không cần password (chỉ dùng local dev)
    • md5: MD5 hashed password (deprecated)
    • scram-sha-256: Modern, secure (khuyến nghị)
    • peer: Unix username = PostgreSQL username
    • cert: SSL certificate authentication

4.3. pg_hba.conf cho Patroni Cluster

# /etc/postgresql/18/main/pg_hba.conf

Local connections

local all postgres peer local all all md5

Localhost

host all all 127.0.0.1/32 scram-sha-256 host all all ::1/128 scram-sha-256

Application connections

host all app_user 10.0.1.0/24 scram-sha-256

Patroni REST API health checks (optional database connection)

host postgres patroni_user 10.0.1.0/24 scram-sha-256

Replication connections (Patroni nodes)

host replication replicator 10.0.1.11/32 scram-sha-256 host replication replicator 10.0.1.12/32 scram-sha-256 host replication replicator 10.0.1.13/32 scram-sha-256

Monitoring connections (Prometheus exporter)

host postgres exporter 10.0.1.0/24 scram-sha-256

4.4. Best practices cho pg_hba.conf

✅ Specific is better: Không dùng 0.0.0.0/0 nếu không cần

✅ Use scram-sha-256: Modern authentication method

✅ Separate users: User khác nhau cho app, replication, monitoring

✅ Document: Comment cho mỗi rule

✅ Restrict replication: Chỉ cho phép replication user từ IP của Patroni nodes

❌ Avoid trust method: Kể cả trong dev environment

5. Tạo users và databases cần thiết

5.1. Tạo replication user

# Sau khi Patroni bootstrap cluster, connect đến primary:
sudo -u postgres psql -h localhost -p 5432

Trong psql:

CREATE ROLE replicator WITH REPLICATION LOGIN ENCRYPTED PASSWORD 'your_strong_password';

Kiểm tra

\du replicator

5.2. Tạo Patroni monitoring user

-- User cho Patroni health checks
CREATE USER patroni_user WITH ENCRYPTED PASSWORD 'patroni_password';
GRANT CONNECT ON DATABASE postgres TO patroni_user;

5.3. Tạo application database và user

-- Tạo database
CREATE DATABASE myapp;

-- Tạo user CREATE USER app_user WITH ENCRYPTED PASSWORD 'app_password';

-- Grant permissions GRANT ALL PRIVILEGES ON DATABASE myapp TO app_user;

-- Connect to myapp database \c myapp

-- Grant schema permissions GRANT ALL ON SCHEMA public TO app_user;

6. Lab: Cài đặt PostgreSQL trên 3 nodes

6.1. Môi trường Lab

node1 (pg-node1): 10.0.1.11  - Primary (sau khi bootstrap)
node2 (pg-node2): 10.0.1.12  - Replica
node3 (pg-node3): 10.0.1.13  - Replica

6.2. Thực hiện trên TẤT CẢ 3 nodes

Bước 1: Update system

sudo apt update && sudo apt upgrade -y

Bước 2: Cài PostgreSQL 18

# Thêm repo
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'

wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -

sudo apt update

Cài đặt

sudo apt install -y postgresql-18 postgresql-contrib-15 postgresql-server-dev-15

Bước 3: Stop và disable default cluster

sudo systemctl stop postgresql
sudo systemctl disable postgresql

sudo pg_dropcluster 15 main --stop

Verify

pg_lsclusters

Output: (should be empty)

Bước 4: Tạo thư mục cho PostgreSQL data

# Patroni sẽ quản lý data directory, nhưng ta tạo structure
sudo mkdir -p /var/lib/postgresql/18/data
sudo mkdir -p /var/lib/postgresql/18/archive

sudo chown -R postgres:postgres /var/lib/postgresql sudo chmod 700 /var/lib/postgresql/18/data

Bước 5: Kiểm tra PostgreSQL binary

# Kiểm tra version
postgres --version

Output: postgres (PostgreSQL) 15.5

Kiểm tra các tools

which psql pg_basebackup pg_rewind

6.3. Verify trên mỗi node

# Node name
hostname

PostgreSQL version

postgres --version

Directories

ls -ld /var/lib/postgresql/18/data ls -ld /var/lib/postgresql/18/archive

PostgreSQL service

systemctl status postgresql

Output: inactive (dead) ✓

6.4. Troubleshooting

Issue 1: Permission denied trên data directory

# Fix ownership
sudo chown -R postgres:postgres /var/lib/postgresql
sudo chmod 700 /var/lib/postgresql/18/data

Issue 2: PostgreSQL service vẫn running

# Stop forcefully
sudo systemctl stop postgresql@15-main
sudo systemctl disable postgresql@15-main

Kill processes nếu cần

sudo pkill -9 postgres

Issue 3: Port 5432 đã bị sử dụng

# Kiểm tra process sử dụng port
sudo lsof -i :5432

Hoặc

sudo netstat -tlnp | grep 5432

7. Tổng kết

Key Takeaways

✅ Package repository: Cài PostgreSQL từ PGDG repo để có version mới nhất

✅ Disable default service: Patroni sẽ quản lý PostgreSQL, không dùng systemd service mặc định

✅ postgresql.conf: Hiểu các parameters quan trọng cho HA và replication

✅ pg_hba.conf: Cấu hình authentication cho connections và replication

✅ Không khởi tạo cluster: Patroni sẽ bootstrap cluster tự động

Checklist sau Lab

  •  PostgreSQL 18 đã cài trên cả 3 nodes
  •  Default cluster đã xóa
  •  PostgreSQL service đã disable
  •  Data directories đã tạo với permissions đúng
  •  Binary paths đã có trong $PATH

Chuẩn bị cho Bài 6

Bài tiếp theo sẽ cài đặt và cấu hình etcd cluster - DCS layer cho Patroni.