velero —— K8s 集群备份恢复
一句话定义
velero 是 K8s 备份恢复的事实标准:把集群里的 K8s 资源(Deployment / Service / ConfigMap / Secret)和 PV 数据备份到对象存储(S3 / GCS / 阿里 OSS)、灾难时一键 restore。
典型场景
- 升级集群前:
velero backup create pre-upgrade - 定期备份:
velero schedule create daily --schedule="0 2 * * *" - 跨集群迁移:A 集群 backup → B 集群 restore
- 灾难恢复:节点丢、PV 在、kubeadm + velero restore
- 不要用 velero 备份 etcd —— 那是 etcdctl 的活
velero 不是 etcd 备份。velero 走 apiserver API、做"K8s 对象级"备份。两者都需要,不互相替代。
velero vs etcdctl snapshot
| velero | etcdctl snapshot | |
|---|---|---|
| 粒度 | 单 namespace / 资源 / app | 整个集群(全 etcd) |
| 跨集群 | ✅(A → B 集群) | ❌(绑定 cluster ID) |
| PV 数据 | ✅(含 snapshot 或 file-level) | ❌ |
| 恢复体验 | 选择性 restore | 整个 etcd 还原 |
| 依赖 | 对象存储 + CSI / Restic | 本地 / 远端文件 |
| 适用 | 应用级备份、迁移、回滚 | 控制面级 DR |
生产两个都要——etcdctl 救集群、velero 救应用。
装
velero 是 CLI + 集群里的 controller。先装 CLI:
# Linux
curl -L https://github.com/vmware-tanzu/velero/releases/latest/download/velero-v1.13.0-linux-amd64.tar.gz \
| tar xz
mv velero-*/velero /usr/local/bin/
# macOS
brew install velero
再装集群 controller(以 AWS S3 为例):
velero install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.9.0 \
--bucket my-velero-backups \
--backup-location-config region=us-west-2 \
--snapshot-location-config region=us-west-2 \
--secret-file ./credentials-velero
credentials-velero 文件:
[default]
aws_access_key_id=...
aws_secret_access_key=...
集群内会创建 velero namespace、deployment、CRD、backup storage location 等。
看 velero 健康
kubectl get pods -n velero
# velero-xxx Running
velero backup-location get
# NAME PROVIDER BUCKET ACCESS MODE DEFAULT
# default aws my-velero-backups ReadWrite true
velero snapshot-location get
backup-location Available = 后端存储连通。Unavailable 要查 secret / 网络。
创建备份
# 全集群备份(除了 velero ns)
velero backup create my-backup
# 单 namespace
velero backup create app-backup --include-namespaces my-app
# 多 namespace
velero backup create app-backup --include-namespaces my-app,my-app-config
# 按 label
velero backup create app-backup --selector app=nginx
# 排除某些
velero backup create my-backup --exclude-resources events,pods
# 不备份 PV 数据(只备份 K8s 对象)
velero backup create my-backup --snapshot-volumes=false
看备份状态
velero backup get
# NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION ...
# my-backup Completed 0 0 5min ago 29d default
velero backup describe my-backup --details # 详情
velero backup logs my-backup # 备份过程日志
Status 字段:
Completed—— 成功Failed—— 失败(看 logs)PartiallyFailed—— 部分失败(某些资源没备份成功)InProgress—— 进行中
定时备份:schedule
# 每天凌晨 2 点
velero schedule create daily --schedule="0 2 * * *"
# 复杂:每小时备份 app ns、保留 24 小时
velero schedule create hourly-app \
--schedule="0 * * * *" \
--include-namespaces my-app \
--ttl 24h0m0s
velero schedule get
velero schedule pause daily # 暂停
velero schedule unpause daily # 恢复
velero schedule delete daily
每个 schedule 触发就生成一个 backup。
恢复
# 列可用备份
velero backup get
# 全恢复
velero restore create --from-backup my-backup
# 只恢复某 ns
velero restore create --from-backup my-backup --include-namespaces my-app
# 改 namespace 恢复(迁移用)
velero restore create --from-backup my-backup \
--namespace-mappings my-app:my-app-restored
# 只恢复某种资源
velero restore create --from-backup my-backup --include-resources deployments,services
看 restore 状态
velero restore get
velero restore describe my-restore-xxx --details
velero restore logs my-restore-xxx
PV 数据备份:CSI snapshot vs Restic vs Kopia
velero 备份 PV 数据有三种模式:
| 模式 | 用途 | 速度 | 跨集群 |
|---|---|---|---|
| CSI snapshot | 云盘原生 snapshot(AWS EBS、GCE PD) | 快 | 限同云 |
| Restic | 文件级(pod 内 mount 拷贝),通用 | 慢 | ✅ 任意 |
| Kopia | Restic 的现代替代 | 中等 | ✅ 任意 |
启用 CSI snapshot(K8s 1.20+ 推荐)
velero install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.9.0,velero/velero-plugin-for-csi:v0.7.0 \
--features=EnableCSI \
...
Backup 时 velero 调用 VolumeSnapshot CRD 让 CSI driver 做 snapshot。云原生,最快。
启用 Restic / Kopia(自建集群 / 跨厂商)
velero install \
--use-node-agent \
--uploader-type=kopia \ # 或 restic
...
需要 pod 加 annotation 才会备份 volume:
metadata:
annotations:
backup.velero.io/backup-volumes: data-volume
实战:升级集群前完整备份
# 1. 备份(含 PV)
velero backup create pre-upgrade-$(date +%F) \
--include-namespaces=default,my-app,monitoring \
--snapshot-volumes \
--wait
# 2. 验证
velero backup describe pre-upgrade-$(date +%F) --details
velero backup logs pre-upgrade-$(date +%F)
# 3. 升级 K8s(用 kubeadm 等)
# 失败 → 用下面回滚
# 4. 紧急 restore
velero restore create --from-backup pre-upgrade-$(date +%F)
实战:跨集群迁移
源集群备份:
# 用同一个 S3 bucket,新集群也能读
velero backup create migration-snapshot --include-namespaces my-app
新集群安装 velero、指向同一个 S3 bucket:
velero install \
--provider aws \
--plugins ... \
--bucket my-velero-backups \ # 同一个
...
让 velero 知道这个 backup 存在:
velero backup get # 应该看到 migration-snapshot
restore:
velero restore create --from-backup migration-snapshot
命令速查
# 备份
velero backup create <name> [flags]
velero backup get
velero backup describe <name> [--details]
velero backup logs <name>
velero backup delete <name>
velero backup download <name> # 下载备份归档到本地
# 定时
velero schedule create <name> --schedule="..." [flags]
velero schedule get / pause / unpause / delete
# 恢复
velero restore create [--from-backup <name>] [flags]
velero restore get / describe / logs / delete
# 存储位置
velero backup-location get / set <name>
velero snapshot-location get
# 集群信息
velero version
velero plugin get
# 日志
kubectl logs deploy/velero -n velero
kubectl logs -l name=node-agent -n velero # restic / kopia pod
常见踩坑
坑 1:备份 PV 但没启用 snapshot
velero backup create my-backup
# 备份完了,恢复时发现 PV 数据丢了
默认 --snapshot-volumes=true,但:
- 没装 CSI snapshot 插件、底层不支持 → 实际不 snapshot
- 没装 Restic / Kopia node-agent → 不能拷贝文件级
确认:
velero backup describe my-backup --details | grep -A 5 "Volume Snapshots"
如果显示 0 of 0 snapshots completed successfully —— 没真备份 PV。
坑 2:S3 / OSS 权限不够
velero backup get
# 列表为空,但你之前明明创建过
后端 secret 错 / IAM 权限不够。看 velero pod 日志:
kubectl logs deploy/velero -n velero | grep -i error
# AccessDenied / NoSuchBucket / ...
坑 3:恢复出来的 ConfigMap / Secret 是旧的
velero restore create --from-backup last-week-backup
# 恢复后 K8s 里某些 ConfigMap 不在
velero 默认不覆盖已存在资源——只创建不存在的。如果你要"全替换":
velero restore create --from-backup last-week --existing-resource-policy update
# K8s 1.20+ 支持
坑 4:restore 卡 InProgress 几小时
velero restore get
# my-restore InProgress ...
Restic / Kopia 拷文件慢。大 PV 数据 GB 级别的恢复就是慢。
监控:
kubectl logs -l name=node-agent -n velero --tail=100 -f
进度。
坑 5:备份了 Pod 但没用
Pod 是临时资源,备份它意义不大(它属于 Deployment / StatefulSet)。
排除:
velero backup create my-backup --exclude-resources pods,replicasets,events
更精简的备份。
坑 6:restore 后 service 不通
kubectl get pods -n my-app # Running
kubectl get svc -n my-app # 在
# 但访问失败
可能:
- Service ClusterIP 变了(被新分配) → DNS 缓存指向旧 IP
- LoadBalancer 服务的 IP 没保留
通常等几分钟自然好。也可以删 service 让 controller 重新创建:
kubectl delete svc my-svc -n my-app # 然后 velero 没事,apiserver 重建
坑 7:在 velero 卸载之前要清干净 CRD
helm uninstall velero -n velero
# 一些 backup / restore CRD 留着,下次 install 出错
清干净:
kubectl delete crd -l app.kubernetes.io/name=velero
kubectl delete ns velero
坑 8:定时备份累积太多
velero backup get | wc -l
# 1000 个,S3 也涨大
默认 schedule 不删旧备份。设 TTL:
velero schedule create daily --schedule="0 2 * * *" --ttl 720h # 30 天
或者手动清:
velero backup delete --selector "velero.io/schedule-name=daily" --confirm
坑 9:node-agent pod 不调度
kubectl get pods -n velero -l name=node-agent
# 只有 2/5(5 个节点)
某些节点有 taint,node-agent DaemonSet 没容忍。
加 tolerations:
kubectl edit ds node-agent -n velero
# spec.template.spec.tolerations 加
或者重装 velero 时加 --node-agent-tolerations。