如何配置Kubernetes对接外部服务器,通过pgbouncer连接外部Postgres?
1. 为外部PostgreSQL创建K8s服务抽象
这一步是为了让集群内的pgbouncer可以通过固定的内部服务名访问外部Postgres,避免直接写IP带来的维护问题
方式1:Endpoint + 无选择器ClusterIP Service (推荐,稳定性更高)
首先创建Endpoint资源,填入外部Postgres的实际IP和端口:apiVersion: v1 kind: Endpoints metadata: name: external-postgres subsets: - addresses: - ip: 【你的外部Postgres实际IP】 ports: - port: 5432 name: postgres再配套创建无选择器的ClusterIP Service:
apiVersion: v1 kind: Service metadata: name: external-postgres spec: ports: - port: 5432 targetPort: 5432 name: postgres配置完成后,集群内可以通过
external-postgres.default.svc.cluster.local:5432访问外部Postgres方式2:ExternalName Service(适合外部Postgres用域名访问的场景)
示例配置:apiVersion: v1 kind: Service metadata: name: external-postgres spec: type: ExternalName externalName: 【你的外部Postgres域名】 ports: - port: 5432注意:使用ExternalName Service时需要确保集群CoreDNS可以正常解析外部Postgres的域名
2. 部署pgbouncer到K8s集群
第一步:创建Secret存储认证信息,避免明文配置
执行命令创建:kubectl create secret generic pgbouncer-secrets --from-literal=postgres-user=【数据库用户名】 --from-literal=postgres-password=【数据库密码】 --from-literal=pgbouncer-admin-password=【pgbouncer管理端密码】第二步:创建ConfigMap存储pgbouncer核心配置
示例配置:apiVersion: v1 kind: ConfigMap metadata: name: pgbouncer-config data: pgbouncer.ini: | [databases] * = host=external-postgres.default.svc.cluster.local port=5432 user=$(POSTGRES_USER) password=$(POSTGRES_PASSWORD) [pgbouncer] listen_addr = 0.0.0.0 listen_port = 6432 auth_type = trust auth_file = /etc/pgbouncer/userlist.txt pool_mode = transaction max_client_conn = 1000 default_pool_size = 20 userlist.txt: | "【数据库用户名】" "【数据库密码】" "pgbouncer" "【pgbouncer管理端密码】"第三步:创建pgbouncer工作负载(访问量低用Deployment即可,高可用场景可换StatefulSet)
示例Deployment配置:apiVersion: apps/v1 kind: Deployment metadata: name: pgbouncer labels: app: pgbouncer spec: replicas: 2 selector: matchLabels: app: pgbouncer template: metadata: labels: app: pgbouncer spec: containers: - name: pgbouncer image: edoburu/pgbouncer:latest # 可替换为自行维护的镜像 ports: - containerPort: 6432 env: - name: POSTGRES_USER valueFrom: secretKeyRef: name: pgbouncer-secrets key: postgres-user - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: name: pgbouncer-secrets key: postgres-password volumeMounts: - name: config mountPath: /etc/pgbouncer/pgbouncer.ini subPath: pgbouncer.ini - name: config mountPath: /etc/pgbouncer/userlist.txt subPath: userlist.txt volumes: - name: config configMap: name: pgbouncer-config第四步:创建pgbouncer的ClusterIP Service,供集群内业务访问
示例配置:apiVersion: v1 kind: Service metadata: name: pgbouncer spec: selector: app: pgbouncer ports: - port: 5432 # 直接映射为5432端口,业务侧无需修改原有端口配置 targetPort: 6432 name: postgres配置完成后,集群内业务可以通过
pgbouncer.default.svc.cluster.local:5432访问经过连接池代理的外部Postgres服务
3. 可选配套配置
- 如果集群开启了NetworkPolicy,需要新增两条策略:允许pgbouncer Pod访问
external-postgres服务的5432端口、允许业务Pod访问pgbouncer服务的5432端口 - 如果外部Postgres配置了访问白名单,需要将K8s集群所有节点的出口IP(或SNAT网关IP)加入白名单
- 可根据需求配置pgbouncer监控指标采集,对接Prometheus实现连接池运行状态监控
内容的提问来源于stack exchange,提问作者just Kirill

