第七季·《PostgreSQL on Kubernetes》 本季将开启云原生数据库的新篇章。我们将从零开始,系统性地学习如何在Kubernetes上部署、管理和运维PostgreSQL,探索云原生时代的数据库新范式。本季旨在帮助DBA和开发者掌握从传统运维到云原生架构的转型升级。
【上期回顾】
上一期我们深入学习了Kubernetes的核心概念:
• Pod:最小部署单元,PostgreSQL实例运行在独立Pod中 • Service:稳定的网络访问入口, -rw
指向主库,-ro
负载均衡到备库• PV/PVC/StorageClass:持久化存储的声明与供给体系 • StatefulSet:有状态应用控制器,提供稳定网络标识和独立存储 • ConfigMap与Secret:配置管理与敏感信息保护 • CNPG独特设计:不使用StatefulSet,直接通过Operator管理Pod
掌握了K8s核心概念后,本期我们将学习Helm——Kubernetes的包管理器,以及如何使用Bitnami PostgreSQL Chart快速部署生产级数据库。
【本集概览】
| 第一部分 | ||
| 第二部分 | ||
| 第三部分 | ||
| 第四部分 | ||
| 第五部分 | ||
| 第六部分 | ||
| 第七部分 |
【第一部分】Helm基础
1.1 什么是Helm?
Helm是Kubernetes的包管理器,类似于Ubuntu的apt、macOS的brew。它将Kubernetes应用打包为Chart,实现一键部署、升级和管理。
核心概念:
| Chart | ||
| Release | ||
| Repository | ||
| Values |
Helm vs 原生YAML:
| 复杂度 | ||
| 配置灵活性 | ||
| 版本管理 | ||
| 回滚 | helm rollback | |
| 依赖管理 | ||
| 模板化 |
1.2 Helm安装与仓库配置
# 安装Helm(macOS)
brew install helm
# 安装Helm(Linux)
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# 验证安装
helm version
# 添加Bitnami仓库(最流行的PostgreSQL Chart)
helm repo add bitnami https://charts.bitnami.com/bitnami
# 更新仓库
helm repo update
# 搜索PostgreSQL Chart
helm search repo postgresql
# 输出示例:
# NAME CHART VERSION APP VERSION DESCRIPTION
# bitnami/postgresql 16.4.6 17.4.0 PostgreSQL object-relational database
# bitnami/postgresql-ha 14.3.4 17.4.0 PostgreSQL HA chart with Pgpool-II
【第二部分】Bitnami PostgreSQL Chart
2.1 Chart架构对比
Bitnami提供两种PostgreSQL Chart,适用于不同场景:
| 默认节点数 | ||
| 高可用机制 | ||
| 连接代理 | ||
| 适用场景 | ||
| 复杂度 |
架构图:
PostgreSQL (单机版):
┌─────────────┐ ┌─────────────┐
│ Primary │────▶│ Replica │
│ (读写) │ │ (只读) │
└─────────────┘ └─────────────┘
│ │
└─────────┬─────────┘
▼
Service (5432)
主库Service指向Primary
PostgreSQL-HA (高可用版):
┌─────────────────┐
│ Pgpool-II │
│ (负载均衡+连接池) │
└────────┬────────┘
│
┌──────────────┼──────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│Primary │ │Replica 1 │ │Replica 2 │
│+repmgr │ │+repmgr │ │+repmgr │
└──────────┘ └──────────┘ └──────────┘
2.2 安装PostgreSQL (单机版)
# 基本安装
helm install my-postgres bitnami/postgresql \
--set auth.postgresPassword=mysecretpassword \
--set auth.password=myuserpassword \
--set auth.username=myuser \
--set auth.database=mydb
# 查看Release状态
helm status my-postgres
# 查看部署的资源
kubectl get all -l app.kubernetes.io/instance=my-postgres
# 获取连接信息
export POSTGRES_PASSWORD=$(kubectl get secret my-postgres-postgresql -o jsonpath="{.data.postgres-password}" | base64 -d)
echo $POSTGRES_PASSWORD
2.3 安装PostgreSQL-HA (高可用版)
# 高可用版安装
helm install my-postgres-ha bitnami/postgresql-ha \
--set postgresql.password=replicationPassword \
--set postgresql.repmgrPassword=repmgrPassword \
--set pgpool.adminPassword=pgpoolAdminPassword
# 查看部署的资源
kubectl get pods -l app.kubernetes.io/instance=my-postgres-ha
# 输出示例:
# NAME READY STATUS RESTARTS AGE
# my-postgres-ha-postgresql-0 1/1 Running 0 2m
# my-postgres-ha-postgresql-1 1/1 Running 0 2m
# my-postgres-ha-postgresql-2 1/1 Running 0 2m
# my-postgres-ha-pgpool-6c9b7f8d9c-xyz 1/1 Running 0 2m
2.4 连接到数据库
# 方法1:通过Pgpool-II连接(高可用版)
kubectl run postgresql-client --rm --tty -i --restart='Never' \
--namespace default --image bitnami/postgresql:latest \
--env="PGPASSWORD=$PGPOOL_ADMIN_PASSWORD" \
--command -- psql -h my-postgres-ha-pgpool -U admin -d postgres -p 5432
# 方法2:端口转发到本地
kubectl port-forward svc/my-postgres-ha-pgpool 5432:5432
# 方法3:获取密码后直接连接
export PGPASSWORD=$(kubectl get secret my-postgres-ha-postgresql -o jsonpath="{.data.postgres-password}" | base64 -d)
kubectl port-forward svc/my-postgres-ha-pgpool 5432:5432 &
psql -h localhost -U postgres -d postgres
【第三部分】核心配置详解
3.1 认证配置
PostgreSQL Chart认证参数:
auth.postgresPassword | mysecretpassword | |
auth.username | myuser | |
auth.password | myuserpassword | |
auth.database | mydb | |
auth.existingSecret | my-postgres-secret |
PostgreSQL-HA认证参数:
postgresql.password | |
postgresql.repmgrPassword | |
pgpool.adminPassword | |
pgpool.srCheckUser | |
pgpool.srCheckPassword |
3.2 持久化配置
# values.yaml - 持久化配置
persistence:
enabled: true # 启用持久化
size: 10Gi # 存储大小
storageClass: "fast-ssd" # 指定存储类
accessModes:
- ReadWriteOnce # 单节点读写
# 对于PostgreSQL-HA,可以为数据和WAL分别配置
postgresql:
persistence:
enabled: true
size: 50Gi # 数据存储
walPersistence:
enabled: true
size: 10Gi # WAL独立存储(推荐)
storageClass: "fast-ssd"
生产环境建议:
• 数据存储和WAL存储分离,使用不同性能的存储类 • 数据存储使用高性能SSD,WAL使用超低延迟存储 • 设置合理的存储大小,避免后期扩容困难
3.3 资源限制配置
# values.yaml - 资源限制
primary:
resources:
requests:
memory: "1Gi"
cpu: "500m"
limits:
memory: "2Gi"
cpu: "1"
readReplicas:
resources:
requests:
memory: "1Gi"
cpu: "500m"
limits:
memory: "2Gi"
cpu: "1"
# PostgreSQL-HA版本
postgresql:
resources:
requests:
memory: "1Gi"
cpu: "500m"
limits:
memory: "2Gi"
cpu: "1"
pgpool:
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "200m"
3.4 配置文件定制
自定义postgresql.conf:
# values.yaml
primary:
configuration: |-
# 替换默认配置
max_connections = 200
shared_buffers = 256MB
effective_cache_size = 1GB
log_min_duration_statement = 1000
# 或使用扩展配置(追加到默认配置)
primary:
extendedConfiguration: |-
max_connections = 200
shared_buffers = 256MB
# PostgreSQL-HA版本
postgresql:
extendedConfiguration: |-
max_connections = 300
shared_buffers = 512MB
log_statement = 'ddl'
自定义pg_hba.conf:
primary:
pgHbaConfiguration: |-
local all all trust
host all all 0.0.0.0/0 md5
host replication all 0.0.0.0/0 md5
使用外部ConfigMap:
primary:
existingConfigmap: my-postgres-config
existingConfigmapKey: postgresql.conf
3.5 初始化脚本
在首次启动时执行自定义SQL或Shell脚本:
# values.yaml
primary:
initdb:
scripts:
create-tables.sql: |
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
seed-data.sql: |
INSERT INTO users (name) VALUES ('admin'), ('test');
# 或使用外部ConfigMap
initdb:
scriptsConfigMap: my-init-scripts
【第四部分】高可用部署
4.1 PostgreSQL-HA核心组件
PostgreSQL-HA Chart包含两个核心组件:
1. repmgr(复制管理器)
• 管理PostgreSQL流复制集群 • 自动故障检测和主备切换 • 处理故障时的选主和降级
2. Pgpool-II
• 连接池,减少连接开销 • 负载均衡,读请求分发到备库 • 自动检测主备切换,对应用透明
4.2 HA配置示例
# values-ha.yaml - 生产级HA配置
architecture: replication
postgresql:
password: "strong_postgres_password"
repmgrPassword: "strong_repmgr_password"
repmgrUsername: repmgr
# 副本数量
replicaCount: 3
# 持久化
persistence:
enabled: true
size: 100Gi
storageClass: "fast-ssd"
# 资源限制
resources:
requests:
memory: 4Gi
cpu: 2
limits:
memory: 8Gi
cpu: 4
# 配置优化
extendedConfiguration: |-
max_connections = 500
shared_buffers = 1GB
effective_cache_size = 3GB
wal_buffers = 16MB
checkpoint_completion_target = 0.9
wal_keep_size = 2GB
max_wal_senders = 10
synchronous_commit = off
hot_standby = on
pgpool:
adminPassword: "strong_pgpool_password"
# 副本数量
replicaCount: 2
# 服务暴露方式
service:
type: LoadBalancer # 云环境用LoadBalancer
port: 5432
# 负载均衡配置
loadBalancing: true
replicationMode: slony
# 资源限制
resources:
requests:
memory: 512Mi
cpu: 250m
limits:
memory: 1Gi
cpu: 500m
# 卷权限初始化容器(解决非root用户权限问题)
volumePermissions:
enabled: true
4.3 部署命令
# 使用values.yaml部署
helm install my-postgres-ha bitnami/postgresql-ha -f values-ha.yaml
# 或使用--set参数
helm install my-postgres-ha bitnami/postgresql-ha \
--set postgresql.password=strong_password \
--set postgresql.repmgrPassword=strong_repmgr_password \
--set pgpool.adminPassword=strong_pgpool_password \
--set postgresql.replicaCount=3 \
--set pgpool.replicaCount=2 \
--set persistence.size=100Gi
4.4 监控HA集群状态
# 查看repmgr集群状态
kubectl exec -it my-postgres-ha-postgresql-0 -- bin/bash -c "repmgr cluster show"
# 输出示例:
# ID | Name | Role | Status | Upstream | Location
# 1 | postgresql-0 | primary | * running | | default
# 2 | postgresql-1 | standby | running | postgresql-0 | default
# 3 | postgresql-2 | standby | running | postgresql-0 | default
# 查看Pgpool-II状态
kubectl exec -it my-postgres-ha-pgpool-0 -- bin/bash -c "pcp_node_info -h localhost -p 9898 -U admin -w"
# 模拟主库故障测试自动切换
kubectl delete pod my-postgres-ha-postgresql-0
# 等待约30秒后,观察新主库选举
【第五部分】生产环境调优
5.1 监控集成
Prometheus Exporter配置:
# values.yaml
metrics:
enabled: true # 启用metrics
serviceMonitor:
enabled: true # 创建ServiceMonitor
namespace: monitoring
interval: 30s
# 自定义监控查询
customMetrics:
enabled: true
queries:
- name: transaction_count
query: "SELECT sum(xact_commit + xact_rollback) FROM pg_stat_database WHERE datname = current_database()"
- name: active_connections
query: "SELECT count(*) FROM pg_stat_activity WHERE state = 'active'"
5.2 备份配置
使用Barman或pgBackRest进行备份:
# 使用pgBackRest(CloudNativePG集成)
pluginBarmanCloud:
enabled: true
configuration:
BARMON_CLOUD_PROVIDER: aws
BARMON_CLOUD_REGION: us-east-1
BARMON_CLOUD_BUCKET: my-backup-bucket
5.3 TLS加密配置
启用TLS加密:
# 1. 创建证书Secret
kubectl create secret generic postgres-tls \
--from-file=tls.crt=./server.crt \
--from-file=tls.key=./server.key \
--from-file=ca.crt=./ca.crt
# 2. 部署时配置TLS
helm install my-postgres bitnami/postgresql \
--set tls.enabled=true \
--set tls.certificatesSecret=postgres-tls \
--set tls.certFilename=tls.crt \
--set tls.certKeyFilename=tls.key \
--set volumePermissions.enabled=true # TLS需要权限调整
5.4 生产环境配置清单
persistence.size | ||
primary.resources | ||
readReplicas.replicaCount | ||
postgresql.extendedConfiguration | ||
metrics.enabled | ||
volumePermissions.enabled | ||
image.tag |
【第六部分】升级与回滚
6.1 常见问题:密码管理
这是最容易被忽视的陷阱!
Bitnami Chart在首次安装时随机生成密码并存入Secret。如果升级时未指定原密码,新Pod会使用新密码,但数据仍用旧密码,导致认证失败。
# 错误示范:直接升级,未指定密码
helm upgrade my-postgres bitnami/postgresql
# 结果:新Pod无法连接数据库!FATAL: password authentication failed
# 正确做法:先获取原密码,升级时指定
export POSTGRES_PASSWORD=$(kubectl get secret my-postgres-postgresql -o jsonpath="{.data.postgres-password}" | base64 -d)
helm upgrade my-postgres bitnami/postgresql \
--set auth.postgresPassword=$POSTGRES_PASSWORD \
--set auth.replicationPassword=$POSTGRES_PASSWORD
6.2 升级Chart版本
# 1. 更新仓库
helm repo update
# 2. 查看可用版本
helm search repo bitnami/postgresql --versions
# 3. 升级到指定版本
helm upgrade my-postgres bitnami/postgresql \
--version 16.4.6 \
--set auth.postgresPassword=$POSTGRES_PASSWORD \
-f production-values.yaml
# 4. 查看升级历史
helm history my-postgres
6.3 回滚操作
# 查看版本历史
helm history my-postgres
# 回滚到上一个版本
helm rollback my-postgres
# 回滚到指定版本
helm rollback my-postgres 2
6.4 PVC保留问题
Helm卸载时,StatefulSet的PVC不会被自动删除。这可能导致重装时数据被重用。
# 完全清理(谨慎操作!)
helm uninstall my-postgres
kubectl delete pvc -l app.kubernetes.io/instance=my-postgres
【第七部分】本章总结
7.1 最佳实践总结
| 密码固定 | |
| 使用immutable tags | |
| 资源配额 | |
| 存储规划 | |
| 监控集成 | |
| 定期备份 | |
| 版本锁定 | |
| 测试先行 |
7.2 两种Chart选型建议
7.3 实战练习
练习1:部署测试环境
# 任务:
# 1. 部署PostgreSQL单机版
# 2. 创建测试数据库和表
# 3. 配置持久化存储
# 4. 测试Pod重启后数据是否保留
练习2:部署HA环境
# 任务:
# 1. 部署PostgreSQL-HA(3副本)
# 2. 查看repmgr集群状态
# 3. 模拟主库故障,观察自动切换
# 4. 验证应用连接未中断
练习3:配置监控
# 任务:
# 1. 启用metrics
# 2. 安装Prometheus Operator(或使用已有)
# 3. 配置ServiceMonitor
# 4. 在Grafana中查看PostgreSQL仪表盘
7.4 下期预告
第4期:StatefulSet手把手部署——原生YAML方式
我们将深入理解StatefulSet的核心机制:
• 手写StatefulSet YAML:从零开始定义PostgreSQL集群 • Headless Service配置:为每个Pod提供稳定DNS • PVC管理:volumeClaimTemplates的使用 • 滚动更新策略:理解StatefulSet的更新行为 • 与Operator对比:理解不同方案的适用场景
手动编写StatefulSet是理解Operator内部原理的必经之路。
下期见!
本文为学习笔记,内容基于Bitnami Charts官方文档及社区最佳实践提炼总结。




