云原生数据库自动备份策略|K8s 定时备份 + 异地存储 + 过期清理
摘要
数据库上 K8s 后,别再把备份脚本挂 cron 里裸奔了。本文交付一套生产级云原生数据库自动备份方案,覆盖达梦 DM8、人大金仓 KingbaseES V9,使用 K8s CronJob 实现定时全量/增量备份,推送到 S3/MinIO 异地存储,并自动清理过期备份集。文中提供可直接复制的 YAML 配置、备份脚本、过期策略对照表及避坑清单,让你的信创数据库备份也享受云原生红利。
📌 政务选金仓,金融选达梦;MySQL 迁移选金仓,Oracle 迁移选达梦。
1. 备份需求与总体设计
生产级数据库备份必须满足3-2-1 原则:至少 3 份副本,2 种不同介质,1 份异地。 容器化环境下的难点在于:
-
备份工具需在容器内可用,且不能依赖宿主机 cron。
-
数据目录通过 PVC 挂载,备份时要做到一致性。
-
备份文件要自动推到异地存储,不能留下单点。
总体设计:
-
K8s CronJob 驱动备份任务,与数据库 Pod 共享数据卷(或通过远程备份)。
-
备份类型: 每日全量 + 每小时归档日志备份。
-
存储目标: 本地 NAS/NFS 先落一份,再通过
mc或s3cmd同步到 MinIO/S3 异地桶。 -
过期清理: 基于备份标签和保留天数自动删除。
✅ 适用场景:达梦单机/主备集群、人大金仓单机/高可用集群。
2. 环境与存储准备
| 组件 | 版本/说明 |
|---|---|
| Kubernetes | v1.28 |
| 达梦数据库 | DM8.1.2.192 |
| 人大金仓 | KingbaseES V9 |
| 本地备份存储 | NFS PV,挂载到 /backup/local |
| 异地对象存储 | MinIO(或 AWS S3),bucket: db-backup-offsite |
| 备份工具 | dmrman(达梦)、sys_dump / sys_basebackup(金仓)、mc 客户端 |
存储类与 PVC 定义:
yaml
# 本地备份 PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: backup-local-pvc
namespace: dm
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 500Gi
storageClassName: nfs-client
MinIO 认证 Secret:
bash
kubectl create secret generic s3-credentials \
--from-literal=accesskey=minioadmin \
--from-literal=secretkey=minioadmin \
-n dm
3. CronJob 定时备份实战
3.1 达梦数据库全量备份 CronJob
达梦使用 dmrman 进行全量备份,需指定数据库 INI 文件路径。我们通过共享 PVC 的方式直接访问数据目录,并在容器中执行备份。
yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: dm-full-backup
namespace: dm
spec:
schedule: "0 2 * * *" # 每天凌晨2点
successfulJobsHistoryLimit: 2
failedJobsHistoryLimit: 2
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: harbor.dm.local/dm8:tools # 包含 dmrman 的镜像
env:
- name: BACKUP_DIR
value: "/backup/local/dm/$(date +%Y%m%d)"
- name: S3_BUCKET
value: "db-backup-offsite"
- name: S3_ACCESS_KEY
valueFrom:
secretKeyRef:
name: s3-credentials
key: accesskey
- name: S3_SECRET_KEY
valueFrom:
secretKeyRef:
name: s3-credentials
key: secretkey
command: ["/bin/bash", "-c"]
args:
- |
set -e
mkdir -p $BACKUP_DIR
echo "开始达梦全量备份..."
dmrman CTLSTMT="BACKUP DATABASE '/dm/data/DAMENG/dm.ini' FULL BACKUPSET '$BACKUP_DIR' COMPRESSED LEVEL 1"
echo "备份完成,文件列表:"
ls -lh $BACKUP_DIR
# 同步到 S3/MinIO
mc alias set myminio http://minio.minio:9000 $S3_ACCESS_KEY $S3_SECRET_KEY
mc mirror $BACKUP_DIR myminio/$S3_BUCKET/dm/$(date +%Y%m%d)/
echo "异地同步完成"
volumeMounts:
- name: data
mountPath: /dm/data
readOnly: true # 只读挂载,保证一致性
- name: local-backup
mountPath: /backup/local
volumes:
- name: data
persistentVolumeClaim:
claimName: data-dm-primary-0 # 与数据库 Pod 相同 PVC
- name: local-backup
persistentVolumeClaim:
claimName: backup-local-pvc
restartPolicy: OnFailure
💡 只读挂载数据卷,避免备份任务意外修改数据文件。达梦的 dmrman 在读环境下可正常备份,但一定要确保数据库处于归档模式。
3.2 人大金仓全量备份 CronJob
金仓可使用 sys_dump 进行逻辑备份,或 sys_basebackup 做物理备份。物理备份效率高,适合大型库。
yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: kingbase-full-backup
namespace: kingbase
spec:
schedule: "0 2 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: kingbase_v9:latest
env:
- name: PGDATA
value: "/var/lib/kingbase/data"
- name: BACKUP_DIR
value: "/backup/local/kingbase/$(date +%Y%m%d)"
command: ["/bin/bash", "-c"]
args:
- |
set -e
mkdir -p $BACKUP_DIR
# 开始物理备份
sys_basebackup -h localhost -p 54321 -U system -D $BACKUP_DIR/base -Ft -z -P
echo "金仓全量备份完成"
# 推送到异地,工具类同
mc alias set myminio http://minio.minio:9000 $S3_ACCESS_KEY $S3_SECRET_KEY
mc mirror $BACKUP_DIR myminio/$S3_BUCKET/kingbase/$(date +%Y%m%d)/
volumeMounts:
- name: local-backup
mountPath: /backup/local
- name: data
persistentVolumeClaim:
claimName: data-kingbase-0
readOnly: true
...
🛑 注意: 物理备份需要连接到数据库实例,如果数据库 Pod 没有 Service,可以通过 sidecar 或者直接 kubectl exec 方式;这里推荐使用独立 CronJob 连接数据库 Service 执行备份,更解耦。
4. 异地存储推送:S3/MinIO 接入
我们选择 MinIO 作为异地存储,兼容 S3 协议。备份完成后使用 mc 客户端镜像同步。
最小权限策略: 创建专用 bucket 并限制访问。
bash
mc mb myminio/db-backup-offsite
mc admin policy create myminio db-backup-write <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:PutObject", "s3:GetObject", "s3:DeleteObject", "s3:ListBucket"],
"Resource": ["arn:aws:s3:::db-backup-offsite/*", "arn:aws:s3:::db-backup-offsite"]
}
]
}
EOF
mc admin user add myminio dbbackupuser <password>
mc admin policy attach myminio db-backup-write --user dbbackupuser
同步命令核心参数:
bash
mc mirror --overwrite --remove --watch /backup/local myminio/db-backup-offsite/
但在 CronJob 中我们通常执行单次同步,不需要 --watch,改为:
bash
mc mirror $BACKUP_DIR myminio/$S3_BUCKET/dm/$(date +%Y%m%d)/
mirror 命令会自动对比并只上传差异部分,节省带宽。
5. 过期备份自动清理策略
保留策略建议:
| 备份类型 | 保留数量/天数 | 清理方式 |
|---|---|---|
| 每日全量 | 保留最近 7 天 | CronJob 每日检查,删除 7 天前目录 |
| 每小时归档 | 保留最近 24 小时 | 与全量同步清理 |
| 异地存储 | 保留 30 天 | MinIO 生命周期规则自动过期 |
本地清理脚本(附加在全量备份 CronJob 末尾):
bash
# 清理 7 天前的本地备份
find /backup/local/dm/ -maxdepth 1 -type d -mtime +7 -exec rm -rf {} \;
MinIO 生命周期规则(通过 mc 设置):
bash
mc ilm rule add --expire-days 30 myminio/db-backup-offsite
这条规则会让 bucket 中超过 30 天的对象自动删除,无需手动干预。
✅ 为防误删,可在清理前加入文件列表审计:
bash
find /backup/local/dm/ -maxdepth 1 -type d -mtime +7 > /tmp/cleanup.log
6. 监控与告警闭环
备份任务不能悄无声息地失败,必须建立监控。
实现方式:
-
CronJob 成功/失败状态通过
kube-state-metrics暴露指标。 -
配置 Prometheus 告警规则:最近一次 CronJob 执行失败或超过 24 小时未成功。
-
备份大小异常告警(与昨天比较波动 > 50%)。
Prometheus 告警规则示例:
yaml
groups:
- name: db-backup
rules:
- alert: DatabaseBackupJobFailed
expr: kube_job_status_failed{job_name=~"dm-full-backup|kingbase-full-backup"} > 0
for: 5m
labels:
severity: critical
annotations:
summary: "数据库备份 Job 失败"
description: "{{ $labels.job_name }} 执行失败,请立即检查。"
- alert: DatabaseBackupMissing
expr: time() - kube_job_status_last_successful_time{job_name=~"dm-full-backup-.*"} > 86400
for: 5m
labels:
severity: critical
annotations:
summary: "数据库备份超过 24 小时未成功"
备份验证: 定期(例如每周)从异地存储拉取备份进行恢复演练,确保备份可用。
7. 避坑清单(血泪史)
| 坑点 | 现象 | 根因与解决 |
|---|---|---|
| 备份时数据不一致 | 恢复后发现数据缺失 | 未用只读挂载或未开启归档;达梦务必用 dmrman 且数据库为 ARCHIVELOG 模式,金仓物理备份需连接数据库获取一致性位点 |
| CronJob 并发导致磁盘爆满 | 节点磁盘 100%,所有 Pod 异常 | 设置 concurrencyPolicy: Forbid,并发时跳过新任务;并加上容量监控 |
| mc 推送失败但不中断脚本 | 后续删除过期备份,导致仅剩残缺副本 | 在脚本中加 set -e 且 mc mirror 返回非 0 时退出;或推送失败发送告警 |
| 权限不足导致备份文件无法读取 | 备份文件属主是 root,恢复容器内 dmdba 无法访问 | 在备份容器中设置 securityContext.fsGroup: 1000,或在备份后执行 chown 1000:1000 |
| PVC 容量不足,备份写到一半失败 | 备份任务连续失败 | 监控 PVC 使用率,设置 persistentVolumeClaimRetentionPolicy 配合清理脚本,或直接备份到对象存储(绕过本地) |
特别警示: 绝对不要将数据库数据卷以读写方式挂载给多个 Pod,极易造成数据文件损坏。备份任务务必只读挂载数据卷。
📢 总结
这篇云原生备份方案,从 CronJob 定时调度、全量备份脚本、异地 MinIO 同步,到过期清理和监控告警,完整覆盖了达梦和人大金仓两大信创数据库的自动备份需求。所有 YAML 配置都可以直接复制进项目,稍作环境变量调整就能跑。
数据库上 K8s,备份策略不是脚本的堆砌,而是一套包含一致性保障、异地多副本、自动生命周期管理的闭环系统。把这套方案落地,你的数据库即使遭遇 PVC 损坏、机房级灾难,也能在分钟级恢复业务。
更多推荐
所有评论(0)