PgBouncer · PostgreSQL 连接池
PgBouncer 是位于 postgres 命名空间的连接池(connection pooler),所有平台层与应用层服务不再直连 postgres-primary,而是经它代理后再访问后端数据库。它以 transaction 池模式把大量短连接收敛成少量后端连接,从而把 PostgreSQL 主库的总连接数压在安全水位之内。
它对客户端表现为一个普通的 PostgreSQL 端点(5432),通过通配 [databases] 规则把任意库名/用户名透传给 postgres-primary.postgres.svc.cluster.local。每个业务服务用各自的用户名与库名连接,认证走 md5 + userlist.txt,用户名口令由 ExternalSecret 从 Vault 拉取后渲染。
部署形态
- Name
- 命名空间
- Description
- postgres
- Name
- 工作负载
- Description
- Deployment,2 副本,RollingUpdate(maxUnavailable: 0 / maxSurge: 1)
- Name
- 镜像
- Description
- edoburu/pgbouncer:v1.25.2-p0(主容器);prometheuscommunity/pgbouncer-exporter:v0.12.0(metrics sidecar)
- Name
- 调度
- Description
- nodeSelector workload=app(worker2 / worker4);podAntiAffinity 按 kubernetes.io/hostname 软反亲和,优先把两副本分散到不同节点
- Name
- 端口
- Description
- postgres 5432(主容器);metrics 9127(exporter sidecar)
- Name
- 资源
- Description
- 主容器 requests 50m/32Mi、limits 200m/128Mi;exporter requests 10m/16Mi、limits 50m/32Mi
- Name
- 探针
- Description
- liveness / readiness 均为 5432 端口 tcpSocket 探测
- Name
- 存储
- Description
- 无持久化卷;config 来自 ConfigMap,userlist 来自 Secret,run / log 为 emptyDir
- Name
- 安全上下文
- Description
- allowPrivilegeEscalation: false,capabilities drop ALL
配置与依赖
连接池核心参数来自 ConfigMap pgbouncer-config(pgbouncer.ini):
| 参数 | 值 | 说明 |
|---|---|---|
| pool_mode | transaction | 事务级复用,适配 GORM / pgx 的短连接 |
| max_client_conn | 200 | 客户端侧最大连接 |
| default_pool_size | 5 | 每个 用户/库 对的默认池大小 |
| min_pool_size / reserve_pool_size | 2 / 2 | 最小常驻与预留池 |
| max_db_connections | 4 | 每库后端连接上限,把总连接压在 90 以内 |
| server_idle_timeout / server_lifetime | 600 / 3600 | 后端连接空闲与生命周期(秒) |
| ignore_startup_parameters | extra_float_digits,options | GORM / pgx 兼容 |
| auth_type / auth_file | md5 / userlist.txt | 认证方式与用户表 |
| admin_users / stats_users | postgres | 管理与统计接口账号 |
max_db_connections = 4 是关键约束:按 ConfigMap 注释的算法(约 21 个服务 × 4 = 84,余 ~16 给 admin / replication / exporter),后端总连接保持在 90 以内。
后端数据库依赖:[databases] 用通配 * 把所有库转发到 host=postgres-primary.postgres.svc.cluster.local port=5432,每个服务凭自己的用户/库名接入。
ExternalSecret pgbouncer-userlist 经 ClusterSecretStore vault-backend 从 Vault 拉取各服务口令,渲染出两份产物:pgbouncer-admin-pass(供 exporter sidecar 拼接连接串)与 userlist.txt(PgBouncer 的用户口令表)。refreshInterval: 1h。引用的 Vault 路径包括:
yldm/database(propertypassword)→ postgres 管理员口令yldm/production/<service>(propertydb_password)→ 各业务服务口令,覆盖平台层(auth、commerce、user、analytics、engagement、gateway、management、media、notification、scheduler、social)、应用层(aidict、creativestore、kubepocket、magicbox、myetc)以及 fluxa
游戏服(board / card / pvp / rpg)的用户条目与对应 Vault 引用已于 2026-06-12 因游戏服下线而注释(见 #881),userlist.txt 模板里用 Go-template 注释包裹,渲染为空,需要时取消注释即可恢复。
exporter sidecar 通过 env PGBOUNCER_EXPORTER_CONNECTION_STRING 以 postgres://postgres:<adminPass>@127.0.0.1:5432/pgbouncer?sslmode=disable 连接本地 PgBouncer 的 admin 库采集指标,口令来自上面的 pgbouncer-admin-pass。
访问与监控
两个 ClusterIP Service:pgbouncer(5432,业务连接入口)与 pgbouncer-metrics(9127,指标)。无 Ingress,仅集群内访问。
ServiceMonitor pgbouncer(label release: kube-prometheus-stack)按 metrics 端口、/metrics 路径、30s 间隔抓取 exporter 指标。无 HPA / VPA / PDB。
NetworkPolicy 收敛访问面:
pgbouncer-deny-all-ingress:默认拒绝所有入站。pgbouncer-allow-business-ingress:仅允许platform、game、app、argo-workflows命名空间访问5432。pgbouncer-allow-prometheus-scraping:仅允许monitoring命名空间访问9127。pgbouncer-allow-postgres-egress:出站只放行到postgres-primary的5432,以及到kube-system的 UDP53(DNS)。
注意事项
迁移流程记录在 applications/data/pgbouncer/MIGRATION.md:部署本身随 ArgoCD 自动同步后,切流是通过把各服务在 Vault 中的 db_host 从 postgres-primary.postgres.svc.cluster.local 改写为 pgbouncer.postgres.svc.cluster.local 来完成的;ExternalSecret 在 1 小时内刷新生效,回滚则把 db_host 改回原值。
健康检查与排障用 PgBouncer 的 admin 库,例如查池子与连接状态:
kubectl -n postgres exec deploy/pgbouncer -- psql -p 5432 -U postgres pgbouncer -c "SHOW POOLS;"
kubectl -n postgres exec deploy/pgbouncer -- psql -p 5432 -U postgres pgbouncer -c "SHOW CLIENTS;"
kubectl -n postgres exec deploy/pgbouncer -- psql -p 5432 -U postgres pgbouncer -c "SHOW SERVERS;"
新增业务服务接入时,需要在 ExternalSecret 的 userlist.txt 模板与 data 引用里同时补上对应用户与 Vault 路径,两处缺一不可,否则该服务无法通过 PgBouncer 认证。
返回 data 服务总览