十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Kubernetes集群备份与恢复实战:etcd快照与Velero双保险方案

Kubernetes集群备份与恢复实战:etcd快照与Velero双保险方案 自打开始正经维护 Kubernetes 集群之后我几乎每天都会被同一个问题敲打如果哪天 etcd 数据盘坏了、误删了一个 namespace或者整台 Master 节点被清空你到底能不能把集群拉回来我相信绝大多数人的第一反应是有资源清单啊丢了重建不就行了。但真正经历过故障的人会明白这种想法在单机实验环境勉强成立放到生产环境里基本等于裸奔。因为集群里除了 Deployment、Service 这些能kubectl get出来的对象还有大量的配置、密钥、PVC 里的业务数据、CRD 资源、RBAC 授权关系这些东西一旦丢失想靠人工重建几乎是不可能完成的任务。这篇博客就围绕 Kubernetes 集群备份与恢复的完整配置与实践展开。我会从备份思路讲起逐步拆解 etcd 快照和 Velero 这两套主流方案把命令、参数、常见坑、恢复演练的步骤全部摊开讲。不管你是在自己搭的测试集群上做实验还是正在为生产集群设计容灾方案这篇内容都能帮你在脑子里建立起一套清晰的备份恢复框架。先说明一点本文所有操作都基于我实际在用的集群环境验证过但版本差异会带来细节上的变化阅读时请结合你自己的集群版本做微调。1. 备份前先把思路理清楚到底要备份什么在动手配置任何工具之前我建议你先完成一轮“灵魂拷问”。因为备份方案的设计本质上是对集群资产做分类分类做不清楚后面所有备份动作都是盲目的。1.1 先问自己三个关键问题第一个问题如果集群彻底无法恢复你能否在 24 小时内重建出所有业务这里说的业务不只是工作负载还包括它依赖的配置中心数据、数据库内容、消息队列里的积压消息、对象存储桶以及 K8s 集群中的各种自定义资源。第二个问题你的备份是否被人为验证过备份文件存在那里没有任何意义只有定期做恢复演练、并且演练成功过备份才算真正有效。第三个问题万一发生误删操作你允许的数据丢失时间窗口是多久这个 RPORecovery Point Objective直接决定了你的备份频率和备份方式。我把这些问题拿出来说是因为我见过太多人把备份等同于“对 etcd 做一个快照”。实际上etcd 快照只覆盖 Kubernetes 控制面存储的状态它根本不包含业务容器写入 PV 的数据。如果你跑的是 MySQL、Redis 这类有状态服务PV 数据丢了etcd 再完整也只能帮你恢复出一个空壳数据库。1.2 把资产拆成三个层次来看待我习惯把一个集群需要保护的资产分成三个层次。第一层是集群状态层对应 etcd 中保存的几乎所有 Kubernetes 对象包括 Deployment、Service、ConfigMap、Secret、Namespace、RBAC 规则、CRD 实例等。这一层的特点是数据量通常不大但变化极其频繁任何一次kubectl apply都会改动它。第二层是持久化数据层也就是 PV/PVC 背后真正存储的业务文件、数据库文件这一层通常由云盘、NFS、Ceph 等外部存储系统承载Kubernetes 自身并不知道里面装了什么。第三层是外部依赖层比如镜像仓库里的镜像、Helm Chart 仓库、GitOps 仓库里的部署清单这些资源往往不在集群内却是重建集群时必不可少的输入。有了这三层视角之后你的备份策略就非常清晰了集群状态层用 etcd 快照解决持久化数据层用 Velero 这类工具配合存储驱动解决外部依赖层则靠日常的版本管理和仓库镜像同步解决。三者缺一不可。1.3 方案选型etcd 快照与 Velero 并不冲突我经常在社区里看到有人争论“备份到底该用 etcd 快照还是 Velero”这个问题本身就问错了。这两种工具解决的不是同一个问题放在一起使用才是一套完整的方案。etcd 快照负责兜底适合应对集群级灾难比如 Master 节点不可用、etcd 数据全部损坏、误删了整个 Namespace 且资源无法重建。Velero 负责精细化和应用级备份适合做资源迁移、版本回滚、按命名空间恢复还能借助 restic 或 Kopia 备份 PV 数据。如果你的集群所有数据都有外部备份并且一切皆代码那你可以只依赖 GitOps 方式重建但大多数团队还没做到这个程度因此快照依然是必需品。看到这里你基本明白了我不是让你二选一而是建议你用“双保险”思路搭建备份体系。后面几节我会把两条路线都走一遍你可以直接照抄配置。2. 动手前的环境准备与配置项梳理不管用 etcd 快照还是 Velero集群本身需要满足一些最基本的条件。这一节先把环境准备和核心配置项讲清楚避免后面实操时卡在一些莫名其妙的地方。2.1 确认集群部署方式与 etcd 形态首先要确认你的 etcd 是怎么部署的。不同集群形态会导致 etcd 的访问方式完全不同这一点是新手最容易栽跟头的地方。kubeadm 部署的集群etcd 以静态 Pod 方式运行在 Master 节点上通过/etc/kubernetes/manifests/etcd.yaml定义证书和配置集中在/etc/kubernetes/pki/etcd/目录。二进制方式部署的集群etcd 通常以 systemd 服务运行数据目录、证书路径、监听地址全部由你自定义快照时需要手动拼接参数。云厂商托管的集群如 EKS、ACK、TKE控制面 etcd 基本由云厂商管理用户无法直接接触此时你更需要依赖 Velero 或云厂商自带的集群快照能力做应用级备份。定位好你自己的集群形态后面的命令才能跑通。我下面的实践示例基于 kubeadm 部署的集群来展开这也是社区里最常见的自建集群方式。2.2 为备份账号准备必要的权限配置如果你要用 Velero它需要一个专用的服务账号并且这个账号需要有足够权限读取集群中的所有资源。Velero 安装时默认会创建velero命名空间并部署一组 RBAC 规则正常情况下不用手动造轮子。但有一点容易忽略当你计划备份自定义资源CRD时需要确保 Velero 的服务账号对相关 CRD 有 get、list、watch 权限。如果某天你发现备份任务显示成功但恢复后 CRD 实例丢了优先检查是不是权限不足导致 Velero 无法枚举资源。这里给出一个排查用的最小 RBAC 配置它授予了备份操作所需的粗粒度权限。如果你对安全要求比较高建议按需收缩到具体资源apiVersion: v1 kind: ServiceAccount metadata: name: velero namespace: velero --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: velero-admin roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: velero namespace: velero这个配置看起来比较粗暴但它能保证 Velero 不会因为权限问题而跳过资源。生产环境建议结合 Velero 官方文档中的 RBAC 模板做进一步裁剪。2.3 准备一套独立的对象存储用于存放备份Velero 的备份文件需要落到对象存储中。如果你已经在用 AWS S3、阿里云 OSS、MinIO 这类兼容 S3 协议的服务那可以直接复用。如果还没有我强烈建议你在内网部署一个 MinIO专门用于存放备份。它的部署非常简单单机版用 Docker 几分钟就能跑起来。用 MinIO 主要是为了两个目的一是让备份文件集中管理不会被随意清理二是 Velero 官方对 S3 API 的兼容性很好选它省去很多兼容性适配的麻烦。存储桶创建好后记录下 endpoint 地址、access key、secret key后面配置 Velero 时要用到。下面是我的 MinIO 初始化命令示例实际使用时请替换成你自己的账号密码docker run -d \ --name minio \ -p 9000:9000 \ -p 9001:9001 \ -e MINIO_ROOT_USERvelero_backup \ -e MINIO_ROOT_PASSWORDYourStrongPass2026 \ -v /data/minio:/data \ minio/minio server /data --console-address :9001启动后到控制台创建一个名为velero-backup的 bucket并且建议开启版本控制。原因很简单版本控制能防止备份对象被误删或覆盖相当于给备份又加了一层保险。3. etcd 快照备份与恢复的完整实践etcd 快照是整个集群备份体系的第一块基石也是恢复集群控制面数据的终极手段。我不敢说它难但操作过程中稍有不慎就会造成数据不一致所以接下来我会把每一步拆得很细。3.1 配置 etcd 客户端证书环境变量使用etcdctl做快照通常需要 TLS 证书认证。kubeadm 部署的集群中etcd 证书位于 Master 节点的/etc/kubernetes/pki/etcd/目录你需要在执行命令前导出环境变量否则会提示证书校验失败。我的做法是先把以下内容写到/etc/profile.d/etcdctl.sh中简化后续操作export ETCDCTL_API3 export ETCDCTL_CACERT/etc/kubernetes/pki/etcd/ca.crt export ETCDCTL_CERT/etc/kubernetes/pki/etcd/server.crt export ETCDCTL_KEY/etc/kubernetes/pki/etcd/server.key export ETCDCTL_ENDPOINTShttps://127.0.0.1:2379关于证书文件有一个细节值得说明server.crt和server.key是 etcd 服务端证书用于 etcd 各成员之间通信同时也被 etcdctl 作为客户端证书使用。如果你在某个节点上找不到server.*文件也可以尝试用peer.crt和peer.key替代但首选仍是 server 证书。执行source /etc/profile.d/etcdctl.sh后可用一条简单的etcdctl endpoint health命令验证连接是否正常。3.2 执行手动快照与定时备份完成认证配置后做一次手动快照就非常简单了mkdir -p /backup/etcd etcdctl snapshot save /backup/etcd/snapshot-$(date %Y%m%d-%H%M%S).db执行成功后会输出类似Snapshot saved at /backup/etcd/snapshot-xxxx.db的信息。此时你可以用校验命令确认快照文件没有损坏etcdctl snapshot status /backup/etcd/snapshot-xxxx.db该命令会返回快照的版本、数据大小、hash 值等信息。我每次做完快照都会顺手跑一次这条命令它虽然不能百分百保证恢复成功但至少能从哈希层面排除文件在落盘过程中出现损坏的可能。手动快照只能救急不能作为常态化机制。更合理的做法是写一个定时任务脚本每天在业务低峰期自动执行快照并清理三天前的旧文件。下面是我实际在用的脚本你拿走改成自己的备份目录就能用#!/bin/bash BACKUP_DIR/backup/etcd RETENTION_DAYS3 source /etc/profile.d/etcdctl.sh mkdir -p ${BACKUP_DIR} etcdctl snapshot save ${BACKUP_DIR}/snapshot-$(date %Y%m%d-%H%M%S).db find ${BACKUP_DIR} -name snapshot-*.db -mtime ${RETENTION_DAYS} -exec rm -f {} \;用crontab -e添加定时任务以每天凌晨 2 点执行为例0 2 * * * /opt/scripts/etcd-backup.sh /var/log/etcd-backup.log 21关于快照保留周期我建议根据自己的数据量决定。etcd 快照文件一般不会很大几百 MB 到几个 GB 都很常见所以你完全可以把保留周期设置得长一些比如保留 7 份每日快照外加每周快照。丢失数据这件事宁可多留不可少留。3.3 恢复实操从快照还原到单机集群恢复 etcd 是整个集群恢复流程中最容易手忙脚乱的部分因为你需要把一个“已经存在的故障集群”先停下来再手动去重建数据目录。这里强调一下恢复操作必须在所有 etcd 节点上协调进行不建议只对单节点操作而让其他节点继续运行。下面以单节点 etcd 为例展开。第一步停掉 kube-apiserver 和 etcd。如果是静态 Pod 方式部署最直接的做法是把/etc/kubernetes/manifests/下的etcd.yaml移走并用kubelet的静态 Pod 机制让它自动停掉。但更稳妥的顺序是先把 apiserver 停掉避免 apiserver 在 etcd 恢复期间不断写入数据导致快照还原后的数据被再次污染。mv /etc/kubernetes/manifests/etcd.yaml /root/backup-manifests/ mv /etc/kubernetes/manifests/kube-apiserver.yaml /root/backup-manifests/ sleep 30第二步备份并清空旧的 etcd 数据目录。默认数据目录是/var/lib/etcd我建议先把它整个移动到一个备份位置而不是直接删除防止恢复失败时还有后悔药可吃mv /var/lib/etcd /var/lib/etcd.bak.$(date %Y%m%d)第三步用快照文件恢复数据目录。etcdctl 的snapshot restore命令会生成一个新的数据目录你需要通过--data-dir参数指定位置并传入与旧集群一致的名称和证书参数etcdctl snapshot restore /backup/etcd/snapshot-xxxx.db \ --name etcd-1 \ --initial-cluster etcd-1https://127.0.0.1:2380 \ --initial-cluster-token etcd-cluster \ --initial-advertise-peer-urls https://127.0.0.1:2380 \ --data-dir /var/lib/etcd这里有一个关键点--initial-cluster-token的值必须和原来的集群保持一致或者干脆随意指定一个全新值。后者其实更常见因为你在做恢复时通常是想启动一个全新的 etcd 数据实例。但如果你希望恢复后的 etcd 能重新加入原有集群拓扑那就必须保持 peer URL 与集群配置一致否则其他节点会认为这是一个陌生成员。第四步把etcd.yaml和kube-apiserver.yaml移回静态 Pod 目录等待 kubelet 自动拉起 etcd 和 apiservermv /root/backup-manifests/etcd.yaml /etc/kubernetes/manifests/ mv /root/backup-manifests/kube-apiserver.yaml /etc/kubernetes/manifests/ sleep 60最后验证集群状态kubectl get nodes kubectl get pods -A如果看到 Node 状态正常、之前的资源都回来了说明恢复成功。如果 apiserver 启动失败先去看 kubelet 日志和 etcd 日志绝大多数问题出在证书路径不匹配或数据目录权限不对上。3.4 恢复操作中的风险控制与注意事项关于 etcd 恢复我吃过不少亏挑几个最典型的提醒一下。第一恢复操作前必须停止所有写入方。不只是 kube-apiserver如果集群里还有其他组件直接通过 etcd 客户端接口读写数据比如某些定制 Operator也要一并停止。否则很可能出现恢复后一部分旧数据被新数据覆盖或冲突的情况表现为资源状态诡异、对象反复重建。第二不要在生产集群上边跑业务边恢复。即便恢复的是单节点 etcd也强烈建议先摘掉业务流量因为恢复过程中 kubelet 可能会根据旧数据重新创建 Pod造成未知影响。第三etcd 快照不保证包含最近几秒的写入。etcd 的 snapshot 是某一时间点的存储状态自快照时间点之后发生的变更都会丢失。这决定了你的 RPO 不可能为零如果你的业务对数据极其敏感需要在上层做更细粒度的备份或同步。4. Velero 应用级备份与恢复实操etcd 快照能保住控制面但它无法备份 PVC 里的数据。所以当业务真正跑起来之后它用的数据库文件、上传的文件、生成的临时数据全都在 PV 里面这时候必须请出 Velero。4.1 Velero 的核心架构与备份原理Velero 的工作机制可以简单概括为两部分一方面通过 Kubernetes API 读取集群中的资源对象打包后上传到对象存储另一方面通过文件系统备份组件如 restic 或 Kopia读取 PVC 挂载的数据卷内容将其一并上传。它不需要在集群里安装特权 DaemonSet 之外的 agent备份动作由 Velero Server 组件部署在集群内和 Velero CLI 客户端协同完成。CLI 下发备份指令后Velero Server 会在集群中创建 Backup 资源随后 Backup Controller 负责执行具体任务。你在使用过程中会经常看到 Backup、Restore、Schedule、BackupStorageLocation 这几类 CRD它们都是 Velero 的核心抽象。理解它们的层级关系对排查问题很有帮助BackupStorageLocation 定义备份文件存放位置Schedule 定义周期巡检任务Backup 是一次具体备份动作的记录Restore 是一次恢复动作的记录。看日志时只需要找到对应 Backup 或 Restore 资源然后通过velero backup logs name查看详细日志即可。4.2 安装 Velero 并配置对象存储安装 Velero 的工具本身并不复杂核心是把云厂商存储的访问凭证准备好。以 MinIO 为例首先创建一个包含访问密钥的文件cat credentials-velero EOF [default] aws_access_key_id velero_backup aws_secret_access_key YourStrongPass2026 EOF然后执行安装命令velero install \ --provider aws \ --plugins velero/velero-plugin-for-aws:v1.9.0 \ --bucket velero-backup \ --secret-file ./credentials-velero \ --backup-location-config regionminio,s3ForcePathStyletrue,s3Urlhttp://minio.velero.svc.cluster.local:9000 \ --snapshot-location-config regionminio \ --use-restic \ --use-volume-snapshotsfalse \ --wait拆解一下这条命令中几个容易出错的参数--provider aws这里不是说你必须用 AWS而是 Velero 用 AWS S3 兼容协议去对接对象存储MinIO、OSS、COS 都支持这种协议。--plugins velero/velero-plugin-for-aws:v1.9.0插件版本要和 Velero 主版本接近否则可能出现 API 不兼容的问题。s3ForcePathStyletrueMinIO 这类私有对象存储要求路径风格 URL不加这个参数会导致 Velero 无法找到桶。--use-restic启用文件系统备份能力用来备份 PVC 数据。--use-volume-snapshotsfalse如果存储后端没有实现 CSI 快照能力就关掉卷快照功能避免 Velero 一直尝试调用不存在的快照接口。安装完成后查看 velero 命名空间下的 Pod 状态确保velero和restic相关 Pod 都正常运行kubectl get pods -n velero4.3 按命名空间备份先从小范围开始Velero 上手最好的方式不是一上来就全集群备份而是先挑一个测试命名空间做验证。比如我需要备份wordpress命名空间下的所有资源以及 PVC 数据可以执行velero backup create wordpress-backup \ --include-namespaces wordpress \ --default-volumes-to-restic \ --ttl 168h0m0s参数说明--include-namespaces只备份指定命名空间。--default-volumes-to-restic对 PVC 数据启用 restic 备份。--ttl备份文件在对象存储中的保留时间这里设置了 7 天。执行后可能会等待一段时间你可以用velero backup get查看状态从 New 变成 Completed 就说明备份成功了。然后模拟一次灾难直接删掉wordpress命名空间kubectl delete namespace wordpress等命名空间完全清理干净后执行恢复velero restore create --from-backup wordpress-backup恢复完成后进入命名空间检查资源确认 Pod、PVC、Service、Ingress 都回来了。如果 PVC 里的数据文件已经通过 restic 重新灌入新恢复的 PV 中那业务一般能无缝拉起。4.4 整个集群与全量备份策略如果你想把整个集群的所有资源都备份起来需要更加谨慎。我先提醒一句全集群备份并备份 PVC 数据是代价最大的方案耗时和存储成本都不可小觑所以不要动不动就跑全量备份。Velero 默认在velero backup create时如果不加任何筛选参数实际上就已经备份了所有非系统命名空间的资源。但要注意它默认不会备份velero、kube-system、kube-public、kube-node-lease这些系统级命名空间。这样设计是合理的因为这些命名空间里的组件大多可以通过重建或重新安装还原备份它们意义不大。设置了清理系统命名空间后如果需要做“全集群模拟恢复验证”可以用以下命令初始化一个 full backup 作业把白名单和黑名单调整清楚velero backup create full-backup \ --exclude-namespaces kube-system,kube-public,kube-node-lease,velero \ --exclude-resources events,events.events.k8s.io \ --default-volumes-to-restic \ --ttl 336h0m0s排除了 events 的原因是事件数据通常量大且无恢复价值既浪费时间又浪费存储空间。实际需求中你再结合是否要排除一些临时缓存类资源根据业务情况调整。4.5 跨集群迁移Velero 的高阶玩法Velero 备份文件存储在对象存储里这意味着它天然支持跨集群恢复。假如你有 A、B 两个集群对象存储是同一个 MinIO那么在 A 集群做好备份后到 B 集群执行一条恢复命令就能完成资源迁移。我在做环境迁移时常用一套组合拳A 集群创建备份B 集群配置相同的 BackupStorageLocation 和 credentials然后执行恢复。步骤上你先要在 B 集群上安装 Velero使用同样的 MinIO 配置参数velero install \ --provider aws \ --plugins velero/velero-plugin-for-aws:v1.9.0 \ --bucket velero-backup \ --secret-file ./credentials-velero \ --backup-location-config regionminio,s3ForcePathStyletrue,s3Urlhttp://minio.velero.svc.cluster.local:9000 \ --snapshot-location-config regionminio \ --wait然后你要保证 B 集群能够读到一个备份名。执行velero backup get看到 A 集群创建的那个备份名称后直接执行恢复即可。如果目标集群中没有对应的 StorageClass 或不支持同样的存储协议PVC 可能会恢复失败。此时可以通过 Velero 的存储类映射功能在恢复时把源存储类替换为目标集群的存储类。5. 自动化定时备份与恢复演练经验手动备份能保一时备份体系的真正价值在于自动化。一个无法自动运行的备份机制最终一定会被日常工作节奏挤掉。5.1 使用 Velero Schedule 实现定时备份Velero 内置了 Schedule 概念创建它之后Velero 会按照 Cron 表达式周期性地生成新的 Backup。它的最大优点是把备份动作纳入了集群内部状态管理你随时可以通过 CRD 查看备份计划。创建每日全量备份计划保留 7 天命令如下velero schedule create daily-full-backup \ --schedule0 2 * * * \ --include-namespaces wordpress,default \ --default-volumes-to-restic \ --ttl 168h0m0s你可以用velero schedule get查看调度计划状态用velero backup get查看它自动触发的 Backup 是否成功。如果其中一个 Backup 失败了Schedule 会继续保留并不会影响下一次触发。这种解耦设计很实用至少我不会因为一次失败而漏掉后续备份。关于 Cron 表达式我建议结合业务低谷期来设置。如果集群和对象存储都相对空闲凌晨 2 点到 4 点之间跑备份是比较通用的选择。如果备份数据量很大可能单次执行超过 30 分钟你还要注意 Schedule 的时间窗口不能与下一次调度重叠否则会形成备份任务堆积。5.2 对象存储侧的备份生命周期管理备份文件生成之后对象存储侧同样要有生命周期管理规则。MinIO 提供了生命周期配置可以为 bucket 配置过期删除规则所以 Velero 里的--ttl并不是唯一的清理机制。我的建议是两侧都设但以 Velero 的 ttl 为主MinIO 生命周期为辅。假设 Velero 设置了 7 天 TTLMinIO 生命周期规则设置为 10 天过期这样能有效防止因 Velero 控制器异常导致备份文件无限堆积。配置 CapEx 时应考虑到存储成本不要把周期设得太长也不要设得太短。比较稳妥的做法是“本地 7 天 异地副本 30 天”这部分需要根据你公司对数据安全的要求调整。5.3 每季度做一次真实的恢复演练我没见过哪个团队的备份策略是第一次就能做完美的。真正的分水岭在于是否做了恢复演练而且不是演练一次就结束是每季度或半年固定做一次。我自己的做法是准备一个独立的演练集群这个集群规模不需要很大但安装的 K8s 版本和插件配置尽量与生产一致。然后我每个月从对象存储中随机挑一个备份把资源恢复到演练集群再验证几个核心业务是否能正常工作。曾有一次演练暴露过大问题一切资源恢复成功但业务无法启动原因是 Secret 中的密码在源集群里已经轮换过而 ConfigMap 中引用的配置仍旧是旧值。如果没做演练等真实灾难发生时这个问题会变成生产事故的原因。所以我说演练不是额外负担它是备份体系中最有价值的一环。6. 常见故障与排查技巧备份恢复大概率不是一次就能顺利跑通的。我把这两年遇到的高频问题整理成了一张速查表供你定位问题。症状可能原因解决方案etcdctl snapshot save 报证书错误未正确加载 ETCDCTL_CERT / ETCDCTL_KEY 环境变量重新 source 环境变量文件检查证书路径etcd snapshot restore 后 apiserver 起不来数据目录权限不对或新旧集群 token 不一致确认/var/lib/etcd属主为 etcd 用户检查 apiserver 日志Velero backup 状态一直停留在 NewBackupStorageLocation 无效或插件版本不匹配查看 velero 日志检查存储桶是否可访问Velero 备份完成但恢复后 PVC 为空没有启用 restic / 卷快照被显式关闭恢复动作加上--default-volumes-to-restic并确认 restic Pod 运行恢复时提示 storageclass 不存在目标集群缺少源集群的 StorageClass创建同名 StorageClass或用--storage-class-mapping参数做替换定时备份连续失败但你完全没发现缺少失败告警机制为 Velero 配置监控告警或检查日志工具备份文件在 MinIO 中被误删bucket 没有开启版本控制开启 bucket 版本控制并配置生命周期规则除了表格里的问题我再补充三个比较隐秘但很重要的经验。第一Velero 备份过程中如果集群正在发生大量资源变更可能出现部分资源处于中间状态导致恢复回来后资源版本冲突或字段不完整。对于核心数据库这类服务我建议备份前先将应用置于只读或停写状态至少也要接受 PVC 数据本身的一致性由应用层保证。第二restic 备份模式对 PVC 数据的备份速度较慢。如果 PVC 体积达到 TB 级别全量备份耗时可能数小时。这时候需要考虑文件系统层面的定期快照比如云厂商磁盘快照或数据库自身备份工具而不是一味依赖 Velero 的每个卷备份。第三恢复时注意资源间的依赖顺序。Velero 会尽力做依赖排序但有些自定义资源需要先创建 CRD再创建 CRD 实例。如果恢复后自定义资源没有正常出现优先检查 CRD 是否已经注册必要时手动应用 CRD 定义。还有一个小技巧恢复前把目标集群的命名空间先清空或者使用一个新的命名空间做恢复验证避免与现有资源产生冲突。这个操作能帮你把问题边界缩小少在环境干扰上浪费时间。说一个我印象最深的教训。某次我把 etcd 快照恢复做完了节点全部 ReadyPod 也全部 Running表面上一切完美。结果第二天业务反馈数据缺失一查发现备份时间点在业务高峰期前一小时随后一小时内的写入全部丢掉了。从此以后我在设计备份策略时都会先问一句业务能否接受这个 RPO如果能承受小时级丢失则每日备份足够如果不能那就需要借助数据库层的 binlog 同步或存储层的实时快照来缩短丢失窗口。备份恢复这件事看起来只是几条命令但真正把它做扎实需要你对集群的部署形态、业务的数据特性、存储后端的接口能力都有清晰认知。希望这篇基于配置与实践的梳理能让你在构建自己的备份方案时少走一些弯路。下一次遇到故障时希望你想到的不是后悔没备份而是从容地执行演练过无数遍的恢复流程。
返回列表