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 备份还原的工作流程

image

 

 

image

 

 备份数据:

本地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 来启动应用副本等)。对于有持久卷数据需要恢复的情
况,它会从备份存储位置获取数据并还原到对应的持久卷中,确保应用能够正常使用之前的数据。

image

 

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

5b4ed30214638479a299fa37cb82a6a4

 

 

 

 

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

 

a2f5e7fc5e3ee812590ca6742503fea9

 

 

创建一个bucket名为: velero

8262d9211b7aa251149cbb3abbf79c96

 

 

9aa52a0d7df9afbd5769beb736e53325

 

创建Access Key并配置权限
创建并记录 Access Key 和 Secret key

#Access Key
y81QoEEcmV06Zc18e2Fp
#Secret key
8VdbRxsgG7Or5yk7f5FXHjs87dOMhjuPmNK8s2cs

 

06459c8dc427dfbfe38c060b01e91fc1

 

 

配置 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/

image

 

创建测试应用

无状态资源(支持)

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

 

299042c714eeaf81010dfd5ad5931b9d

 

764cf1048d134de8122c6506b604af19

 

 

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 查看备份

74f3ea63dd4f4c2850e8922005070f7b

 

数据恢复
注意:

  • 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的目录

 

972d6edfec21a4f3af0b7d8e5dfcbc1e

 

 

f51576ee5c3ebf40ce0151289060f778

 

验证还原数据

[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>

 

d70b8dbbad959f6a4b89b4ac8460a383

 

 

#删除定时备份

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 集群的资源数据迁移

image

 

迁移前准备
对旧的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/

 

 
posted @ 2026-07-29 15:06  minger_lcm  阅读(8)  评论(0)    收藏  举报