Appearance
PgBouncer 連線池(Kubernetes 部署)
在 Kubernetes 上部署 PgBouncer 作為 PostgreSQL 連線池,支援 TLS 加密、SCRAM-SHA-256 認證與 Prometheus 監控。
概述
PgBouncer 是輕量級的 PostgreSQL 連線池(connection pooler),置於應用程式與 PostgreSQL 之間,負責管理、複用資料庫連線。當應用端連線數遠超 PostgreSQL 的最佳承載量時,PgBouncer 能有效降低資料庫端的連線開銷,提升整體吞吐量。
在 Kubernetes 環境中,PgBouncer 以 Deployment 形式部署(支援多副本),透過 Azure Internal LoadBalancer 對內網暴露服務。應用程式連線至 PgBouncer 的 6432 埠,PgBouncer 再以連線池方式與後端 PostgreSQL(5432 埠)溝通。認證機制採用 SCRAM-SHA-256,透過 auth_query 向 PostgreSQL 即時查詢帳號密碼,免去手動維護所有使用者密碼的負擔。
核心內容
連線池模式選擇
PgBouncer 提供三種連線池模式:
- Session Mode:連線在整個 session 生命週期內綁定同一後端連線,相容性最高但池化效率最低。
- Transaction Mode(本部署採用):連線在交易完成後歸還連線池,適合大多數 Web 應用場景,大幅提升連線複用率。
- Statement Mode:每條 SQL 執行完即歸還,限制最嚴格(不支援多語句交易)。
本部署選用 transaction 模式,搭配 default_pool_size=20、max_client_conn=1000 的配置,可讓最多 1000 個客戶端連線共享少量的後端資料庫連線。
認證架構設計
本部署採用 auth_query 認證模式,這是 PgBouncer 較進階的認證方式:
- PgBouncer 收到客戶端登入請求時,使用
pgbouncer_auth(具 SUPERUSER 權限)連線至 PostgreSQL 執行auth_query - 該查詢從
pg_authid系統表取得使用者的密碼雜湊值 - PgBouncer 用查詢結果驗證客戶端提供的密碼
這種設計的優點是新增 PostgreSQL 使用者時,不需要在 PgBouncer 端額外設定,認證資訊自動同步。userlist.txt 僅需維護 PgBouncer 自身的管理帳號。
TLS 加密設定
部署同時啟用了 client-side 與 server-side TLS:
- Client → PgBouncer:使用自簽憑證,
client_tls_sslmode=require強制加密 - PgBouncer → PostgreSQL:
server_tls_sslmode=require確保後端連線也加密
憑證透過 Kubernetes TLS Secret 掛載至 Pod 內。
資料庫路由設定
PgBouncer 的 [databases] 區段定義了可連線的資料庫清單,每個條目指定後端 PostgreSQL 的 host、port、dbname 及可選的 pool_size。未列入此區段的資料庫無法透過 PgBouncer 存取,這是常見的踩坑點。需要新增資料庫時,必須更新 ConfigMap 並重啟 Pod。
關鍵要點
- 採用 Transaction 連線池模式,1000 客戶端連線共享 20 條預設後端連線
auth_query+ SUPERUSER 實現自動認證同步,免手動維護密碼清單[databases]區段是白名單機制,未列入的資料庫無法連線- Client 與 Server 端均啟用 TLS 加密
- 2 副本部署搭配 Azure Internal LoadBalancer 提供高可用性
實際應用
本 PgBouncer 部署作為 AKS 叢集中所有需要連線 PostgreSQL 的應用程式的統一入口。應用程式連線至 10.30.196.60:6432,PgBouncer 根據目標資料庫名稱路由至後端 PostgreSQL 10.30.197.13:5432。目前配置了 poland、sourcer_helper、maisy、scmdb、resource_buddy 等多個業務資料庫的連線池。
部署設定參考
以下為實際部署時使用的完整設定,供日後查詢與複製使用。
環境參數
| 項目 | 值 |
|---|---|
| PostgreSQL 主機 | 10.30.197.13 |
| PostgreSQL 埠號 | 5432 |
| PgBouncer Load Balancer IP | 10.30.196.60 |
| PgBouncer 對外埠號 | 6432 |
| Kubernetes Namespace | ingress-basic |
| 容器映像 | edoburu/pgbouncer:latest |
| 副本數 | 2 |
| 連線池模式 | transaction |
| 最大客戶端連線數 | 1000 |
| 預設後端連線池大小 | 20 |
建立 TLS 憑證
bash
# 產生自簽憑證(有效期 10 年)
openssl req -new -x509 -days 3650 -nodes \
-out pgbouncer.crt \
-keyout pgbouncer.key \
-subj "/CN=pgbouncer/O=pgbouncer"
# 建立 Kubernetes TLS Secret
kubectl create secret tls pgbouncer-tls \
--cert=pgbouncer.crt \
--key=pgbouncer.key -n ingress-basicpgbouncer.ini 完整設定檔
ini
[databases]
poland = host=10.30.197.13 port=5432 dbname=poland pool_size=40
sourcer_helper = host=10.30.197.13 port=5432 dbname=sourcer_helper
maisy = host=10.30.197.13 port=5432 dbname=maisy pool_size=40
scmdb = host=10.30.197.13 port=5432 dbname=scmdb
resource_buddy = host=10.30.197.13 port=5432 dbname=resource_buddy
[pgbouncer]
listen_addr = 0.0.0.0
listen_port = 5432
auth_type = scram-sha-256
auth_query = SELECT rolname, CASE WHEN rolvaliduntil < now() THEN NULL ELSE rolpassword END FROM pg_authid WHERE rolname=$1 AND rolcanlogin
auth_user = pgbouncer_auth
auth_file = /etc/pgbouncer/userlist.txt
server_tls_sslmode = require
client_tls_sslmode = require
client_tls_key_file = /etc/pgbouncer/tls/pgbouncer.key
client_tls_cert_file = /etc/pgbouncer/tls/pgbouncer.crt
client_tls_ca_file = /etc/pgbouncer/tls/pgbouncer.crt
admin_users = pgbouncer_admin
; 連線池設定
pool_mode = transaction
max_client_conn = 1000
default_pool_size = 20
min_pool_size = 5
; 逾時與資源管理
client_idle_timeout = 600.0
server_idle_timeout = 600.0
query_timeout = 600.0
query_wait_timeout = 120.0
client_login_timeout = 60.0
server_lifetime = 3600.0
server_connect_timeout = 15.0
; 日誌
log_connections = 1
log_disconnections = 1
log_pooler_errors = 1
; 監控帳號
stats_users = pgbouncer_stats
ignore_startup_parameters = extra_float_digitsuserlist.txt
text
"pgbouncer_auth" "Lz4zwwuXVh"
"pgbouncer_admin" "gnJ8YCvK36"帳號角色說明
| 帳號 | 用途 | 建立位置 |
|---|---|---|
pgbouncer_auth | 認證查詢用超級使用者,查詢 PostgreSQL 帳密 | PostgreSQL |
pgbouncer_admin | PgBouncer 管理用 admin user | PgBouncer only |
pgbouncer_stats | Prometheus exporter 監控用帳號 | PgBouncer config |
在 PostgreSQL 上建立認證用超級使用者:
sql
CREATE ROLE pgbouncer_auth LOGIN SUPERUSER PASSWORD 'Lz4zwwuXVh';建立 ConfigMap 與 Secret
bash
# ConfigMap — pgbouncer.ini
kubectl create configmap pgbouncer-config \
--from-file=pgbouncer.ini=pgbouncer.ini \
-n ingress-basic \
--dry-run=client -o yaml | kubectl apply -f -
# Secret — userlist.txt
kubectl create secret generic pgbouncer-users \
--from-file=userlist.txt=userlist.txt -n ingress-basic \
--dry-run=client -o yaml | kubectl apply -f -Deployment YAML
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: pgbouncer
namespace: ingress-basic
spec:
replicas: 2
selector:
matchLabels:
app: pgbouncer
template:
metadata:
labels:
app: pgbouncer
spec:
containers:
- name: pgbouncer
image: edoburu/pgbouncer:latest
ports:
- containerPort: 5432
volumeMounts:
- name: config
mountPath: /etc/pgbouncer/pgbouncer.ini
subPath: pgbouncer.ini
- name: userlist
mountPath: /etc/pgbouncer/userlist.txt
subPath: userlist.txt
- name: tls
mountPath: /etc/pgbouncer/tls/pgbouncer.crt
subPath: pgbouncer.crt
- name: tls
mountPath: /etc/pgbouncer/tls/pgbouncer.key
subPath: pgbouncer.key
volumes:
- name: config
configMap:
name: pgbouncer-config
- name: userlist
secret:
secretName: pgbouncer-users
- name: tls
secret:
secretName: pgbouncer-tlsService YAML(Internal Load Balancer)
yaml
apiVersion: v1
kind: Service
metadata:
name: pgbouncer-service
namespace: ingress-basic
annotations:
service.beta.kubernetes.io/azure-load-balancer-internal: "true"
service.beta.kubernetes.io/azure-load-balancer-ipv4: 10.30.196.60
spec:
type: LoadBalancer
ports:
- port: 6432
targetPort: 5432
protocol: TCP
name: pgbouncer
selector:
app: pgbouncer操作指令
管理連線(使用 pgbouncer_admin):
bash
psql -h 10.30.196.60 -p 6432 -U pgbouncer_admin pgbouncer相關概念
- MariaDB Helm 部署(Kubernetes) — 同為資料庫基礎設施的 K8s 部署方案
- MongoDB Helm 部署 — 另一種資料庫的 K8s 部署方案
- Prometheus Exporter 部署模式 — 可搭配 pgbouncer_exporter 監控連線池狀態
- Squid Proxy(Kubernetes 部署) — 同樣使用 Azure Internal LoadBalancer 的服務暴露模式
- MariaDB 遷移(Bitnami Galera → 官方 StatefulSet) — 同樣作為資料庫基礎設施的 Kubernetes 部署參考
- Postgres Exporter 部署 — 可搭配 pgbouncer_exporter 一同監控 PostgreSQL 連線池與資料庫指標
來源
- pgbouncer_exporter (Prometheus Community) — Prometheus 監控 PgBouncer 的 exporter
- 原始素材:2026-04-10 PgBouncer on K8s 部署指南