Kubernetes 运维管理Velero工作机制和工具安装
Velero 对 Kubernetes 集群备份还原和迁移
Velero 简介
Velero介绍
Velero (西班牙语,意思是“帆船)最初由 Heptio 公司开发,项目名称为 “Heptio Ark”。
Heptio 由 Kubernetes 的两位联合创始人 Craig McLuckie 和 Joe Beda 创立,旨在为 Kubernetes 用户
提供一系列可靠的工具来增强集群的管理、运维能力。
Ark 项目应运而生,其核心目标就是解决 Kubernetes 集群的备份和恢复这一关键需求,当时市场上缺
乏功能完善且易于使用的针对 Kubernetes 的此类工具。
Heptio 在 2017 年将 Ark 开源发布,开源之后,吸引了大量 Kubernetes 用户以及开发者的关注。许多
企业和开发者开始尝试使用 Ark 来保障自身集群内应用及数据的安全性,同时也积极向项目贡献代码、
反馈使用过程中遇到的问题以及提出新的功能需求,社区围绕 Ark 开始逐渐活跃起来,不断推动其功能
的完善和对更多存储、云平台环境等的适配。
2018 年,随着 Heptio 被 VMware 收购,Ark 项目为了更好地体现其通用性以及适应更广泛的社区发展
需要,被重命名为 “Velero”。后由 VMware Tanzu 对其进行维护和开发, 并于 2018 年捐赠给 CNCF,
成为 CNCF 的孵化项目之一
发展至今,Velero 已经成为 Kubernetes 云原生生态中不可或缺的一部分,众多企业将其作为保障集群
业务连续性、进行数据保护和应用迁移的重要手段。其社区仍然保持着较高的活跃度,不断有开发者贡
献新的功能特性、改进文档,而且与其他云原生相关项目之间也有着紧密的协作关系,一起助力云原生
应用在 Kubernetes 平台上更安全、稳定地运行。
Velero是一个云原生的灾难恢复和迁移工具,它本身也是开源的, 采用 Go 语言编写,可以安全的备份、
恢复和迁移Kubernetes集群资源和持久卷。
特点
- 备份可以按集群资源的子集,按命名空间、资源类型标签选择器进行过滤,从而为备份和恢复的内容提供高度的灵活性
- 支持复制当前 Kubernetes 集群的资源到其它 Kubernetes 集群,注意:只备份kubernetes中的元数据,不会备份PVC等数据内容
- 通过聚合 API 服务器(公开的资源可以轻松备份和恢复,即使它们存储在单独的 etcd 数据库中
- 要求kubernetes集群在正常工作的情况下才能实现备份和还原
官网: https://velero.io/
Github 地址:https://github.com/vmware-tanzu/velero
官方文档:https://velero.io/docs/
Velero 主要功能
备份功能
集群资源备份:能够备份 Kubernetes 集群中的各种资源对象,包括 Deployment、Service、ConfigMap、Secret、PersistentVolumeClaims 等几乎所有常见资源类型。例如,可以定期备份
重要的应用部署配置以及相关的服务定义等,方便在需要时进行还原。
持久卷数据备份:除了资源对象本身,Velero 还支持对与应用相关联的持久卷(PersistentVolumes)中的数据进行备份。这对于保存有重要业务数据(如数据库文件、用户上传文件等)的
应用来说至关重要,确保数据不会因意外删除、集群故障等情况丢失。
可基于文件系统备份(FileSystem Backup)备份Pod卷中的数据,并借助于restc或kopia上传到对象存储系统
支持基于快照备份PV,这种方式较之FSB能确保文件的一致性;它支持两种操作: 1 仅创建PV快照,2创建PV快照,并借助于restic或kopia上传到对象存储系统上
恢复功能
- 资源还原:可以将之前备份的资源对象按照备份时的状态准确地还原到集群中,无论是因为误操作删除了某个关键服务,还是集群整体出现故障重建后,都能快速恢复应用部署和配置。
- 数据恢复:与资源还原配合,能把持久卷中的数据也恢复到相应的存储位置,使整个应用恢复到备份时刻的可用状态,保障业务的连续性。
灾难恢复与迁移支持
跨集群迁移:方便将应用及数据从一个 Kubernetes 集群迁移到另一个集群,比如从测试环境集群迁移到生产环境集群,或者在进行数据中心迁移、云平台更换等场景下,实现平滑的资源和数据转
移。
灾难恢复预案:作为灾难恢复计划的关键部分,通过定期备份,在遇到如集群硬件故障、数据中心灾难等极端情况时,能快速依据备份在新的环境中恢复集群的关键业务应用,最大限度减少业务停
机时间和损失
Velero 使用场景
灾备场景:
提供备份和恢复kubernetes集群的能力
Velero 只做「集群级灾备」,意思是:
Velero 负责“Kubernetes 集群本身能不能恢复”, 而不是“业务数据在任何情况下都 100% 正确”。
Velero 负责恢复 Kubernetes 世界, 但不对业务数据的逻辑正确性兜底
Velero 只保证 Pod 能跑起来, 数据库备份才能保证数据是对的
迁移场景:
提供复制和迁移集群资源到其他集群的能力,可用于快速实现开发,测试,生产等不同集群配置同步
需要将两个集群连接同一个对象存储服务
什么叫「集群级灾备」?
Velero 擅长备份的东西(平台层)
Velero 备份的是:
1)Kubernetes 资源对象(YAML)
Namespace
Deployment / StatefulSet
Service / Ingress
ConfigMap / Secret
PV / PVC 定义
2)卷里的文件(通过 Node Agent)
PVC
NFS
local PV(有前提)
👉 目标是:“集群没了,我能不能快速拉起一个一模一样的集群”
Velero 不保证的东西(应用层)
Velero 不保证:
MySQL / Redis / ES 在备份瞬间的数据一致性
事务是否刚好写了一半
binlog / redo log 是否完整
crash recovery 是否一定成功
因为:Velero 做的是 文件级快照,并不知道数据库内部状态
案例
1)场景:K8s 集群整个挂了
etcd 损坏
master 节点磁盘炸了
误删 namespace
2)用 Velero 恢复后,你能得到什么?
✔ Namespace 回来了
✔ Deployment / Pod 全回来了
✔ PVC / PV 结构回来了
✔ NFS / local PV 里的文件也回来了
✔ MySQL Pod 能启动
👉 集群“形态”完全恢复
3)但 Velero 不保证什么?
❌ MySQL 数据一定 100% 正确
❌ 不一定是某个时间点的一致快照
❌ 有概率需要 MySQL crash recovery
❌ 极端情况下数据损坏
这就是:“集群级 OK,业务级不兜底”
Velero 与 ETCD 备份比较
- ETCD 备份是直接把集群的全部资源备份,而 Velero 可以支持对 Kubernetes 集群内对象级别进行备份。
- Velero 除了对 Kubernetes 集群进行整体备份外, 还可以支持对 Namespace、Type、Label、Pod 等对象进行分类备份或者恢复
- ETCD方式是直接对ETCD的数据库备份,无需连接API Server, 而 velero是通过API Server 进行备份,要求Kubernetes 是可用的才可以备份和还原
- Velero 自身支持实现周期的定期备份,ETCD需要自行通过其它方式实现
- Velero 还支持将PV卷的数据进行备份,ETCD方式只能备份Kubernetes 集群的资源
Velero 组件
Velero 组件一共分三部分,分别是客户端和服务端,插件。
客户端:
运行在本地的 velero 命令行工具,包括安装服务端、备份、定时任务备份、恢复等命令,特别需要注意的是,安装服务端时需要在机器上已配置好kubectl及集群kubeconfig。
服务端:
就是一组运行在Kubernetes集群中(以Pod方式运行)controller 资源
通过一组 CRD 实现的 Operator,包括: Backup Controller 和 Restore Contoller
这是整个工具的核心控制组件,负责与 Kubernetes API 服务器通信,协调备份和恢复任务的执
行,管理备份记录等,同时也会和各种插件交互来完成具体的功能,比如和存储插件协作进行数据
的存储和读取操作。
插件(Plugins)
https://velero.io/docs/main/supported-providers/
存储插件:用于对接不同的存储后端,支持多种存储类型,像 Amazon S3、Google CloudStorage、Azure Blob Storage、MinIO等云存储服务,以及一些本地的兼容 S3 协议的存储系
统,如MinIO,实现备份数据的可靠存储和获取。
卷快照插件:针对不同的存储提供商(如不同云平台对持久卷的管理机制不同),卷快照插件
能够与相应的存储系统集成,实现对持久卷数据的快照创建和恢复,提高备份和恢复的效率,
尤其是对于大容量数据的处理。
Velero 后端存储
Velero 支持两种关于后端存储的 CRD ,分别是 BackupStorageLocation 和VolumeSnapshotLocation 。
BackupStorageLocation
主要用来定义 Kubernetes 集群资源的数据存放位置,也就是集群对象数据,不是 PVC 的数据。
主要支持的后端存储是 S3 兼容的存储,比如:MinIO,阿里云 OSS,AWS S3,Azure Blob,Google
Cloud 等。
VolumeSnapshotLocation
主要用来给 PV 做快照,这个需要使用 CSI 等存储机制。
如果是公有云需要云提供商提供插件。比如: 阿里云已经提供了插件,
也可以使用专门的备份工具 Restic ,把 PV 数据备份到阿里云 OSS 中去(安装时需要自定义选项)
Restic 是一款 GO 语言开发的数据加密备份工具,可以将本地数据加密后传输到指定的仓库。支
持的仓库有 Local、SFTP、Aws S3、Minio、OpenStack Swift、Backblaze B2、Azure BS、
Google Cloud storage、Rest Server。
Velero 备份还原的工作流程


备份数据:
本地velero客户端发送备份命令,就会调用API Server创建Backup资源对象
服务端的Backup Controller 收到通知有新的Backup对象创建并执行验证
服务端的Backup Controller 开始执行备份过程,向API Server查询需要备份的数据
服务端的Backup Controller 调用OSS对象存储服务,将备份数据保存到对象对象存储上
默认情况下,BackupController还会为PV创建Snapshot(若PV支持),用户可使用 --snapshotvolumes=false 选项禁用该功能
Velero 会与 Kubernetes API 服务器交互,首先获取要备份的资源对象的清单信息,然后根据配置
决定是否对关联的持久卷数据进行备份(通过调用相应的存储插件来操作)。对于持久卷数据备
份,它会协调存储系统(如支持的云存储服务或本地存储解决方案)创建数据的快照或者复制数据
到指定的备份存储位置。整个备份过程中会生成相应的备份记录,记录备份的资源范围、时间、状
态等关键信息。
恢复数据:
本地velero客户端发送恢复指令,就会调用API Server创建Restore资源对象
服务端的Restore Controller 收到通知有新的Restore对象创建并执行验证
服务端的Restore Controller 调用对象存储,将指定的备份文件下载下来
服务端的Restore Controller 开始执行恢复过程,根据备份数据调用API Server重新创建相关资源对象
当执行恢复操作时,Velero 读取备份记录,先将资源对象的定义重新应用到 Kubernetes 集群中,
创建相应的资源(如重新创建 Deployment 来启动应用副本等)。对于有持久卷数据需要恢复的情
况,它会从备份存储位置获取数据并还原到对应的持久卷中,确保应用能够正常使用之前的数据。

Velero 官方支持存储矩阵
Velero 的真实支持情况是:
存储类型 备份 还原
PVC(NFS / 云盘) ✅ ✅
local PV ✅ ⚠(同节点)
hostPath ✅ ❌(不保证)
emptyDir ❌ ❌
安装和使用 Velero Cli
Velero CLI 二进制安装
软件包下载地址
https://github.com/vmware-tanzu/velero/releases
范例: 二进制安装 Velero CLI
#在K8s集群的Master节点上安装velero CLI
VERSION=v1.18.1
#直接下载
wget https://github.com/vmwaretanzu/velero/releases/download/${VERSION}/velero-${VERSION}-linux-amd64.tar.gz
#如果下载失败,可以通过代理如下
wget https://githubfast.com/vmwaretanzu/velero/releases/download/${VERSION}/velero-${VERSION}-linux-amd64.tar.gz
tar -zxvf velero-${VERSION}-linux-amd64.tar.gz
tree velero-${VERSION}-linux-amd64
mv velero-${VERSION}-linux-amd64/velero /usr/local/bin/
velero version
Velero CLI 集成 MinIO 存储
Velero支持很多种存储插件,可查看:https://velero.io/docs/main/supported-providers/获取插件信
息
此处使用minio作为S3兼容的对象存储提供程序。您也可以在任意地方部署Minio对象存储,只需要保证
K8S集群可以访问到即可。
容器化部署单机单磁盘
范例: Docker 容器化部署单机单磁盘
#docker部署
192.168.3.65 机器用docker部署minio
docker run -d \
-p 9000:9000 \
-p 9090:9090 \
--name minio \
--restart always \
-v /data/minio:/data \
-e "MINIO_ROOT_USER=admin" \
-e "MINIO_ROOT_PASSWORD=12345678" \
registry.cn-beijing.aliyuncs.com/wangxiaochun/minio:RELEASE.2025-04-22T22-12-26Z server /data --console-address ":9090"
#使用admin/12345678 登录MinIO 的 Console
http://minio.ming.org:9090

创建 bucket
使用admin/12345678 登录MinIO 的 Console

创建一个bucket名为: velero


创建Access Key并配置权限
创建并记录 Access Key 和 Secret key
#Access Key
y81QoEEcmV06Zc18e2Fp
#Secret key
8VdbRxsgG7Or5yk7f5FXHjs87dOMhjuPmNK8s2cs

配置 CLI 访问 MinIO 认证密钥
#在K8s集群的Master节点上MinIO的创建认证文件
cat > credentials-velero <<EOF
[default]
#aws_access_key_id = admin
#aws_secret_access_key = 12345678
aws_access_key_id = y81QoEEcmV06Zc18e2Fp
aws_secret_access_key = 8VdbRxsgG7Or5yk7f5FXHjs87dOMhjuPmNK8s2cs
EOF
安装 Velero Server
velero install 安装
velero install 命令用于在 Kubernetes 集群中安装 Velero,它有多个选项可用来定制化安装过程
安装 Velero Server
范例: 安装 Velero Server
#示例1: 支持资源和数据以文件方式备份,但不支持快照备份
velero install \
--provider aws \
--image registry.cn-beijing.aliyuncs.com/wangxiaochun/velero:v1.15.0 \
--plugins registry.cn-beijing.aliyuncs.com/wangxiaochun/velero-plugin-for-aws:v1.11.0 \
--backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://192.168.3.65:9000 \
--bucket velero \
--secret-file ./credentials-velero \
--namespace velero \
--use-node-agent \
--use-volume-snapshots=false \
--wait
#选项说明 --provider aws #指定云服务提供商为 AWS。尽管这里用的是aws,但 Velero 支持通过插件机制与其他存储系统(如 MinIO)兼容。此选项告诉 Velero 使用 AWS 兼容的存储接口。 --backup-location-config #配置备份存储位置的参数,以逗号分隔的键值对形式提供。具体参数如下: region=minio #指定存储区域名称。对于 MinIO,此值可以是任意字符串(如minio),因为 MinIO 不使用传统的 AWS 区域概念。 s3ForcePathStyle="true" #强制使用路径风格的 S3 URL。路径风格的 URL 格式为http://<host>/<bucket>/<key>,而不是虚拟主机风格的http://<bucket>.<host>/<key>。MinIO 要求启用此选项。 s3Url=http://minio.ming.org:9000 #指定 MinIO 服务器的 URL。Velero 将通过此 URL 连接到 MinIO 服务,端口9000是 MinIO 的默认 API 端口。minio.ming.org需要coreDNS解析,
不能用hosts文件解析
-secret-file
用途:指定包含访问存储资源(比如存储桶等)所需的认证凭据等敏感信息的文件。这个文件内容一般是以加密或者符合安全规范的形式存储的,确保 Velero 在与存储后端交互时能够进行身份验
证并获得相应权限。
示例:指向了存储在 /root/credentials-velero 这个路径下的包含认证信息的文件
--secret-file ./credentials-velero
--provider
用途:指明 Velero 所运行的底层基础设施提供商(如云平台等),这有助于 Velero 根据对应平台
特性来进行适配性安装,比如针对 AWS、Azure、GCP 等不同平台,启用相应的特定功能模块或配
置不同的资源访问方式。
示例:告知 Velero 是运行在 AWS 环境下,后续的安装流程就会按照 AWS 相关的规范和接口来配
置组件以及资源访问等事项。
--provider=aws
--namespace
用途:定义 Velero 组件将会被安装到的 Kubernetes 命名空间。默认情况下,通常安装到
velero 命名空间
示例:会把 Velero 相关组件安装到名为 velero 的命名空间内。
--namespace=velero
--use-node-agent
用途:启用 Velero 的 Node Agent 组件,该组件以 DaemonSet 形式部署在每个节点上。默认值为不启用此功能,即不会创建daemonset
--use-node-agent` 用于在每个 Kubernetes 节点上部署 Node Agent(Restic)组件,实现对PVC/PV 数据的文件级备份。这个选项在私有云或不支持原生 VolumeSnapshot 的环境中尤为重要。
Node Agent 是唯一能备份以下类型存储的方式:
- 普通 PVC(文件系统)
- hostPath
本地盘(local PV)
- NFS / CephFS / GlusterFS 等文件系统
注意: Velero 不会备份 emptyDir 的数据,原因:emptyDir 是 临时缓存,不具备“备份价值”,官方明确不支持
作用:
- 支持对 PVC(Persistent Volume Claim)数据的文件级备份,而非仅备份卷快照。
- 在备份和恢复过程中执行自定义操作(如在 Pod 暂停状态下执行备份)。
适用场景:
- 需要备份无法通过卷快照捕获的临时文件或内存数据。
- 使用不支持卷快照的存储后端(如 NFS)。
如果备份数据,还需要在资源中添加下面额外 Annotation
默认情况: 不会自动备份所有卷的数据,需要明确告诉 Velero 备份哪些 Pod Volume
推荐方式(通用),在 Pod / Deployment / StatefulSet 中添加:
metadata: annotations: backup.velero.io/backup-volumes: data,logs #`data,logs` = Pod 中 volume 名称
--use-volume-snapshots
用途:卷快照是通过云提供商(如 AWS EBS、GCP PD)或 CSI 驱动实现的块级备份。该选项用于指定 Velero 在执行备份和恢复操作时是否使用存储卷快照功能。在 Kubernetes 环境中,很多应
用依赖存储卷来持久化数据,当进行数据备份和恢复时,利用存储卷快照可以高效地捕获某一时刻
存储卷上数据的状态,使得后续恢复时能基于这个准确的快照还原数据,极大地提高备份与恢复的
效率和准确性。
如果将 --use-volume-snapshots 设置为 true ,则 Velero 会尝试在满足条件(比如底层存储系统支持创建存储卷快照,像部分云平台提供的块存储服务等具备此功能)的情况下,对相关存储卷创
建快照,并将其作为备份操作的一部分,在需要恢复时也会基于这些快照来还原数据到对应的存储
卷上。
相反,若将其设置为 false ,Velero 就不会利用存储卷快照机制来进行备份和恢复工作,而是可能采用其他方式(比如直接复制存储卷中的文件数据等相对来说更常规、但在某些情况下效率更低
的方法)来完成数据的备份和恢复流程
--use-volume-snapshots=false
作用:
- 仅备份 PVC 的元数据和挂载信息,不备份卷的实际数据。
- 数据恢复时需依赖底层存储系统的持久化能力(如 NFS 共享存储)。
适用场景:
- 使用不支持卷快照的存储系统(如 NFS、CephFS)。
- 依赖文件级备份(通过 Node Agent)而非块级快照。
- 希望降低备份存储成本(仅保存元数据)。
--wait
用途:设置安装完成后是否等待 Velero 组件达到就绪状态才返回结果。如果设置为 true ,命令会一直阻塞,直到确认 Velero 相关组件都已经成功启动并且可以正常工作了才结束执行;如果设
置为 false ,则命令执行完安装操作后立即返回,不关注后续组件是否就绪。
常用于自动化部署脚本等场景,确保后续基于 Velero 的操作(如备份操作等)能马上开展。
--plugins
用途:用来指定要安装的插件列表。Velero 要适配不同的云平台、存储系统等需要对应的插件支持,通过该选项可以明确安装所需插件,确保能与相应的基础设施顺利协同工作。
示例:表示同时安装适用于 AWS 和 GCP(Google Cloud Platform)的插件,方便 Velero 在两种云环境完成备份、恢复等操作
--plugins registry.cn-beijing.aliyuncs.com/wangxiaochun/velero-plugin-for-aws:v1.11.0
--use-node-agent #启用 Velero 的 Node Agent组件,该组件以DaemonSet形式部署在每个节点上,可以支持对 PVC数据的文件级备份。
--use-volume-snapshots=false #禁用卷快照功能。卷快照是通过云提供商(如 AWS EBS、GCP PD)或 CSI 驱动实现的块级备份。仅备份 PVC 的元数据和挂载信息,不备份卷的实际数据
#执行install命令后会创建一系列清单,包括CustomResourceDefinition、Namespace、Deployment等。
kubectl get all -n velero
[root@master1 ~]# kubectl get pod -n velero NAME READY STATUS RESTARTS AGE node-agent-6mqvh 1/1 Running 1 (4m43s ago) 16m node-agent-gptm5 1/1 Running 0 16m velero-66fd688cb-56pjp 1/1 Running 0 16m [root@master1 ~]# [root@master1 ~]# [root@master1 ~]# kubectl get all -n velero NAME READY STATUS RESTARTS AGE pod/node-agent-6mqvh 1/1 Running 1 (5m2s ago) 17m pod/node-agent-gptm5 1/1 Running 0 17m pod/velero-66fd688cb-56pjp 1/1 Running 0 17m NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset.apps/node-agent 2 2 2 2 2 <none> 17m NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/velero 1/1 1 1 17m NAME DESIRED CURRENT READY AGE replicaset.apps/velero-66fd688cb 1 1 1 17m
kubectl get pod -n velero
[root@master1 ~]# kubectl get pod -n velero NAME READY STATUS RESTARTS AGE node-agent-6mqvh 1/1 Running 1 (4m43s ago) 16m node-agent-gptm5 1/1 Running 0 16m velero-66fd688cb-56pjp 1/1 Running 0 16m
kubectl get backupstoragelocation -A
[root@master1 ~]# kubectl get backupstoragelocation -A NAMESPACE NAME PHASE LAST VALIDATED AGE DEFAULT velero default Available 57s 17m true
#查看运行日志
kubectl logs deployment/velero -n velero
#查看备份位置信息
velero backup-location get
[root@master1 ~]# velero backup-location get NAME PROVIDER BUCKET/PREFIX PHASE LAST VALIDATED ACCESS MODE DEFAULT default aws velero Available 2026-07-22 18:18:11 +0800 CST ReadWrite true [root@master1 ~]#
卸载 Velero Server
如果想从集群中完全卸载Velero,则以下命令将删除由 velero install 创建的所有资源:
#方法1
velero uninstall --namespace velero
#方法2
kubectl delete namespace/velero clusterrolebinding/velero
kubectl delete crds -l component=velero
服务器端 客户端都安装好
案例: Velero 实现备份与恢复
数据备份
备份命令说明
https://velero.io/docs/v1.8/how-velero-works/

创建测试应用
无状态资源(支持)
kubectl create ns demo
kubectl create deployment myapp --image registry.cn-beijing.aliyuncs.com/wangxiaochun/pod-test:v0.1 --replicas 3 -n demo
kubectl get pod -n demo
[root@master1 scheduler]# kubectl get pod -n demo NAME READY STATUS RESTARTS AGE myapp-7b478c76d7-4m6vh 1/1 Running 0 6s myapp-7b478c76d7-c8tvz 1/1 Running 0 6s myapp-7b478c76d7-ggvzb 1/1 Running 0 6s
PVC 存储资源(支持)
#示例:基于storageclass的PVC的存储数据
[root@master1 scheduler]# cat redis-pvc-sc.yaml kind: PersistentVolumeClaim apiVersion: v1 metadata: name: redis-pvc spec: storageClassName: sc-nfs accessModes: - ReadWriteMany resources: requests: storage: 2Gi --- apiVersion: v1 kind: Pod metadata: #需要额外 Annotation,默认情况不会自动备份所有卷的数据,需要明确告诉Velero 备份哪些 Pod Volume #不写 annotation 的话:只备份 Kubernetes 资源(YAML),不备份卷内数据 #annotations: # backup.velero.io/backup-volumes: data name: redis-pvc-pod spec: containers: - name: redis image: registry.cn-beijing.aliyuncs.com/wangxiaochun/redis:7.2.5 ports: - containerPort: 6379 name: redis volumeMounts: - mountPath: /data name: data volumes: - name: data persistentVolumeClaim: claimName: redis-pvc
kubectl apply -f redis-pvc-sc.yaml
kubectl get pod
root@master1 scheduler]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES redis-pvc-pod 1/1 Running 0 37s 10.244.3.21 node2.org <none> <none>
kubectl get pvc
[root@master1 scheduler]# kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE redis-pvc Bound pvc-dbf37aa8-d669-4d64-925a-a0a7f9a882b0 2Gi RWX sc-nfs <unset> 60s
root@master1 scheduler]# ls -trl /data/sc-nfs/ total 0 drwxrwxrwx 2 root root 6 Jun 18 16:21 harbor-myharbor-jobservice-pvc-d9c06ed5-31cc-4ca3-89a5-2d368d3fb50b drwxrwxrwx 4 root root 34 Jun 18 16:32 harbor-data-myharbor-trivy-0-pvc-67bce1f8-9ebe-4bde-b93c-5f7a915ca5e0 drwxrwxrwx 3 root root 20 Jun 18 16:32 harbor-database-data-myharbor-database-0-pvc-9496532a-3df3-4b48-9b22-932aa71e34e6 drwxrwxrwx 3 root root 20 Jun 18 17:59 harbor-myharbor-registry-pvc-61b660de-2459-4833-9d40-8927c42ae818 drwxrwxrwx 2 root root 22 Jul 22 18:30 harbor-data-myharbor-redis-0-pvc-2628e1b2-9824-4b0f-b7e1-26a62ee5be0d drwxrwxrwx 2 systemd-coredump root 6 Jul 22 18:31 default-redis-pvc-pvc-dbf37aa8-d669-4d64-925a-a0a7f9a882b0
[root@master1 scheduler]# ls -trl /data/sc-nfs/default-redis-pvc-pvc-dbf37aa8-d669-4d64-925a-a0a7f9a882b0 total 0 [root@master1 scheduler]#
#创建测试数据
[root@master1 scheduler]# kubectl exec -it redis-pvc-pod -- sh # # redis-cli 127.0.0.1:6379> set name tom OK 127.0.0.1:6379> keys * 1) "name" 127.0.0.1:6379> config get dir 1) "dir" 2) "/data" 127.0.0.1:6379> exit # ls /data # redis-cli 127.0.0.1:6379> save OK 127.0.0.1:6379> exit # ls /data dump.rdb
[root@master1 scheduler]# ls -trl /data/sc-nfs/default-redis-pvc-pvc-dbf37aa8-d669-4d64-925a-a0a7f9a882b0 total 4 -rw------- 1 systemd-coredump systemd-coredump 103 Jul 22 18:37 dump.rdb
[root@master1 scheduler]# kubectl get pod -n demo NAME READY STATUS RESTARTS AGE myapp-7b478c76d7-4m6vh 1/1 Running 0 6s myapp-7b478c76d7-c8tvz 1/1 Running 0 6s myapp-7b478c76d7-ggvzb 1/1 Running 0 6s
[root@master1 scheduler]# kubectl get pod NAME READY STATUS RESTARTS AGE redis-pvc-pod 1/1 Running 0 12m
备份
TIME=`date +%F-%H-%M-%S`
#示例1:只备份demo,default名称空间的资源和相关数据
velero backup create k8s-backup-$TIME --kubeconfig ~/.kube/config --include-namespaces=demo,default --default-volumes-to-fs-backup --snapshot-volumes=false --wait
velero backup create k8s-backup-$TIME --include-namespaces=demo,default --default-volumes-to-fs-backup --snapshot-volumes=false --wait
[root@master1 scheduler]# velero backup create k8s-backup-$TIME --include-namespaces=demo,default --default-volumes-to-fs-backup --snapshot-volumes=false --wait Backup request "k8s-backup-2026-07-22-19-00-34" submitted successfully. Waiting for backup to complete. You may safely press ctrl-c to stop waiting - your backup will continue in the background. ............. Backup completed with status: Completed. You may check for more information using the commands `velero backup describe k8s-backup-2026-07-22-19-00-34` and `velero backup logs k8s-backup-2026-07-22-19-00-34`.
#不加选项:--include-namespaces 即表示所有名称空间
选项:
--include-namespaces :指定需要备份的命名空间
--default-volumes-to-fs-backup : 默认不备份PV,使用此选项可以将PV的卷数据以文件方式上传至远程存储
--selector :标签选择器,如app=nginx


kubectl delete deployment myapp -n demo
TIME=`date +%F-%H-%M-%S
velero backup create k8s-backup-$TIME --include-namespaces=demo,default --default-volumes-to-fs-backup --snapshot-volumes=false --wait
[root@master1 scheduler]# velero backup create k8s-backup-$TIME --include-namespaces=demo,default --default-volumes-to-fs-backup --snapshot-volumes=false --wait Backup request "k8s-backup-2026-07-22-19-06-01" submitted successfully. Waiting for backup to complete. You may safely press ctrl-c to stop waiting - your backup will continue in the background. .... Backup completed with status: Completed. You may check for more information using the commands `velero backup describe k8s-backup-2026-07-22-19-06-01` and `velero backup logs k8s-backup-2026-07-22-19-06-01`.
kubectl get backup -n velero
[root@master1 scheduler]# kubectl get backup -n velero NAME AGE k8s-backup-2026-07-22-19-00-34 8m53s k8s-backup-2026-07-22-19-06-01 3m28s
velero get backup -n velero
root@master1 scheduler]# velero get backup -n velero NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION QUEUE POSITION SELECTOR k8s-backup-2026-07-22-19-00-34 Completed 0 0 2026-07-22 19:00:39 +0800 CST 29d default <none> k8s-backup-2026-07-22-19-06-01 Completed 0 0 2026-07-22 19:06:04 +0800 CST 29d default <none>
模拟破坏 然后用备份恢复
kubectl delete -f redis-pvc-sc.yaml
kubectl delete ns demo
[root@master1 scheduler]# ls /data/sc-nfs/archived-default-redis-pvc-pvc-dbf37aa8-d669-4d64-925a-a0a7f9a882b0/ dump.rdb
MinIO 查看备份

数据恢复
注意:
- velero restore 恢复时不会覆盖已有的资源,只恢复当前集群中不存在的资源。
- 已有的资源不会回滚到之前的版本,如需要回滚,需在restore之前提前删除现有的资源。
模拟灾难
恢复资源
#恢复前查看备份名称
velero backup get
[root@master1 scheduler]# velero backup get NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION QUEUE POSITION SELECTOR k8s-backup-2026-07-22-19-00-34 Completed 0 0 2026-07-22 19:00:39 +0800 CST 29d default <none> k8s-backup-2026-07-22-19-06-01 Completed 0 0 2026-07-22 19:06:04 +0800 CST 29d default <none> [root@master1 scheduler]#
velero restore create --from-backup k8s-backup-2026-07-22-19-00-34 --wait
[root@master1 scheduler]# velero restore create --from-backup k8s-backup-2026-07-22-19-00-34 --wait Restore request "k8s-backup-2026-07-22-19-00-34-20260722191853" submitted successfully. Waiting for restore to complete. You may safely press ctrl-c to stop waiting - your restore will continue in the background. .................................................................................... Restore completed with status: Completed. You may check for more information using the commands `velero restore describe k8s-backup-2026-07-22-19-00-34-20260722191853` and `velero restore logs k8s-backup-2026-07-22-19-00-34-20260722191853`.
检查恢复的资源
#创建restores资源
root@master1 scheduler]# kubectl get restores.velero.io -n velero NAME AGE k8s-backup-2026-07-22-19-00-34-20260722191853 2m
#完成恢复后,会在MinIO存储中同时创建和一个和backups同级的restores的目录


验证还原数据
[root@master1 scheduler]# kubectl get pod NAME READY STATUS RESTARTS AGE redis-pvc-pod 1/1 Running 0 4m2s [root@master1 scheduler]# [root@master1 scheduler]# kubectl get pod -n demo NAME READY STATUS RESTARTS AGE myapp-7b478c76d7-4m6vh 1/1 Running 0 4m4s myapp-7b478c76d7-c8tvz 1/1 Running 0 4m4s myapp-7b478c76d7-ggvzb 1/1 Running 0 4m4s [root@master1 scheduler]# [root@master1 scheduler]# [root@master1 scheduler]# ls -trl /data/sc-nfs/ archived-default-redis-pvc-pvc-dbf37aa8-d669-4d64-925a-a0a7f9a882b0/ default-redis-pvc-pvc-ee3f8b84-5e64-4db1-9c01-981e478d9e2d/ harbor-database-data-myharbor-database-0-pvc-9496532a-3df3-4b48-9b22-932aa71e34e6/ harbor-data-myharbor-redis-0-pvc-2628e1b2-9824-4b0f-b7e1-26a62ee5be0d/ harbor-data-myharbor-trivy-0-pvc-67bce1f8-9ebe-4bde-b93c-5f7a915ca5e0/ harbor-myharbor-jobservice-pvc-d9c06ed5-31cc-4ca3-89a5-2d368d3fb50b/ harbor-myharbor-registry-pvc-61b660de-2459-4833-9d40-8927c42ae818/ [root@master1 scheduler]# ls -trl /data/sc-nfs/default-redis-pvc-pvc-ee3f8b84-5e64-4db1-9c01-981e478d9e2d/ total 4 -rw------- 1 systemd-coredump systemd-coredump 103 Jul 22 18:37 dump.rdb [root@master1 scheduler]#
root@master1 scheduler]# kubectl exec -it redis-pvc-pod -- sh Defaulted container "redis" out of: redis, restore-wait (init) # redis-cli 127.0.0.1:6379> keys * 1) "name" 127.0.0.1:6379> get name "tom" 127.0.0.1:6379>
#查看恢复情况
velero restore get
root@master1 scheduler]# velero restore get NAME BACKUP STATUS STARTED COMPLETED ERRORS WARNINGS CREATED SELECTOR k8s-backup-2026-07-22-19-00-34-20260722191853 k8s-backup-2026-07-22-19-00-34 Completed 2026-07-22 19:18:53 +0800 CST 2026-07-22 19:20:18 +0800 CST 0 2 2026-07-22 19:18:53 +0800 CST <none>
[root@master1 scheduler]# kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE redis-pvc Bound pvc-ee3f8b84-5e64-4db1-9c01-981e478d9e2d 2Gi RWX sc-nfs <unset> 7m44s
定时备份
velero支持定时备份
范例:定时备份
#每分钟备份一次
velero schedule create k8s-backup-schedule --schedule="* * * * *" --include-namespaces=demo --default-volumes-to-fs-backup --snapshot-volumes=false
#等待一会儿,可以看到下面备份
velero schedule get
[root@master1 scheduler]# velero schedule get NAME STATUS CREATED SCHEDULE BACKUP TTL LAST BACKUP SELECTOR PAUSED k8s-backup-schedule Enabled 2026-07-22 19:36:48 +0800 CST * * * * * 0s n/a <none> false
velero get backup
[root@master1 scheduler]# velero get backup NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION QUEUE POSITION SELECTOR k8s-backup-2026-07-22-19-00-34 Completed 0 0 2026-07-22 19:00:39 +0800 CST 29d default <none> k8s-backup-2026-07-22-19-06-01 Completed 0 0 2026-07-22 19:06:04 +0800 CST 29d default <none> k8s-backup-schedule-20260722113713 Completed 0 0 2026-07-22 19:37:13 +0800 CST 29d default <none>

#删除定时备份
velero schedule delete k8s-backup-schedule --confirm
#确认删除
velero schedule get
#手动立即触发定时任务
velero backup create --from-schedule k8s-backup-daily --wait
#等一会儿可以查看备份成功
velero get backup
velero backup get
kubectl delete deployment myapp -n demo
#恢复定时备份k8s-backup-schedule中的最近成功的备份版本
velero restore create --from-schedule k8s-backup-schedule--wait
#如果恢复定时备份的数据
#使用如下命令恢复指定的备份
velero restore create --from-backup k8s-backup-schedule-20260722113713 --wait
[root@master1 scheduler]# velero get backup NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION QUEUE POSITION SELECTOR k8s-backup-2026-07-22-19-00-34 Completed 0 0 2026-07-22 19:00:39 +0800 CST 29d default <none> k8s-backup-2026-07-22-19-06-01 Completed 0 0 2026-07-22 19:06:04 +0800 CST 29d default <none> k8s-backup-schedule-20260722114213 Completed 0 0 2026-07-22 19:42:13 +0800 CST 29d default <none> k8s-backup-schedule-20260722114113 Completed 0 0 2026-07-22 19:41:13 +0800 CST 29d default <none> k8s-backup-schedule-20260722114013 Completed 0 0 2026-07-22 19:40:13 +0800 CST 29d default <none> k8s-backup-schedule-20260722113913 Completed 0 0 2026-07-22 19:39:13 +0800 CST 29d default <none> k8s-backup-schedule-20260722113813 Completed 0 0 2026-07-22 19:38:13 +0800 CST 29d default <none> k8s-backup-schedule-20260722113713 Completed 0 0 2026-07-22 19:37:13 +0800 CST 29d default <none>
[root@master1 scheduler]# velero restore create --from-backup k8s-backup-schedule-20260722113713 --wait Restore request "k8s-backup-schedule-20260722113713-20260722194324" submitted successfully. Waiting for restore to complete. You may safely press ctrl-c to stop waiting - your restore will continue in the background. . Restore completed with status: Completed. You may check for more information using the commands `velero restore describe k8s-backup-schedule-20260722113713-20260722194324` and `velero restore logs k8s-backup-schedule-20260722113713-20260722194324`. [root@master1 scheduler]#
[root@master1 scheduler]# kubectl get pod -n demo NAME READY STATUS RESTARTS AGE myapp-7b478c76d7-4m6vh 1/1 Running 0 18s myapp-7b478c76d7-c8tvz 1/1 Running 0 18s myapp-7b478c76d7-ggvzb 1/1 Running 0 17s
案例: Velero 实现跨 Kubernetes 集群的资源数据迁移

迁移前准备
对旧的Kubernetes集群做好备份至MinIO的远程存储
安装新的 Kubernetes 集群
源k8s集群
192.168.3.60 master
192.168.3.63 node1
192.168.3.64 node2
目标迁移k8s集群
192.168.3.61 master
192.168.3.62 node1
192.168.3.67 node2
[root@master1 ~]# [root@master1 ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.3.61 kubeapi.org kubeapi 192.168.3.61 master1.org master1 192.168.3.62 node1.org node1 192.168.3.67 node2.org node2
目标迁移k8s集群安装和源端k8s集群一样 安装好网络附件 sc-nfs
新的 Kubernetes 集群安装 velero CLI 并配置 MinIO 认证
注意: 相同版本的 velero CLI和原MinIO相同的认证信息
范例:
安装和使用 Velero Cli
Velero CLI 二进制安装
软件包下载地址
https://github.com/vmware-tanzu/velero/releases
范例: 二进制安装 Velero CLI
#在K8s集群的Master节点上安装velero CLI
VERSION=v1.18.1
#直接下载
wget https://github.com/vmwaretanzu/velero/releases/download/${VERSION}/velero-${VERSION}-linux-amd64.tar.gz
#如果下载失败,可以通过代理如下
wget https://githubfast.com/vmwaretanzu/velero/releases/download/${VERSION}/velero-${VERSION}-linux-amd64.tar.gz
tar -zxvf velero-${VERSION}-linux-amd64.tar.gz
tree velero-${VERSION}-linux-amd64
mv velero-${VERSION}-linux-amd64/velero /usr/local/bin/
velero version
新的 Kubernetes 集群安装 velero CLI 并配置 MinIO 认证 注意: 相同版本的 velero CLI和原MinIO相同的认证信息
范例:
配置 CLI 访问 MinIO 认证密钥
#在K8s集群的Master节点上MinIO的创建认证文件
cat > credentials-velero <<EOF
[default]
#aws_access_key_id = admin
#aws_secret_access_key = 12345678
aws_access_key_id = y81QoEEcmV06Zc18e2Fp
aws_secret_access_key = 8VdbRxsgG7Or5yk7f5FXHjs87dOMhjuPmNK8s2cs
EOF
新的 Kubernetes 集群安装 Velero Server
安装 Velero Server
velero install 安装
velero install 命令用于在 Kubernetes 集群中安装 Velero,它有多个选项可用来定制化安装过程
安装 Velero Server
范例: 安装 Velero Server
#示例1: 支持资源和数据以文件方式备份,但不支持快照备份
velero install \
--provider aws \
--image registry.cn-beijing.aliyuncs.com/wangxiaochun/velero:v1.15.0 \
--plugins registry.cn-beijing.aliyuncs.com/wangxiaochun/velero-plugin-for-aws:v1.11.0 \
--backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://192.168.3.65:9000 \
--bucket velero \
--secret-file ./credentials-velero \
--namespace velero \
--use-node-agent \
--use-volume-snapshots=false \
--wait
备份
TIME=`date +%F-%H-%M-%S`
#示例1:只备份demo,default名称空间的资源和相关数据
velero backup create k8s-backup-$TIME --kubeconfig ~/.kube/config --include-namespaces=demo,default --default-volumes-to-fs-backup --snapshot-volumes=false --wait
velero backup create k8s-backup-$TIME --include-namespaces=demo,default --default-volumes-to-fs-backup --snapshot-volumes=false --wait
velero backup create k8s-backup-$TIME --default-volumes-to-fs-backup --snapshot-volumes=false --wait
#不加选项:--include-namespaces 即表示所有名称空间
选项:
--include-namespaces :指定需要备份的命名空间
--default-volumes-to-fs-backup : 默认不备份PV,使用此选项可以将PV的卷数据以文件方式上传至远程存储
--selector :标签选择器,如app=nginx
新的 Kubernetes 集群下载 MinIO 上备份数据并恢复
#可以查看到原来旧的Kubernetes集群的备份名称信息
kubectl get backups.velero.io -n velero
velero backup get
#基于上面查看到的备份名称进行恢复
velero restore create --from-backup k8s-backup --wait
velero restore create --from-backup k8s-backup-2026-07-25-18-52-44 --wait
# 删除所有 Failed 的恢复
velero restore get | grep Failed | awk '{print $1}' | xargs -I {} velero restore delete {} --confirm 2>/dev/null || true
如果恢复时遇到 "already exists" 错误
--existing-resource-policy=update 覆盖已存在资源velero restore create --from-backup k8s-backup-2026-07-25-18-52-44 \
--existing-resource-policy=update \
--wait
新的 Kubernetes 集群检查数据恢复情况
#查看恢复情况
velero restore get
# 查看最新恢复的详情
velero restore describe $(velero restore get | grep -v NAME | tail -1 | awk '{print $1}')
kubectl get pod
ls /data/sc-nfs/
浙公网安备 33010602011771号