Kubernetes 集群看似稳定,但一次误删 Namespace、一次 Helm 升级失败,甚至一次 AWS 区域级故障,都可能让整个业务瘫痪。Velero 作为 CNCF 毕业项目,专门解决集群备份、恢复和迁移问题。它通过将集群资源清单上传到对象存储,结合云厂商的快照机制处理持久卷数据,实现了应用级别的整体备份。本文以 EKS 为例,从零开始完整走一遍备份与恢复流程。

一、准备工作:S3 存储桶与 IAM 权限配置
Velero 的备份原理是把集群资源的 YAML 清单打包上传到 S3,同时在需要时调用 AWS EBS 的快照接口对持久卷做快照。所以第一步要创建一个 S3 存储桶,并给 Velero 配置足够的 IAM 权限。存储桶建议与 EKS 集群放在同一个区域,这样快照操作不需要跨区授权,速度也更快。
创建存储桶很简单,使用 aws cli 一条命令即可。假设集群在 cn-north-1 区域:
aws s3api create-bucket \
--bucket velero-backup-demo-eks \
--region cn-north-1 \
--create-bucket-configuration LocationConstraint=cn-north-1
接下来是 IAM 权限部分。官方推荐使用服务账号的 IRSA 方式(IAM Roles for Service Accounts),也就是让 Velero 的 Pod 通过 EKS 的 OIDC 提供商扮演特定角色,这种方式比把 AK/SK 写进 Secret 安全得多。先下载官方提供的权限策略文件并创建策略:
curl -s https://raw.githubusercontent.com/vmware-tanzu/velero/main/examples/iam-policy-aws.json -o iam-policy.json
aws iam create-policy \
--policy-name velero-policy \
--policy-document file://iam-policy.json
策略中包含了 ec2 的快照操作权限、s3 的读写权限以及必要的检查权限。创建好策略后,需要确认 EKS 集群已经启用了 OIDC Provider,然后创建信任角色并把策略绑定上去。这一步如果嫌手动操作繁琐,可以用 eksctl 直接创建服务账号,命令会在创建角色的同时自动完成信任关系绑定:
eksctl create iamserviceaccount \
--cluster my-eks-cluster \
--name velero \
--namespace velero \
--attach-policy-arn arn:aws-cn:iam::123456789012:policy/velero-policy \
--approve
需要注意,中国区账号要把 arn 中的 aws 换成 aws-cn,这是很多人第一次配置时最容易踩的坑,权限配了半天却一直报 AccessDenied,多半是这个问题。
二、安装 Velero 并验证运行状态
安装推荐使用 Helm,版本管理和后续升级都更方便。先添加官方仓库:
helm repo add vmware-tanzu https://vmware-tanzu.github.io/helm-charts helm repo update
然后编写 values 配置文件,核心是指定 S3 存储桶信息和快照插件:
configuration:
backupStorageLocation:
name: aws
provider: aws
bucket: velero-backup-demo-eks
config:
region: cn-north-1
volumeSnapshotLocation:
name: aws
provider: aws
config:
region: cn-north-1
credentials:
existingSecret: false
serviceAccount:
server:
create: false
name: velero
initContainers:
- name: velero-plugin-for-aws
image: velero/velero-plugin-for-aws:v1.9.0
volumeMounts:
- mountPath: /target
name: plugins
这里有一个关键点:因为我们用 IRSA 方式,serviceAccount 要复用之前 eksctl 创建的那个,所以 create 设为 false。如果选择传统的 AK/SK 方式,则需要先创建一个包含 credentials 文件的 Secret,内容大致是 [default] 加上 aws_access_key_id 和 aws_secret_access_key 两行,然后在 Helm 安装时通过参数传入。两种方式都可以,但生产环境强烈建议 IRSA,避免密钥泄漏风险。
执行安装:
kubectl create namespace velero
helm install velero vmware-tanzu/velero \
--namespace velero \
-f values.yaml
安装完成后不要急着做备份,先用两条命令验证状态。检查 Pod 是否全部 Running,再确认存储位置是否可用:
kubectl get pods -n velero velero backup-location get
如果 backup-location 显示 AVAILABLE,说明 S3 权限验证通过。反之如果显示 Unavailable,用 kubectl logs 查看 velero Pod 日志,通常会明确提示是权限问题还是网络问题。中国区环境还有一个常见情况是 Pod 无法访问 S3 域名,需要检查子网的路由表和安全组配置。
三、执行备份:集群资源与持久卷数据
Velero 的备份分为两部分:资源清单备份和卷数据备份。资源清单备份默认覆盖集群内几乎所有命名空间,卷数据则通过两种方式处理,一是 CSI 快照,二是基于 restic 或 Kopia 的文件级复制。对于 EBS 卷,CSI 快照方式效率最高,秒级完成且增量存储成本更低。
先做一次手动全量备份,命名规范建议带上日期和说明:
velero backup create demo-backup-20240610 \
--include-namespaces my-app \
--snapshot-volumes \
--snapshot-move-data false
备份完成后用 velero backup describe demo-backup-20240610 --details 查看详情,重点确认两列信息:资源数量是否符合预期,以及快照是否创建成功。如果 Pod 挂载的是通过 CSI 驱动创建的 PVC,快照记录会出现在 Volume Snapshots 部分。对于一些特殊场景,比如数据库这类对一致性要求高的应用,建议在备份前通过 BackupHook 执行 FLUSH TABLES WITH READ LOCK 之类的操作,保证数据落盘后再做快照。
生产环境更重要的是定时备份策略。Velero 内置了 Schedule 机制,表达式和 Linux crontab 一致:
velero schedule create daily-backup \
--schedule="0 2 * * *" \
--include-namespaces my-app \
--snapshot-volumes \
--ttl 720h
这条命令表示每天凌晨两点执行备份,保留最近 30 天。TTL 参数一定要设置,否则备份会无限累积,S3 和快照的费用会悄悄涨上去。另外建议给 S3 存储桶开启生命周期规则,把超过一定时间的对象转入低频存储,进一步压缩成本。
四、灾难恢复:把备份还原到新集群
备份的价值只有通过恢复演练才能验证。模拟一次灾难场景:假设原集群的 my-app 命名空间被误删,需要完整找回。
恢复前先确认备份对象存在且状态为 Completed,然后在目标集群执行:
velero restore create --from-backup demo-backup-20240610
Velero 会按依赖顺序重建资源,先创建 Namespace 和 PVC,再恢复 Pod、Service、Ingress 等。默认策略是不覆盖已存在的资源,可以通过 --existing-resource-policy update 改为更新模式。对于持久卷数据,恢复时会基于快照创建新的 EBS 卷,如果原集群使用的是 gp2 存储,新卷默认会恢复为 gp3,这是 AWS CSI 驱动的默认行为,一般不影响使用。
如果是跨集群迁移场景,比如把业务从一个 EKS 集群迁到另一个区域的集群,流程基本一致:新集群安装好 Velero 并指向同一个 S3 存储桶,执行 velero backup-location get 同步备份元数据后即可恢复。跨区域恢复需要注意 EBS 快照无法直接跨区挂载,要么在恢复时改用文件级备份方式,要么提前用快照复制功能把快照同步到目标区域。
最后提醒一点,备份策略没有经过恢复验证之前等于没有。建议每季度做一次完整的恢复演练,在独立的测试集群中跑通全流程,同时记录恢复耗时,这个数据在制定 RTO 目标时非常关键。只有演练通过的方案,才能真正在事故发生时救你一命。
Velero备份恢复EKS集群Kubernetes灾难恢复修改时间:2026-09-10 13:38:41