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_modetransaction事务级复用,适配 GORM / pgx 的短连接
max_client_conn200客户端侧最大连接
default_pool_size5每个 用户/库 对的默认池大小
min_pool_size / reserve_pool_size2 / 2最小常驻与预留池
max_db_connections4每库后端连接上限,把总连接压在 90 以内
server_idle_timeout / server_lifetime600 / 3600后端连接空闲与生命周期(秒)
ignore_startup_parametersextra_float_digits,optionsGORM / pgx 兼容
auth_type / auth_filemd5 / userlist.txt认证方式与用户表
admin_users / stats_userspostgres管理与统计接口账号

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(property password)→ postgres 管理员口令
  • yldm/production/<service>(property db_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_STRINGpostgres://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:仅允许 platformgameappargo-workflows 命名空间访问 5432
  • pgbouncer-allow-prometheus-scraping:仅允许 monitoring 命名空间访问 9127
  • pgbouncer-allow-postgres-egress:出站只放行到 postgres-primary5432,以及到 kube-system 的 UDP 53(DNS)。

注意事项

迁移流程记录在 applications/data/pgbouncer/MIGRATION.md:部署本身随 ArgoCD 自动同步后,切流是通过把各服务在 Vault 中的 db_hostpostgres-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 服务总览

评论