Velero backupPVC 配置设计:基于 node-agent ConfigMap 的 CSI 快照数据迁移中间卷调优
Velero backupPVC 配置设计基于 node-agent ConfigMap 的 CSI 快照数据迁移中间卷调优【免费下载链接】veleroBackup and migrate Kubernetes applications and their persistent volumes项目地址: https://gitcode.com/GitHub_Trending/ve/velero导读本文围绕 VeleroKubernetes 应用与持久卷备份迁移工具中Volume Snapshot Data Movement卷快照数据迁移场景下的中间 PVCbackupPVC配置机制展开完整解析其设计文档《Backup PVC Configuration Design》中的背景、目标、数据结构、配置示例与实现细节。你将掌握如何通过node-agent的 ConfigMap 按源 PVC 的 StorageClass 为 backupPVC 指定专用存储类与ReadOnlyMany只读访问模式理解配置项在node-agent启动时如何被加载、如何传递到 CSI Snapshot Exposer 并最终作用到 backupPVC/backupPod 的创建上以及配置错误时 DataUpload CR 卡在Accepted阶段与 prepare 超时默认 30 分钟的排障思路。背景为什么要为 backupPVC 提供高级配置在 Volume Snapshot Data Movement Design 定义的数据迁移架构中Exposer 模块负责把卷快照暴露给 Velero node-agentVGDPVelero Generic Data Path通过一个中间卷完成数据读取。这个中间卷在设计中被称为backupPVC消费它的 Pod 称为backupPod而真正要被备份的 PVC 称为sourcePVC。三者关系如下sourcePVC要被备份的 PVC其快照由数据迁移插件创建backupPVC由 Exposer 创建的中间 PVCVGDP 从它上面读取数据backupPod挂载 backupPVC 的 Pod供 VGDP 访问其中数据。在默认流程里Exposer 从快照创建一个可写的 backupPVC其存储类与访问模式继承自 sourcePVC。但在一些真实环境中这种默认行为并非最优只读卷创建更快部分存储提供商从快照创建只读卷时速度极快而创建可写卷则需要克隆整块磁盘数据耗时明显。如果 backupPVC 的accessModes被设为ReadOnlyMany卷驱动便有机会通知存储层直接创建只读卷从而大幅缩短快照暴露时间。但ReadOnlyMany并非所有存储都支持因此需要允许用户自行配置。中间卷不需要副本部分存储提供商在创建卷时会按存储类定义生成一个或多个副本但对备份用的中间卷来说保留副本毫无意义。因此需要允许用户为 backupPVC 指定另一个专用存储类。这正是本设计文档要解决的问题——为用户提供一种机制按需为 backupPVC 指定多种高级配置。设计目标为用户提供指定 backupPVC 各种配置的机制配置需要按卷即按 sourcePVC 的存储类区分允许不同来源卷使用不同的 backupPVC 配置。解决方案总览复用 node-agent ConfigMap设计采用 Velero node-agent CLI 的--node-agent-configmap参数所指定的 ConfigMap 来承载 backupPVC 配置。核心约定如下该 ConfigMap不是由 Velero 创建的用户按需手动创建ConfigMap 必须位于Velero 安装所在的命名空间如果多个 Velero 实例安装在不同命名空间则每个命名空间各有一个 ConfigMap且只对该命名空间内的 node-agent 生效node-agent 服务在启动时读取这些配置并用于初始化相关 Exposer 模块。因此用户可以随时编辑该 ConfigMap但要使修改生效必须重启 node-agent 服务配置以 ConfigMap 的 data 形式存在本设计新增一种配置类型名称为backupPVC由于用户可能为不同卷设置不同的 backupPVC 配置因此配置被定义为一个以 sourcePVC 存储类名为键的 map键是 sourcePVC 使用的存储类名值是针对该 sourcePVC 创建的 backupPVC 的配置集合。从源码看node-agent 的配置加载逻辑位于 pkg/nodeagent/node_agent.go 的GetConfigs函数它读取指定 ConfigMap要求 data 中只能有一个 key并将该 JSON 字符串反序列化为NodeAgentConfigs结构。配置读取发生在 node-agent server 构造阶段见 pkg/cmd/cli/nodeagent/server.go 的getDataPathConfigs调用随后在run()中被取出并传给 DataUpload 控制器见 pkg/cmd/cli/nodeagent/server.go 与 pkg/cmd/cli/nodeagent/server.go印证了启动时读取、编辑后需重启的设计约束。数据结构详解设计中给出了承载配置的核心数据结构。它隶属于 node-agent 整体配置Configs当前实现中该类型位于 pkg/types/node_agent.go名为NodeAgentConfigstype Configs struct { // LoadConcurrency is the config for data path load concurrency per node. LoadConcurrency *LoadConcurrency json:loadConcurrency,omitempty // LoadAffinity is the config for data path load affinity. LoadAffinity []*LoadAffinity json:loadAffinity,omitempty // BackupPVC is the config for backupPVC of snapshot data movement. BackupPVC map[string]BackupPVC json:backupPVC,omitempty } type BackupPVC struct { // StorageClass is the name of storage class to be used by the backupPVC. StorageClass string json:storageClass,omitempty // ReadOnly sets the backupPVCs access mode as read only. ReadOnly bool json:readOnly,omitempty }要点说明BackupPVC是map[string]BackupPVC键为sourcePVC 的存储类名值为该卷对应的 backupPVC 配置StorageClassbackupPVC 要使用的存储类名ReadOnly是否将 backupPVC 的访问模式设为只读。需要特别指出的是当前仓库中的实现已经在设计文档的两个字段之外做了扩展。在 pkg/types/node_agent.go 中BackupPVC结构体实际包含以下字段type BackupPVC struct { StorageClass string json:storageClass,omitempty ReadOnly bool json:readOnly,omitempty // SPCNoRelabeling sets Spec.SecurityContext.SELinux.Type to spc_t for the pod mounting the backupPVC // ignored if ReadOnly is false SPCNoRelabeling bool json:spcNoRelabeling,omitempty // ReadWriteOncePod sets the backupPVCs access mode to ReadWriteOncePod so the kubelet can use // mount-level SELinux labeling (-o context) instead of per-file relabeling, when the CSI driver // advertises SELinux mount support. // ignored if ReadOnly is true ReadWriteOncePod bool json:readWriteOncePod,omitempty Annotations map[string]string json:annotations,omitempty // SecretNames is a list of secret names to copy from the source PVC namespace // to the Velero namespace before creating the backupPVC. ... SecretNames []string json:secretNames,omitempty // ConfigMapNames is a list of configmap names to copy from the source PVC namespace // to the Velero namespace before creating the backupPVC. ... ConfigMapNames []string json:configMapNames,omitempty }这些扩展字段spcNoRelabeling、readWriteOncePod、annotations、secretNames、configMapNames对应了后续演进中引入的能力SELinux 标签控制、ReadWriteOncePod 访问模式、自定义注解以及为加密卷等场景将 Secret/ConfigMap 从源 PVC 命名空间复制到 Velero 命名空间相关复制逻辑与清理逻辑见 pkg/exposer/csi_snapshot.go 与 pkg/exposer/csi_snapshot.go。本文以下内容以设计文档的两个核心字段为主线扩展字段作为补充说明。配置示例与 ConfigMap 创建设计文档给出的 ConfigMap data 示例JSON 格式如下{ backupPVC: { storage-class-1: { storageClass: snapshot-storage-class, readOnly: true }, storage-class-2: { storageClass: snapshot-storage-class }, storage-class-3: { readOnly: true } } }示例中三种场景的语义源卷存储类为storage-class-1backupPVC 使用snapshot-storage-class存储类且设为只读源卷存储类为storage-class-2backupPVC 仅更换存储类为snapshot-storage-class保持默认访问模式源卷存储类为storage-class-3backupPVC 不换存储类仅设为只读。创建 ConfigMap 的操作步骤为将上述 JSON 保存为文件例如node-agent-config.json然后执行kubectl create cm ConfigMap 名称 -n velero --from-filejson 文件名例如kubectl create cm node-agent-config -n velero --from-filenode-agent-config.json创建后需要在 node-agent 启动参数中通过--node-agent-configmap指定该 ConfigMap 名称对应 CLI 参数定义见 pkg/cmd/cli/nodeagent/server.go。GetConfigs对 ConfigMap 的约束是data 中只能有一个 key否则会返回more than one keys are found in ConfigMap的错误见 pkg/nodeagent/node_agent.go。也就是说这个 ConfigMap 的 data 应只包含一份完整 JSON可以包含loadConcurrency、loadAffinity等其他类型的配置项但都合并在这同一个 JSON 中而不是拆成多个 key。实现原理从配置到 backupPVC 的完整链路设计文档规定了两条核心实现规则均可在 CSI Snapshot Exposer 源码中得到印证存储类回退如果backupPVC.storageClass不存在或为空则使用 sourcePVC 的存储类访问模式规则如果backupPVC.readOnly为 true则ReadOnlyMany是 backupPVCaccessModes的唯一值否则使用ReadWriteOnce。在 pkg/exposer/csi_snapshot.go 中Exposer 先从csiExposeParam.BackupPVCConfig[csiExposeParam.StorageClass]按 sourcePVC 存储类取出配置若配置中的StorageClass非空则覆盖默认存储类否则沿用 sourcePVC 的存储类并读取ReadOnly标志。随后在createBackupPVC中pkg/exposer/csi_snapshot.go落实访问模式pvcAccessMode : corev1api.ReadWriteOnce if readOnly { pvcAccessMode corev1api.ReadOnlyMany } else if readWriteOncePod { pvcAccessMode corev1api.ReadWriteOncePod }即默认ReadWriteOncereadOnlytrue时切换为ReadOnlyMany扩展字段readWriteOncePodtrue且非只读时切换为ReadWriteOncePod。备份 Pod 创建时若 backupPVC 为只读则对应卷挂载也会带上ReadOnly: true见 pkg/exposer/csi_snapshot.go。配置从 node-agent 到 Exposer 的传递链路为node-agent server 在启动时通过getDataPathConfigs加载 ConfigMappkg/cmd/cli/nodeagent/server.gorun()中取出BackupPVCConfig并传入NewDataUploadReconcilerpkg/cmd/cli/nodeagent/server.goDataUpload 控制器在 reconcile 时将BackupPVCConfig放入 Exposer 参数pkg/controller/data_upload_controller.goCSI Snapshot Exposer 按 sourcePVC 存储类查找配置并创建 backupPVC/backupPod。测试用例对该链路做了充分验证例如 pkg/exposer/csi_snapshot_test.go 的 backupPod mounts read only backupPVC 用例构造了BackupPVCConfigStorageClass: fake-sc-read-only、ReadOnly: true并断言生成的 PVC 访问模式为只读、存储类被替换pkg/exposer/csi_snapshot_test.go 则统一断言了ReadOnlyMany/ReadWriteOncePod与存储类的预期结果。这些用例可作为理解配置生效细节的直接参考。配置错误的影响与排障建议设计文档明确指出了配置错误会带来的后果一旦设置了backupPVC.storageClass用户必须确保该存储类在集群中存在且可被 backupPVC 使用否则对应的 DataUpload CR 将一直停留在Accepted阶段直到 prepare 超时默认 30 分钟一旦设置了backupPVC.readOnlytrue用户必须确保存储支持从快照创建ReadOnlyMany的 PVC否则同样会导致 DataUpload CR 停留在Accepted阶段直至 prepare 超时。prepare 超时机制在源码中有对应实现node-agent 服务默认的data-mover-prepare-timeout为 30 分钟见 pkg/cmd/cli/nodeagent/server.go 与 pkg/cmd/cli/nodeagent/server.goDataUpload 控制器在Accepted阶段会依据AcceptedTimestamp与 prepare 超时做超时判断见 pkg/controller/data_upload_controller.go。另一个需要注意的排障难点是超时发生后 DataUpload CR 会被取消且 backupPVC 与 backupPod 会被删除因此仅凭最终状态无法区分问题原因是上述两类配置错误还是其他原因。设计文档提出的改进方向是为 CSI Exposer 增加诊断机制在 prepare 超时删除 backupPod 之前探查其状态。从当前仓库看这一思路已被实现CSI Snapshot Exposer 提供了DiagnoseExpose方法pkg/exposer/csi_snapshot.go会依次检查 backupPod、backupPVC及关联 PV、backup VolumeSnapshot/VolumeSnapshotContent 以及相关 Event 的状态并输出诊断信息供排障定位问题根源。总结backupPVC 配置机制为 Velero 的 CSI 卷快照数据迁移提供了按需调优中间卷的能力通过 node-agent ConfigMap 中的backupPVCmap用户可针对不同 sourcePVC 存储类分别指定 backupPVC 的存储类与只读访问模式从而利用快照创建只读卷更快的存储特性缩短暴露时间、避免中间卷产生冗余副本。该机制的核心约束是配置在 node-agent 启动时加载、修改后需重启 node-agent 生效配置错误存储类不存在/不可用或不支持 ReadOnlyMany会导致 DataUpload CR 卡在Accepted阶段直至 30 分钟 prepare 超时排障时可借助 Exposer 的诊断能力定位根因。如需深入理解该配置所处的整体架构可继续阅读数据迁移整体工作流Volume Snapshot Data Movement DesignVGDP 与备份仓库设计Unified Repository and Kopia Integration配置加载与结构定义pkg/nodeagent/node_agent.go、pkg/types/node_agent.goExposer 实现与测试pkg/exposer/csi_snapshot.go、pkg/exposer/csi_snapshot_test.go【免费下载链接】veleroBackup and migrate Kubernetes applications and their persistent volumes项目地址: https://gitcode.com/GitHub_Trending/ve/velero创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

VOC人车数据集手工标注规范与YOLOv8训练实战

VOC人车数据集手工标注规范与YOLOv8训练实战

简介:本资源是面向深度学习初学者与计算机视觉实践者的高质量人车识别训练数据集,专为YOLO等目标检测模型训练优化设计,解决小规模场景下标注质量不足、泛化能力弱等常见痛点。数据集共1994个文件,包含729张JPG与268张PNG格式原始…

2026/9/22 14:51:25 阅读更多 →
STM32F103扫雷游戏开发:Keil时钟配置与SysTick定时器实战

STM32F103扫雷游戏开发:Keil时钟配置与SysTick定时器实战

简介:这是一份基于STM32F103的裸机嵌入式项目包,重点围绕时钟系统配置、OLED屏幕驱动和扫雷小游戏展开。项目使用Keil ARM MDK-ARM环境,兼顾STM32基础外设编程与简单游戏开发,适合刚接触STM32或想学习小型嵌入式项目的开发者。压缩…

2026/9/20 21:36:34 阅读更多 →
NFS与SMB选型指南:Linux用NFS,Windows用SMB,混用踩坑全记录

NFS与SMB选型指南:Linux用NFS,Windows用SMB,混用踩坑全记录

先说我个人的态度:NFS 和 SMB 这两个东西,本身没有谁比谁绝对高级,只有谁比谁更合适。我在混合环境里折腾过很多次,最直观的结论就是标题这句话——Linux 机器之间共享文件,老老实实用 NFS;Windows 参与的共…

2026/9/20 13:12:15 阅读更多 →

最新新闻

3个坑让excel财务软件跑不通?源码最佳实践全解析

3个坑让excel财务软件跑不通?源码最佳实践全解析

3个坑让excel财务软件跑不通?源码最佳实践全解析 复制来的Excel财务软件源码,改个路径就报错,或者公式计算结果全是#REF!,这种“复制粘贴”的绝望感,相信做财务自动化的同学都懂。很多教程只给最终效果,却不讲底层逻辑,导致代码在不同…

2026/9/22 14:50:52 阅读更多 →
MATLAB拟合曲线避坑指南:3个核心技巧搞定实战项目数据

MATLAB拟合曲线避坑指南:3个核心技巧搞定实战项目数据

MATLAB拟合曲线避坑指南:3个核心技巧搞定实战项目数据 还在对着教程里的代码发呆?别慌,这种“看懂了但写不出”的困境,几乎每个刚接触工程类数据处理的毕业生都踩过。很多教程只给你一行 polyfit…

2026/9/22 14:50:52 阅读更多 →
613越狱实战项目避坑:3步搞定环境配置与面试高频考点

613越狱实战项目避坑:3步搞定环境配置与面试高频考点

613越狱实战项目避坑:3步搞定环境配置与面试高频考点 配置环境就卡半天,是不是让你对 实战项目 的开发提不起兴趣?很多应届生在准备613越狱相关的技术面试时,往往死磕在底层环境搭建和基础原理上,导致面试时一问三不知。其实,613越狱的核心…

2026/9/22 14:50:52 阅读更多 →
2026最新种子下载器源码深扒:API大改后如何重构核心逻辑

2026最新种子下载器源码深扒:API大改后如何重构核心逻辑

2026最新种子下载器源码深扒:API大改后如何重构核心逻辑 刚把项目里的 libtorrent 依赖从 2.x 升到 2.1,测试跑了一半直接崩了。报错信息刺眼: PeerConnection::connect() 参数不匹配 。这就是…

2026/9/22 14:50:52 阅读更多 →
2026最新:图解下线原理,3步解决教程看完不会写项目的痛点

2026最新:图解下线原理,3步解决教程看完不会写项目的痛点

2026最新:图解下线原理,3步解决教程看完不会写项目的痛点 看了一堆教程还是不会写项目?这是2026年无数开发者的真实写照。你背了八股文,敲了Hello…

2026/9/22 14:50:52 阅读更多 →
微信背景图避坑指南:3个致命错误让前端崩溃

微信背景图避坑指南:3个致命错误让前端崩溃

微信背景图避坑指南:3个致命错误让前端崩溃 配置环境就卡半天,是不是你也在为一张微信背景图头大?明明代码看着没问题,一跑起来图片要么拉伸变形,要么加载白屏,调试半天找不到原因。这份避坑指南专治这类疑难杂症,帮你省掉至少半天的抓狂时间。…

2026/9/22 14:49:51 阅读更多 →

日新闻

3台商务办公笔记本实测:手写实现环境配置,告别卡半天

3台商务办公笔记本实测:手写实现环境配置,告别卡半天

3台商务办公笔记本实测:手写实现环境配置,告别卡半天 配置环境就卡半天?别怪机器慢,多半是你没选对工具链。在Java、Go或Python的项目现场, 手写实现…

2026/9/22 0:00:41 阅读更多 →
剑帝加点速查手册:3分钟搞懂核心逻辑

剑帝加点速查手册:3分钟搞懂核心逻辑

剑帝加点速查手册:3分钟搞懂核心逻辑 面试被问原理答不上来,是不是常态?别慌。很多开发者对着 GitHub 开源仓库里的代码发呆,看似简单实则暗藏玄机。今天这份【剑帝加点】速查手册,直接带你拆解核心实现,把面试必考的原理讲透。…

2026/9/22 0:00:41 阅读更多 →
手写实现图片压缩网站核心:搞定WebP转换与质量调优

手写实现图片压缩网站核心:搞定WebP转换与质量调优

手写实现图片压缩网站核心:搞定WebP转换与质量调优 复制来的代码跑不通不知道怎么调?别慌,这种“复制粘贴地狱”在开发圈太常见了。尤其是做 图片压缩网站…

2026/9/22 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/22 4:32:41 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/22 4:38:57 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/22 8:51:04 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/21 15:36:51 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/21 15:36:51 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/22 2:43:42 阅读更多 →