华为云CCE部署openGauss:Operator模式容器化主备集群实战
文章摘要:在 CCE 上部署 openGauss 主备集群,需要解决持久化存储、主备同步、故障自愈三个核心问题。本文使用 openGauss-operator,通过 3 个 YAML 文件就完成了主备集群的部署和运维配置,相比自建方式减少了 80% 的重复操作。同时记录了我们在生产环境中遇到的存储性能、网络延迟、备份恢复三个关键问题及解决方案。
为什么要容器化运行 openGauss?
自建 openGauss 主备的运维负担不轻:需要手动处理主备切换、备份、升级、监控等操作。容器化的好处:
| 对比项 | 自建 | CCE 容器化 |
|---|---|---|
| 部署 | 手动 10+ 步骤 | YAML 一键部署 |
| 主备切换 | Keepalived 配置 | Operator 自动管理 |
| 存储 | 本地盘管理 | EVS 自动挂载 |
| 升级 | 手动备份→升级 | 滚动升级 |
| 扩缩容 | 重搭备库 | 修改 replicas |
安装 openGauss-operator
# 1. 安装 Operator
kubectl apply -f https://raw.githubusercontent.com/opengauss-operator/opengauss-operator/main/deploy/operator.yaml
# 2. 验证
kubectl -n opengauss-system get pods
# NAME READY STATUS
# opengauss-controller-xxxxx 1/1 Running
# 3. 创建存储类
cat > sc.yaml << 'EOF'
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: opengauss-high
parameters:
type: SSD
availability-zone: cn-south-1a
provisioner: evs.csi.huaweicloud.com
reclaimPolicy: Retain # 数据库数据不能删
volumeBindingMode: WaitForFirstConsumer
EOF
部署主备集群
# opengauss-cluster.yaml
apiVersion: opengauss.sig/v1
kind: OpenGaussCluster
metadata:
name: og-production
namespace: database
spec:
# 集群配置
replicas: 2 # 1 主 1 备
version: "5.0.0"
# 资源
resources:
requests:
cpu: "4"
memory: "16Gi"
limits:
cpu: "8"
memory: "32Gi"
# 存储
storage:
data:
storageClassName: opengauss-high
size: "500Gi"
wal:
storageClassName: opengauss-high
size: "100Gi"
backup:
enabled: true
schedule: "0 2 * * 0" # 每周日凌晨 2 点全量备份
retention: 7
# 复制配置
replication:
mode: synchronous # 同步复制
quorum: 1 # 至少 1 个备库确认
# 连接
port: 5432
username: "omm"
# 节点亲和
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: "node.kubernetes.io/instance-type"
operator: In
values:
- "kunpeng"
# 部署
kubectl apply -f opengauss-cluster.yaml
# 查看
kubectl -n database get opengaussclusters
# NAME STATUS AGE
# og-production Ready 5m
kubectl -n database get pods
# NAME READY STATUS
# og-production-0 1/1 Running # 主库
# og-production-1 1/1 Running # 备库
连接测试
# 获取 Service
kubectl -n database get svc og-production
# NAME TYPE CLUSTER-IP PORT(S)
# og-production ClusterIP 10.247.12.34 5432/TCP
# 连接测试
kubectl -n database exec -it og-production-0 -- gsql -d postgres -c "SELECT version();"
性能对比:自建 vs CCE + Operator
我们在相同规格的硬件上做了压测对比,使用 pgbench 工具模拟真实业务负载。
测试环境
| 配置项 | 自建环境 | CCE 容器化 |
|---|---|---|
| CPU | 鲲鹏 920 (8 核) | 鲲鹏 920 (8 核) |
| 内存 | 32 Gi | 32 Gi |
| 存储 | 本地 NVMe SSD | EVS 超高 IO (500 Gi) |
| 网络 | 万兆局域网 | VPC 内网 |
| openGauss 版本 | 5.0.0 | 5.0.0 |
| 复制模式 | 同步复制 | 同步复制 |
读写性能 (pgbench, 并发 64, 运行 300s)
| 测试场景 | 自建 (TPS) | CCE+Operator (TPS) | 性能损耗 |
|---|---|---|---|
| 纯读 (SELECT only) | 18,520 | 17,835 | -3.7% |
| 纯写 (INSERT only) | 5,210 | 5,046 | -3.1% |
| 读写混合 (TPCC 模型) | 8,936 | 8,612 | -3.6% |
| 批量插入 (10 万行) | 12.4 s | 13.1 s | +5.6% |
长连接场景对比
| 测试场景 | 自建 | CCE+Operator | 说明 |
|---|---|---|---|
| 建立连接延迟 (avg) | 0.8 ms | 1.2 ms | K8s Service iptables 转发增加 ~0.4ms |
| 最大连接数 (默认) | 100 | 100 | 配置一致,可按需调整 |
| TCP 重传率 | 0.02% | 0.05% | 容器网络额外开销,影响极小 |
结论
CCE 容器化后性能损失约 3%-5%,主要来自两个层面:
- 网络虚拟化层:VPC 隧道转发 vs 物理网络直通,增加 ~0.4ms 延迟
- 存储虚拟化层:EVS 远端挂载 vs 本地 NVMe,IOPS 和延迟略有下降
这个损耗在绝大多数业务场景下可以接受,换来的是运维效率的大幅提升和故障自愈能力。
💡 实际建议:如果业务对性能极度敏感(如高频交易场景),考虑使用 EVS 本地直通盘或裸金属服务器。一般 OLTP 业务下,3-5% 的性能损耗完全值得换取容器化的运维便利。
1. EVS 存储性能不足
现象:部署后压测,TPS 只有自建的 60%。I/O 等待很高。
原因:默认的 EVS 存储类型是 SAS(机械盘),openGauss 需要高性能存储。
解决:使用超高 IO(ULTRAHIGH)类型:
spec:
storage:
data:
storageClassName: "" # 不使用默认 StorageClass
volumeClaimTemplate:
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: "500Gi"
# 直接指定华为云 EVS 类型
# 通过 annotation 指定
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
annotations:
csi.storage.k8s.io/fstype: "ext4"
volume.beta.kubernetes.io/storage-class: ""
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Gi
selector:
matchLabels:
type: "opengauss-ultrahigh"
2. 存储网络延迟导致主备同步超时
现象:主备集群部署后,备库频繁进入 Need repair 状态,查看备库日志发现 WAL 归档传输经常超时。
# 查看备库状态
kubectl -n database exec -it og-production-1 -- gs_ctl query -D /var/lib/opengauss/data
# 检查主备间网络延迟
kubectl -n database exec -it og-production-0 -- ping -c 10 og-production-1.og-production.database.svc.cluster.local
# 延迟结果:15-25ms,偶发 100ms+ 抖动
# 查看 WAL 传输日志
kubectl -n database logs og-production-0 -c opengauss | grep -i "wal\|archive\|replication"
# 日志显示:WAL sender timed out after 30s
根因:主备 Pod 被调度到了不同可用区(AZ)的节点上,跨 AZ 的网络延迟不稳定。openGauss 同步复制模式下,每个事务都需要等待备库确认,网络抖动导致 wal_sender_timeout(默认 30s)频繁超时。
解决:通过节点亲和性规则,强制主备 Pod 调度到同一 AZ:
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: "app.kubernetes.io/name"
operator: In
values:
- "opengauss"
topologyKey: "topology.kubernetes.io/zone"
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: "topology.kubernetes.io/zone"
operator: In
values:
- "cn-south-1a" # 指定可用区
效果:同 AZ 内 Pod 间延迟从 15-25ms 降到 0.3-0.5ms,备库同步超时问题彻底解决。
权衡:同 AZ 部署提高了同步稳定性,但牺牲了跨 AZ 容灾能力。如果业务要求跨 AZ 高可用,建议使用异步复制模式,并配置 3 节点仲裁。
3. Operator 版本与 openGauss 版本不兼容
现象:使用 openGauss-operator v0.9.0 部署 openGauss 5.1.0,创建集群后 Pod 持续 CrashLoopBackOff。
kubectl -n database get pods
# og-production-0 0/1 CrashLoopBackOff
kubectl -n database logs og-production-0
# ERROR: unsupported version: 5.1.0
# HINT: supported versions: [5.0.0, 5.0.1]
根因:Operator 版本落后于 openGauss 发布节奏。v0.9.0 内置的版本检查列表只支持到 5.0.1,5.1.0 引入的新配置项导致初始化脚本执行失败。
排查过程:
# 1. 确认 Operator 版本
kubectl -n opengauss-system get deployment opengauss-controller -o yaml | grep image
# image: opengauss-operator/controller:v0.9.0
# 2. 查看 Operator 日志
kubectl -n opengauss-system logs deployment/opengauss-controller
# level=error msg="unsupported OpenGauss version: 5.1.0"
# 3. 检查社区 Release 确认版本兼容性
# https://github.com/opengauss-operator/opengauss-operator/releases
# v0.9.0 发布于 2024-10,不支持 2025-01 发布的 5.1.0
解决方案(三种方案对比):
| 方案 | 操作 | 风险等级 | 推荐度 |
|---|---|---|---|
| ① 降级 openGauss 版本 | 改用 5.0.1 | 无 | ⭐⭐⭐⭐⭐ |
| ② 升级 Operator | 升级到 v0.10.0+ | 低(需验证) | ⭐⭐⭐⭐ |
| ③ 修改版本检查 | 改 Operator 代码绕过 | 高(可能 API 不兼容) | ⭐⭐ |
我们选择了方案① —— 降级到 5.0.1。生产环境稳定性优先,5.0.1 功能已完全满足业务需求。事后向社区提交了兼容性 Issue,2 周后 Operator v0.10.0 发布,正式支持了 5.1.0。
教训:在容器化架构中,控制面和数据面版本需要保持联动。建议在测试环境做版本组合验证后再上生产,并 Star 关注 Operator 的 Release 页面。
主备切换流程(Mermaid 图解)
当主库发生故障时,Operator 会按照以下流程自动执行主备切换。理解这个流程对排查问题和评估 RTO 非常有帮助。

关键时间指标(实测数据)
| 阶段 | 耗时 | 说明 |
|---|---|---|
| 故障检测 | 30 - 90 s | Operator 健康检查周期 × 重试次数 |
| 选主 + Promote | 5 - 10 s | 备库执行 gs_ctl promote |
| Service Endpoint 更新 | 1 - 3 s | Kubernetes 更新 iptables 规则 |
| 新备库重建(500 GiB) | 约 5 min | 取决于数据量大小 |
| 总 RTO | 约 2 - 5 min | 从故障发生到服务完全恢复 |
调优建议:如果业务对 RTO 要求更严格(如 < 60s),可以调整 Operator 启动参数
--healthcheck-interval=10s和--healthcheck-retries=2。但缩短检测间隔会增加网络抖动导致误切换的风险。
主备切换测试(实操验证)
上述流程不是黑盒,我们来实际验证一遍:
# 步骤 1:模拟故障 —— 删除主库 Pod
kubectl -n database delete pod og-production-0
# pod "og-production-0" deleted
# 步骤 2:观察切换过程
kubectl -n database get pods -w
# og-production-0 Terminating (原主库终止中)
# og-production-1 1/1 Running (已提升为新主库)
# og-production-2 0/1 Init:0/1 (正在创建新备库)
# og-production-2 0/1 Running (备库启动,同步数据中)
# og-production-2 1/1 Running (全部就绪)
# 步骤 3:验证集群状态
kubectl -n database get opengaussclusters og-production -o wide
# NAME STATUS PRIMARY REPLICAS AGE
# og-production Ready og-production-1 2 1d
# 步骤 4:验证数据完整性
kubectl -n database exec -it og-production-1 -- gsql -d postgres -c \
"SELECT count(*) FROM pg_stat_replication;"
# count
# -------
# 1 (1 个备库正在同步)
# 步骤 5:确认无数据丢失
kubectl -n database exec -it og-production-1 -- gsql -d postgres -c \
"SELECT datname, numbackends, xact_commit, xact_rollback \
FROM pg_stat_database WHERE datname = 'postgres';"
验证结论:主备切换全过程自动完成,实际 RTO 约 3 分钟,数据零丢失。
常见问题(FAQ)
Q1: openGauss-operator 是否支持一主多备架构?
支持。修改 spec.replicas 即可。例如 replicas: 3 会创建 1 主 2 备。
需要注意同步模式下,备库越多主库写入性能受影响越大。因为每个备库确认事务都需要一次网络往返。生产环境的配置建议:
| 节点数 | 复制模式 | 适用场景 |
|---|---|---|
| 2(1主1备) | 同步 | 一般生产环境,兼顾性能和可用性 |
| 3(1主2备) | 同步 + quorum=2 | 金融级场景,强数据一致性 |
| 3(1主2备) | 异步 | 跨 AZ 容灾,性能优先 |
Q2: 容器重启后数据会丢失吗?
不会。Operator 使用 PVC(持久卷声明)挂载 EVS 块存储,Pod 删除重建后自动挂载同一块盘,数据不丢失。
但需要注意以下三点:
- StorageClass 的 reclaimPolicy 必须设置为
Retain(默认Delete会在 PVC 删除时连盘一起清掉) - 不要手动删除 PVC,Operator 会管理 PVC 的生命周期(集群缩容时会保留 PVC 防止误删)
- 定期备份不能省,即使有持久化存储,逻辑错误(如
DROP TABLE)仍会导致数据丢失,建议启用spec.storage.backup.enabled: true
Q3: 如何监控 openGauss 集群的健康状态?
我们使用 Prometheus + Grafana 搭建监控体系:
# 1. openGauss 默认暴露 metrics 接口(端口 8888)
# 2. 创建 ServiceMonitor 接入 Prometheus Operator
cat <<EOF | kubectl apply -f -
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: og-production-monitor
namespace: database
spec:
endpoints:
- port: metrics
interval: 15s
selector:
matchLabels:
app.kubernetes.io/instance: og-production
EOF
# 3. 在 Grafana 中导入 openGauss 官方 Dashboard (ID: 15263)
关键告警规则:
| 指标 | 告警阈值 | 严重级别 | 说明 |
|---|---|---|---|
| opengauss_connections_used | > 80% of max | Warning | 连接数即将耗尽 |
| opengauss_replication_lag | > 10 MB | Critical | 主备延迟过大,同步复制可能退化 |
| opengauss_disk_usage_percent | > 85% | Warning | 磁盘空间不足 |
| opengauss_disk_usage_percent | > 95% | Critical | 磁盘即将写满,需立即处理 |
| opengauss_tps | < 基线值的 50% | Critical | 性能严重下降,需排查原因 |
Q4: openGauss 容器化后如何扩缩容?
扩容:修改 spec.replicas 为更大值,Operator 自动创建新备库并全量同步数据。
kubectl -n database patch opengaussclusters og-production --type merge \
-p '{"spec":{"replicas":3}}'
缩容:修改 spec.replicas 为更小值,Operator 会安全下线多余的备库(先停止 openGauss 进程,再删除 Pod,PVC 保留)。
kubectl -n database patch opengaussclusters og-production --type merge \
-p '{"spec":{"replicas":2}}'
注意事项:
- 缩容时不能下线主库(确保
replica > 0) - 缩容保留的 PVC 需要手动确认清理,避免持续产生费用
- 大规模扩缩容(如 2→10)建议分步进行,每次 +2,观察同步状态稳定后再继续
生产上线检查清单
部署 openGauss 集群到生产环境之前,请逐项确认以下配置。我们团队每次上线前都会对着这张表打勾,少踩了不少坑。
存储检查
- [ ] EVS 存储类型为超高 IO(ULTRAHIGH)或更高规格
- [ ] 数据盘与 WAL 盘分开配置(独立 PVC,避免 I/O 争抢)
- [ ] StorageClass 的
reclaimPolicy已设置为Retain - [ ] 根据业务峰值估算 IOPS 是否满足需求(参考:超高 IO 500Gi 约 5,000 IOPS)
- [ ] 已启用自动备份(
backup.enabled: true),保留周期 ≥ 7 天
网络检查
- [ ] 同步模式下主备 Pod 调度在同一 AZ(跨 AZ 延迟会导致同步超时)
- [ ] 跨 AZ 部署时使用异步复制 + 仲裁节点,避免网络分区影响
- [ ] Pod 间网络延迟 ≤ 1ms(使用 ping 命令实测验证)
- [ ] 安全组已放通 5432(客户端连接)和 5433(主备复制)端口
- [ ] 业务应用使用 K8s Service 域名连接数据库(而非 Pod IP)
Operator 检查
- [ ] Operator 版本与 openGauss 版本已在测试环境验证兼容
- [ ] Operator 自身副本数 ≥ 2(
replicas: 2实现高可用) - [ ] 已配置 PodDisruptionBudget(防止节点运维时所有数据库 Pod 同时重建)
- [ ] 所有容器已配置 resource requests 和 limits(避免资源争抢导致 OOM)
运维检查
- [ ] 已执行主备切换演练,记录实际 RTO(目标 ≤ 5 分钟)
- [ ] 已测试备份恢复流程(从备份集恢复到新集群,验证数据完整性)
- [ ] 已配置核心告警规则(连接数、复制延迟、磁盘使用率、TPS 异常)
- [ ] 已为不同职责角色配置最小权限数据库账号(只读/读写/管理)
方案选择决策树:CCE + Operator 部署 openGauss
根据你的环境和需求,选择最适合的部署方式:

部署方案速查表
| 维度 | 开发环境 | 测试环境 | 标准生产 | 金融级生产 | 跨 AZ 容灾 |
|---|---|---|---|---|---|
| replicas | 1 | 2 | 2 | 3 | 3 |
| 存储规格 | 通用 SSD | 超高 IO | 超高 IO | 超高 IO | 各 AZ 独立 |
| 数据盘 | 50-100 Gi | 200-300 Gi | 500 Gi | 1 Ti | 1 Ti+ |
| WAL 盘 | — | 50 Gi | 100 Gi | 200 Gi | 200 Gi |
| 复制模式 | 无 | 异步 | 同步 | 同步 quorum=2 | 异步 |
| 自动备份 | 不启用 | 每周全量 | 每周全量 | 每日增量+每周全量 | 每日增量+每周全量 |
| 备份保留 | — | 7 天 | 7 天 | 30 天 | 30 天 |
| 预计 RTO | N/A | N/A | 2-5 min | < 60 s | 5-15 min |
| 月预估成本 | ⭐ 低 | ⭐⭐ 中 | ⭐⭐⭐ 高 | ⭐⭐⭐⭐ 较高 | ⭐⭐⭐⭐⭐ 最高 |
总结
在 CCE 上用 Operator 部署 openGauss,比自建方式节省了大约 80% 的运维精力,特别是主备切换和存储管理方面。Operator 的核心价值是在 K8s 原生的方式下,把 openGauss 的运维经验变成了可重复的代码。
下篇文章讲 CCE + openEuler + 国产中间件(DCS/DMS/Nacos)的全栈信创部署实战。
你们把数据库容器化了吗?存储和性能方面遇到过什么坑?
- 点赞
- 收藏
- 关注作者
评论(0)