PostgreSQL Bài 50: Triển khai cụm PostgreSQL High Availability trên Kubernetes bằng Zalando Postgres Operator
Ở Bài 49, chúng ta đã xây dựng thành công kiến trúc High Availability (HA) hoàn chỉnh trên môi trường máy chủ ảo (VM/Bare-metal). Chúng ta phải tự tay cấu hình Patroni, etcd, cài đặt HAProxy, và khởi chạy PgBouncer.
Nhưng khi chuyển dịch lên môi trường Kubernetes (K8s), việc quản lý thủ công các Stateful workloads như Database là một cơn ác mộng (phải xử lý Persistent Volumes, StatefulSets, cấu hình mạng Pod-to-Pod). Để giải quyết triệt để vấn đề này, mô hình Operator Pattern ra đời. Bài học này sẽ hướng dẫn bạn sử dụng công cụ mạnh mẽ nhất trong hệ sinh thái K8s cho PostgreSQL: Zalando Postgres Operator.

1. Operator Pattern là gì và Sức mạnh của Zalando?
Trong Kubernetes, Operator đóng vai trò như một "Quản trị viên Database (DBA) bằng code" chạy ngầm 24/7. Thay vì bạn phải tự cấu hình từng Pod, bạn chỉ cần khai báo: "Tôi muốn một cụm PostgreSQL version 15, có 3 node, dung lượng 50GB mỗi node, tự động có PgBouncer". Operator sẽ tự động thực hiện mọi thao tác (tạo ổ đĩa, cài đặt DB, cấu hình HA, giám sát) để đạt được trạng thái đó.
Kiến trúc lõi của Zalando Postgres Operator bao gồm:
-
Tiến trình Operator (
postgres-operator): Chạy như một Deployment độc lập trong K8s. Nó lắng nghe các đối tượng Custom Resource (CRD) do bạn tạo ra. -
Container Image Spilo: Thay vì dùng image
postgresnguyên bản từ DockerHub, Zalando dùng image tự chế tên là Spilo. Spilo đóng gói sẵn: PostgreSQL, Patroni (quản lý HA), PgBouncer (Connection pooling) và WAL-G (để backup lên S3). -
K8s API thay cho etcd/ZooKeeper: Patroni bên trong Spilo không cần bạn phải dựng thêm cụm etcd riêng! Nó sử dụng trực tiếp Kubernetes API (thông qua đối tượng Endpoints hoặc ConfigMaps) để lưu trữ trạng thái bầu chọn Master (Leader Election).
2. Giải pháp Định tuyến (Routing) không cần HAProxy
Trên K8s, HAProxy trở nên thừa thãi. Zalando Operator tự động giải quyết bài toán định tuyến Read/Write thông qua Kubernetes Services và Label Selectors.
Khi bạn khởi tạo cụm tên là my-db, Operator sẽ tự động tạo ra 2 K8s Service:
-
my-db(Master Service): Trỏ duy nhất vào Pod đang giữ vai trò Master. -
my-db-repl(Replica Service): Trỏ vào tất cả các Pod đang giữ vai trò Slave (Read-only).
Phép màu diễn ra như thế nào khi Master bị sập?
-
Pod Master hiện tại (
pod-0) bị crash. -
Patroni trong các Pod còn lại lập tức bầu ra Master mới (ví dụ:
pod-1). -
Patroni trên
pod-1thay đổi nhãn (label) của chính nó thànhspilo-role: master. Đồng thời nó gỡ nhãn master khỏipod-0. -
Kubernetes Service
my-dbliên tục theo dõi nhãnspilo-role: master. Khi nhãn thay đổi, Service tự động cập nhật Endpoint, chuyển toàn bộ traffic (luồng Ghi) từpod-0sangpod-1ngay lập tức! Ứng dụng Backend chỉ cần kết nối vào tên miền nội bộmy-db:5432cho luồng Ghi vàmy-db-repl:5432cho luồng Đọc.
3. Thực hành: Cài đặt và Khởi tạo Cụm PostgreSQL HA
Bước 1: Cài đặt Zalando Postgres Operator qua Helm
Bạn cần có một cụm Kubernetes (Minikube, EKS, GKE) và Helm đã cài đặt.
Bash
# Thêm Helm repo của Zalando
helm repo add postgres-operator-charts https://opensource.zalando.com/postgres-operator/charts/postgres-operator
# Cài đặt Operator vào K8s
helm install postgres-operator postgres-operator-charts/postgres-operator
Bước 2: Viết file Khai báo Cụm (Manifest YAML)
Đây là toàn bộ những gì bạn cần viết để tạo ra một cụm Database Production-ready thay vì phải viết hàng ngàn dòng script Bash:
Tạo file cluster.yaml:
YAML
apiVersion: "acid.zalan.do/v1"
kind: postgresql
metadata:
name: acid-production-db
namespace: default
spec:
teamId: "acid"
volume:
size: 50Gi
numberOfInstances: 3 # Tạo 3 node (1 Master, 2 Slaves)
users:
api_user: # Tự động tạo user cho backend
- superuser
- createdb
databases:
my_app_db: api_user # Tự động tạo database và gán quyền owner
postgresql:
version: "15" # Phiên bản PostgreSQL
enableConnectionPooler: true # SIÊU VIỆT: Tự động deploy thêm Pod PgBouncer
allowedSourceRanges:
- 10.0.0.0/8 # Bảo mật mạng
Bước 3: Triển khai và Kiểm tra
Bash
# Apply cấu hình
kubectl apply -f cluster.yaml
# Theo dõi quá trình Operator tạo StatefulSet và các Pod
kubectl get pods -l application=spilo -w
Sau vài phút, chạy lệnh kiểm tra Service:
Bash
kubectl get svc | grep acid-production-db
Bạn sẽ thấy K8s trả về:
-
acid-production-db(Cổng 5432) ──► Đi vào Master (Write). -
acid-production-db-repl(Cổng 5432) ──► Đi vào Slaves (Read). -
acid-production-db-pooler(Cổng 5432) ──► Kết nối PgBouncer Transaction Pooling siêu tốc.
4. Tự động hóa Backup lên S3 (WAL-G)
Ngoài HA, Zalando Operator tích hợp cực kỳ sâu công cụ sao lưu vật lý WAL-G (phiên bản hiện đại của WAL-E).
Bạn chỉ cần cấu hình thông tin AWS S3 Bucket và Access Key vào ConfigMap của Operator. Từ đó, mỗi khi cụm acid-production-db chạy:
-
Định kỳ hàng ngày nó tự động nén toàn bộ thư mục
PGDATAđẩy lên S3 (Base Backup). -
Mỗi khi có file WAL mới (như học ở Bài 33), WAL-G tự động stream file đó lên S3.
Nếu lỡ tay làm rơi database, bạn chỉ cần tạo một file YAML mới mang tên acid-production-db-clone, chỉ định thêm tham số clone: trỏ tới mốc thời gian (Timestamp) trong quá khứ. Operator sẽ tự động tải Base Backup từ S3 về và phát lại WAL (PITR - Point-in-Time Recovery) để hồi sinh database sang một cụm K8s hoàn toàn mới.
All rights reserved