在当今的互联网应用中,数据库作为核心基础设施,其稳定性和可用性直接关系到业务连续性。想象一下,当你在电商平台下单时,如果因为数据库单点故障导致交易失败,这种体验有多糟糕?这就是为什么我们需要高可用数据库集群。
PostgreSQL作为最先进的开源关系型数据库之一,在企业级应用中扮演着重要角色。但单实例部署存在明显短板:
我在金融行业的一次项目中就吃过亏。当时使用单节点PostgreSQL,结果主机硬件故障导致系统瘫痪6小时,直接损失数百万交易额。这个惨痛教训让我深刻认识到高可用架构的必要性。
Kubernetes与Bitnami Helm Chart的组合完美解决了这些问题:
在开始部署前,我们需要确保Kubernetes集群满足基本要求。根据我的踩坑经验,以下配置是最低要求:
bash复制# 检查Kubernetes版本
kubectl version --short | grep Server
# 输出应显示 >= v1.23
# 检查Helm版本
helm version --short
# 应显示 >= v3.8.0
如果版本不满足,可以参考官方文档升级。特别提醒:我曾遇到过v1.22集群部署后出现PV绑定异常的问题,升级到v1.23后解决。
生产环境必须配置持久化存储,否则节点重启后数据将全部丢失。建议使用本地SSD或云厂商的高性能云盘:
bash复制# 检查默认StorageClass
kubectl get storageclass
# 输出示例
NAME PROVISIONER RECLAIMPOLICY
standard (default) rancher.io/local-path Delete
如果没有默认StorageClass,需要先部署。以Local Path Provisioner为例:
yaml复制# local-path-storage.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-path
provisioner: rancher.io/local-path
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete
建议为数据库创建独立命名空间,方便资源隔离和管理:
bash复制kubectl create ns pg-db
kubectl label ns pg-db tier=database
Bitnami的postgresql-ha Chart经过大量生产验证,我们在此基础上进行定制:
bash复制helm repo add bitnami https://charts.bitnami.com/bitnami
helm pull bitnami/postgresql-ha --version 12.3.2
tar -xvf postgresql-ha-12.3.2.tgz
cd postgresql-ha
打开values.yaml文件,重点修改以下部分:
yaml复制# 高可用配置
pgpool:
replicaCount: 3 # 生产环境建议至少3个副本
adminPassword: "YourStrong@Password123"
# 存储配置
persistence:
size: 100Gi # 根据数据量预估设置
storageClass: "local-path"
# 服务暴露方式
service:
type: NodePort
nodePorts:
postgresql: 31543 # 避免使用知名端口
根据实际负载情况调整资源请求和限制:
yaml复制resources:
requests:
memory: "4Gi"
cpu: "2"
limits:
memory: "8Gi"
cpu: "4"
使用Helm进行部署,建议开启原子操作和超时设置:
bash复制helm install pg-cluster ./postgresql-ha \
-n pg-db \
--atomic \
--timeout 10m \
--set postgresql.password=DB@Admin123 \
--set postgresql.repmgrPassword=Repmgr@123
安装完成后检查Pod状态:
bash复制kubectl get pods -n pg-db -w
# 预期输出
NAME READY STATUS RESTARTS
pg-cluster-postgresql-ha-pgpool-0 1/1 Running 0
pg-cluster-postgresql-ha-pgpool-1 1/1 Running 0
pg-cluster-postgresql-ha-postgresql-0 1/1 Running 0
pg-cluster-postgresql-ha-postgresql-1 1/1 Running 0
获取连接信息并测试:
bash复制# 获取密码
export PGPASSWORD=$(kubectl get secret -n pg-db pg-cluster-postgresql-ha-postgresql -o jsonpath="{.data.password}" | base64 -d)
# 集群内连接
kubectl run psql-client --rm -it --restart=Never \
--image=bitnami/postgresql-repmgr:16 \
--env="PGPASSWORD=$PGPASSWORD" \
--command -- psql -h pg-cluster-postgresql-ha-pgpool -U postgres
# 外部访问
NODE_IP=$(kubectl get nodes -o jsonpath="{.items[0].status.addresses[0].address}")
NODE_PORT=$(kubectl get svc -n pg-db pg-cluster-postgresql-ha-pgpool -o jsonpath="{.spec.ports[0].nodePort}")
psql -h $NODE_IP -p $NODE_PORT -U postgres
如果遇到"password authentication failed"错误,通常是探针配置不合理导致:
yaml复制# 调整values.yaml中的探针延迟
postgresql:
livenessProbe:
initialDelaySeconds: 120 # 默认30秒可能不够
readinessProbe:
initialDelaySeconds: 60
startupProbe:
initialDelaySeconds: 180
当网络分区时可能出现脑裂情况,可以通过以下命令手动恢复:
bash复制# 查看复制状态
kubectl exec -n pg-db pg-cluster-postgresql-ha-postgresql-0 -- patronictl list
# 强制切换主节点
kubectl exec -n pg-db pg-cluster-postgresql-ha-postgresql-0 -- patronictl failover
根据实际负载调整Pgpool配置:
yaml复制pgpool:
config:
num_init_children: 100 # 连接池大小
max_pool: 5 # 每个子进程最大连接
connection_cache: on # 启用连接缓存
load_balance_mode: on # 开启负载均衡
建议部署Prometheus监控:
yaml复制metrics:
enabled: true
serviceMonitor:
enabled: true
namespace: monitoring
关键监控指标包括:
配置定期备份:
yaml复制backup:
enabled: true
cron: "0 2 * * *" # 每天凌晨2点
storage:
s3:
bucket: "my-postgres-backups"
endpoint: "s3.amazonaws.com"
生产环境必须启用TLS加密:
yaml复制tls:
enabled: true
autoGenerated: true
certCA: ""
certSecret: ""
网络策略限制访问来源:
yaml复制networkPolicy:
enabled: true
allowExternal: false
allowedIPs:
- 10.0.0.0/8