k3s-etcd-backup · 定时给 etcd 拍快照并加密上传 MinIO
etcd 存储整个 Kubernetes 集群的状态(所有资源定义、ConfigMap、Secret、集群元数据),一旦损坏会让 API 不可用,因此它需要独立于 Velero 之外的专门备份。这个组件就是集群三层备份策略里的「层次 1」——以 CronJob 的形式跑在 kube-system 命名空间,每 6 小时给 etcd 拍一次快照,校验完整性、保留本地 7 天,并把快照 GPG 加密后上传到 MinIO,使得 MinIO/NAS 上永远不落明文 etcd(明文 etcd 含全部 Kubernetes secret)。
它由两组互补的 CronJob 组成:一组(etcd-backup)调度到任一控制平面节点,自己用 etcdctl snapshot save 主动拍快照存到一块 NFS PVC;另一组(k3s-etcd-snapshot-upload-masterN,每个 master 一个)直接读取 K3s 自身生成在本机磁盘上的快照,逐个 GPG 加密后用 rclone 推到 MinIO。
部署形态
ArgoCD 通过 bootstrap/applications/infrastructure/etcd-backup.yaml 同步本目录(Application 名 etcd-backup,project platform,automated: {prune, selfHeal},目标命名空间 kube-system)。本目录没有 kustomization,直接是裸 YAML 清单。
- Name
- 命名空间
- Description
- kube-system
- Name
- 工作负载类型
- Description
- CronJob ×4(1 个主动快照 + 3 个 per-master 上传),均 alpine:3.24,concurrencyPolicy: Forbid
- Name
- 调度时间
- Description
- 主动快照与 master1 上传
0 */6 * * *,master25 */6 * * *,master310 */6 * * *(均含时区 Asia/Tokyo),即每 6 小时一轮、错峰 5 分钟
- Name
- 调度约束
- Description
- 主动快照 CronJob 用
nodeSelector: node-role.kubernetes.io/control-plane=true+ control-plane 污点 toleration,hostNetwork: true连本机 etcd;三个上传 CronJob 分别nodeName: k8s-master1/2/3钉死到对应 master
- Name
- 存储
- Description
- 主动快照写到 PVC
etcd-backup-storage(storageClassnfs-client,RWX,20Gi);上传任务只读挂载本机快照目录,不占 PVC
- Name
- 历史保留
- Description
- successfulJobsHistoryLimit / failedJobsHistoryLimit 均为 3
主动快照容器在运行时下载 etcdctl v3.5.12,从 https://127.0.0.1:2379 拉取快照,使用 K3s 的 etcd 证书(/var/lib/rancher/k3s/server/tls/etcd 下的 server-ca.crt / server-client.crt / server-client.key,以只读 hostPath 挂入)。快照存为 etcd-snapshot-<时间戳>.db,附带一份 .metadata(含时间戳、主机名、大小、SHA256、etcd 版本),并清理本地 7 天前的旧快照。
配置与依赖
- Name
- ExternalSecret
- Description
etcd-backup-gpg(ClusterSecretStorevault-backend)从 Vaultyldm/backup/oracle-gpg-passphrase(propertypassphrase)拉取 GPG 口令,生成 Secretetcd-backup-gpg-passphrase,refreshInterval 1h。这是独立于 Oracle 主机的 break-glass 副本
- Name
- MinIO 凭据
- Description
- 上传任务从
minio-secret的root-password读取密码,access key 写死为xiaomo,endpointhttp://minio.minio.svc.cluster.local:9000
- Name
- 加密方式
- Description
gpg --batch -c --cipher-algo AES256,口令来自挂载的/gpg/passphrase;产物<快照名>.gpg上传后从 /tmp 删除
- Name
- 上传目标
- Description
- MinIO bucket
k3s-etcd-snapshots/<主机名>/;上传前先rclone lsf去重,已存在的.gpg跳过,实现幂等增量上传
- Name
- RBAC
- Description
- ServiceAccount
etcd-backup+ ClusterRole/Binding,授予 pods、pods/exec(get/list/create)与 nodes(get/list)
上传 CronJob 通过只读 hostPath 挂载本机的 K3s 快照目录 /var/lib/rancher/k3s/server/db/snapshots,并挂载 /etc(用于读取节点 hostname 拼出 MinIO 子路径)。它不调用 etcdctl,只是把 K3s 自动生成的快照做加密搬运。
访问与监控
这是纯后台批处理组件,没有 Service、Ingress、ServiceMonitor、PrometheusRule、HPA/VPA 或 PDB——CronJob 不需要这些。运行结果以 Job 历史(成功/失败各保留 3 个)和容器日志体现,日志里会打印快照大小、SHA256、本地备份统计,以及上传了几个新的加密快照。
资源配额:主动快照容器 requests 100m/256Mi、limits 500m/512Mi;每个上传容器 requests 100m/128Mi、limits 500m/512Mi。
注意事项
按集群备份运维手册,etcd 快照属于三层备份的层次 1(频率每 6 小时、本地保留 7 天、恢复时间目标 < 5 分钟),层次 2 是 Velero 每日集群备份,层次 3 是数据库逻辑备份 + PVE VM 快照。Velero 备份的是 Kubernetes 资源,但 etcd 故障会让 API 本身不可用,所以 etcd 必须单独备份、用于快速整体恢复。
解密用同一口令:Vault 路径 secret/yldm/backup/oracle-gpg-passphrase。注意 ESO 的 remoteRef.key 省略了 secret/ 挂载前缀(store 会自动补上),而用 vault CLI 读写时需带上完整的 secret/...。
由于设计上集群、MinIO、NAS 三处都不保存明文 etcd,恢复时必须先用该 GPG 口令解密 .gpg 才能拿到 .db 快照——口令丢失等同于备份不可用,务必确保 Vault 与 Oracle 两处副本都在。
返回 infrastructure 总览