Velero backupPVC 配置设计:基于 node-agent ConfigMap 的 CSI 快照数据迁移中间卷调优

发布时间:2026/9/16 1:31:58
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),仅供参考