Velero Restore Resource Modifiers 完全指南:JSON Patch、Merge Patch 与默认资源修饰器

发布时间:2026/9/16 17:49:14
Velero Restore Resource Modifiers 完全指南:JSON Patch、Merge Patch 与默认资源修饰器 Velero Restore Resource Modifiers 完全指南JSON Patch、Merge Patch 与默认资源修饰器【免费下载链接】veleroBackup and migrate Kubernetes applications and their persistent volumes项目地址: https://gitcode.com/GitHub_Trending/ve/velero导读Restore Resource Modifiers 是 Velero 提供的一项通用能力它允许你在资源被还原restore之前通过 JSON Patch / JSON Merge Patch / Strategic Merge Patch 对备份中的资源对象进行就地修改从而解决备份里的资源与目标集群期望状态不一致这类问题例如替换 PVC 的 storageClass、清理 CNI 注入的过期注解、修正容器镜像等。本文以 restore-resource-modifiers.md 为核心结合仓库内 internal/resourcemodifiers 的实现源码系统讲解配置语法、条件匹配、三种 Patch 类型、通配符以及服务器级默认资源修饰器的完整用法。一、工作原理还原前的一次外科手术Velero 在还原流程中会先取得备份对象在将对象提交到目标集群之前应用资源修饰器规则。整个流程的入口在还原控制器 restore_controller.govalidateAndCompletepkg/controller/restore_controller.go#L311在校验阶段加载并校验资源修饰器配置优先加载每个 restore 通过--resource-modifier-configmap指定的 ConfigMap若未指定再判断是否启用服务器级默认配置加载成功后ApplyResourceModifierRulesinternal/resourcemodifiers/resource_modifiers.go#L87会被调用对每个待还原对象依次匹配规则并应用 Patch。从源码结构看每条规则都包含两部分conditions筛选哪些资源被打补丁和patches / mergePatches / strategicPatches打什么样的补丁二者共同定义了一次有条件的资源修改。该设计思路源自kubectl patch命令的 JSON Patch 语义。在编写资源修饰器 YAML 之前可以直接用kubectl patch验证效果同样的 Patch 在 Velero 中会按相同语义工作例如kubectl patch pod valid-pod -typejson -p[{op: replace, path: /spec/containers/0/image, value:new image}]二、快速上手两步使用资源修饰器步骤 1创建资源修饰器 ConfigMap资源修饰器规则以 YAML 文件形式定义并通过 ConfigMap 挂载。ConfigMap 必须创建在 Velero 安装命名空间默认velero中kubectl create cm configmap-name --from-file yaml-file -n velero例如将规则文件保存为resource-modifiers.yaml后kubectl create cm my-resource-modifiers --from-file resource-modifiers.yaml -n velero从实现看GetResourceModifiersFromConfig 要求 ConfigMap 的data中恰好只有一个键解析时对该键的 YAML 内容做严格解码yaml.UnmarshalStrict随后通过 Validate 校验版本与规则合法性。步骤 2创建引用该 ConfigMap 的还原创建 restore 时通过--resource-modifier-configmap指定 ConfigMap 名称velero restore create --resource-modifier-configmap configmap-name该参数在 CLI 中的定义见 pkg/cmd/cli/restore/create.go#L172--resource-modifier-configmap string Reference to the resource modifier configmap that restore will use三、YAML 模板与规则语义3.1 基础模板version: v1 resourceModifierRules: - conditions: groupResource: persistentvolumeclaims resourceNameRegex: ^mysql.*$ namespaces: - bar - foo labelSelector: matchLabels: foo: bar patches: - operation: replace path: /spec/storageClassName value: premium - operation: remove path: /metadata/labels/test上述配置的作用是对命名空间bar和foo中、名称以mysql开头且带有标签foo: bar的所有 PVC先将其storageClassName替换为premium再移除标签test。3.2 语义要点命名空间是原命名空间conditions 中的namespaces指备份时资源所在的原命名空间而不是还原目标命名空间。这是因为修饰器作用的对象是还原前的备份资源。同一条规则可指定多个 PatchPatches 按在 ConfigMap 中出现的顺序依次应用。若多个 Patch 指向同一路径后面的 Patch 会覆盖前面的结果。可指定多条resourceModifierRules多条规则按 ConfigMap 中的顺序依次应用。版本字段必填version目前仅支持v1校验逻辑见 resource_modifiers_validator.go#L50其他版本会被拒绝。3.3 条件conditions字段详解对应源码结构体Conditionsinternal/resourcemodifiers/resource_modifiers.go#L46字段类型说明是否必填groupResourcestring资源组与资源名如persistentvolumeclaims、deployments.apps必填resourceNameRegexstring按资源名称的正则匹配如^mysql.*$可选namespacesstring[]原命名空间列表不填则匹配所有命名空间可选labelSelectorobject与 Kubernetes 标准LabelSelector一致的标签选择器可选matchesobject[]字段级条件匹配列表见下文条件补丁可选所有条件之间是AND关系。匹配逻辑matchresource_modifiers.go#L113依次校验命名空间、groupResource使用 glob 通配编译、名称正则、标签选择器与字段条件全部命中才应用该规则。3.4 groupResource 的取值约定persistentvolumeclaims核心组的 PVC等价于persistentvolumeclaims.v1deployments.appsapps组的 Deploymentpods、services等核心资源可直接写资源名。四、JSON PatchRFC 6902详解4.1 支持的操作patches列表支持 RFC 6902 定义的以下操作校验逻辑见 resource_modifiers_validator.go#L66add在指定路径添加值remove移除指定路径的值replace替换指定路径的值move把某路径的值移动到另一路径copy把某路径的值复制到另一路径test校验某路径的值是否与给定值一致用于条件补丁见下文。4.2 值的类型自动识别一个值得注意的实现细节JSONPatch.Value在 YAML 中声明为字符串但底层 ToString 配合addQuotes会根据内容自动决定是否加引号null、布尔值true/false、数字、以{或[开头的 JSON 对象/数组 →不加引号按 JSON 原生类型处理普通字符串 → 自动加引号若希望布尔值、数字或null被当作字符串写入可将值用双引号包裹转义例如\true\。这一设计让你既能写入字符串也能写入对象、数组和数字例如给容器追加配置。4.3 复杂值示例转义 YAML 写入 JSON 对象version: v1 resourceModifierRules: - conditions: groupResource: deployments.apps resourceNameRegex: ^test-.*$ namespaces: - bar - foo patches: # Dealing with complex values by escaping the yaml - operation: add path: /spec/template/spec/containers/0 value: {\name\: \nginx\, \image\: \nginx:1.14.2\, \ports\: [{\containerPort\: 80}]} # Copy Operator - operation: copy from: /spec/template/spec/containers/0 path: /spec/template/spec/containers/1该示例演示了两个技巧以转义字符串形式写入复杂 JSON 对象add在指定数组下标位置插入一个完整容器定义copy操作从/spec/template/spec/containers/0复制容器定义到下标 1实现复用容器配置。提示from字段仅在move与copy操作中使用其他操作不要携带该字段。4.4 多 Patch 的叠加与覆盖多条 Patch 按顺序逐个应用到同一对象上见 JSONPatcher.Patch因此先test后replace或多条replace同一路径、后者覆盖前者都是合法的组合。五、条件补丁用test操作实现 if-elsetest操作用于先检查、后修改如果目标路径的值与value一致则补丁链继续不一致则整条 Patch 链跳过不会报错。典型场景是把仅当 PVC 使用某存储类时才切换存储类写成声明式规则version: v1 resourceModifierRules: - conditions: groupResource: persistentvolumeclaims resourceNameRegex: .* namespaces: - bar - foo patches: - operation: test path: /spec/storageClassName value: premium - operation: replace path: /spec/storageClassName value: standard上面规则的含义只有当前 PVC 的 storageClassName 恰为premium时才将其替换为standard。源码中当test操作失败jsonpatch.ErrTestFailed时JSONPatcher.Patch 会记录一条 Info 日志并原样返回对象而非中断还原——这是条件补丁优雅跳过的底层保证。六、条件匹配新字段matches适用于所有 Patch 类型除 JSON Patch 的test操作外conditions 还支持一个独立的matches字段可作用于 JSON Patch、Merge Patch、Strategic Merge Patch 全部三种类型。它在条件层做字段值校验只有全部匹配项都满足时才应用规则version: v1 resourceModifierRules: - conditions: groupResource: persistentvolumeclaims.storage.k8s.io matches: - path: /spec/storageClassName value: premium mergePatches: - patchData: | { metadata: { annotations: { foo: null } } }上面规则的作用对所有存储类为premium的 PVC所有命名空间移除注解foo。可在matches中指定多条匹配规则只有全部满足时补丁才会应用从实现看matchConditions 会把每条matches翻译成一次内部的test补丁并统一应用任一失败即视为不匹配path为必填缺省会返回校验错误注意matches与第 5 节test操作的差异test是补丁链内的操作失败时跳过该链matches是规则级前置条件失败时整条规则含 mergePatches 等都不生效。七、JSON Merge Patch按需增删字段当你想按字段级语义合并修改而无需写 RFC 6902 路径时可以使用mergePatches。JSON Merge Patch 的规则是null值表示删除该字段非 null 值表示合并/覆盖。version: v1 resourceModifierRules: - conditions: groupResource: pods namespaces: - ns1 mergePatches: - patchData: | { metadata: { annotations: { foo: null } } }该规则会移除ns1下所有 Pod 的注解foo。要点patchData同时支持JSON 与 YAML两种格式底层统一经 yaml.YAMLToJSON 转换后交给jsonpatch.MergePatch执行多条mergePatches按顺序依次合并适合加注解、删注解、改字段等轻量修改场景。八、Strategic Merge Patch类型感知的合并对于 Pod、Deployment 等包含复杂列表语义的内置资源推荐使用strategicPatches。Strategic Merge Patch 依赖 Kubernetes 的 schema 信息如containers按name合并而非按数组下标覆盖因此需要知道目标资源的类型。version: v1 resourceModifierRules: - conditions: groupResource: pods resourceNameRegex: ^my-pod$ namespaces: - ns1 strategicPatches: - patchData: | { spec: { containers: [ { name: nginx, image: repo2/nginx } ] } }上面规则的作用把ns1中名为my-pod的 Pod 内nginx容器的镜像更新为repo2/nginx而不会影响其他容器这正是 Strategic Merge Patch 与普通 JSON Merge Patch 的关键差异。实现要点strategic_merge_patch.go通过对象的GroupVersionKind从runtime.Scheme取出类型化对象作为 schema 参考L28-L32调用strategicpatch.StrategicMergeMapPatch完成合并并带有严格的类型校验与错误归类patchData同样支持 JSON 与 YAML 两种格式。因此使用strategicPatches的前提是 Velero 进程内已注册该 GVK 的 Go 类型内置资源均满足对于自定义资源等无 schema 的类型请回退到patches或mergePatches。三种 Patch 类型在同一规则中互斥从 Validate 可以看出patches、mergePatches、strategicPatches三者最多只能指定其一否则校验失败。九、groupResource 通配符支持conditions.groupResource支持 glob 通配语法源码使用glob.Compile(..., .)编译匹配写法含义*.appsapps组内的所有资源如 Deployment、StatefulSet、DaemonSet 等*核心组v1的所有资源*.*所有组、所有资源特殊规则当同时指定*.groupName与namespaces时补丁会作用于指定命名空间内的所有命名空间级资源该组下以及该组下所有集群级资源不受 namespaces 限制因为集群资源本身没有命名空间。这非常适合编写对整个资源组的注解统一清理之类的全局规则。十、服务器级默认资源修饰器Default Resource ModifiersVelero 支持在服务器端配置一个默认资源修饰器只要配置了它每次还原都会自动应用无需为每个 restore 单独指定。典型场景是清理备份中残留的、会导致还原后工作负载异常的 CNI 注解。10.1 创建默认 ConfigMap仓库提供了现成示例 examples/default-resource-modifier-cni.yaml它利用 Merge Patch 清除 Pod 上三个常见的 CNI 网络状态注解apiVersion: v1 kind: ConfigMap metadata: name: default-restore-resource-modifiers namespace: velero data: resource-modifiers.yaml: | version: v1 resourceModifierRules: - conditions: groupResource: pods mergePatches: - patchData: | metadata: annotations: k8s.ovn.org/pod-networks: null k8s.v1.cni.cncf.io/network-status: null k8s.v1.cni.cncf.io/networks-status: null应用方式kubectl apply -f examples/default-resource-modifier-cni.yaml10.2 让 Velero 服务器使用它方式一安装时指定见 pkg/cmd/cli/install/install.go 中对应的服务器参数velero install --default-resource-modifier-configmapdefault-restore-resource-modifiers ...方式二编辑已有 deployment 添加服务器参数kubectl -n velero edit deploy velero # Add to the server args: --default-resource-modifier-configmapdefault-restore-resource-modifiers服务器端参数定义位于 pkg/cmd/server/config/config.go由 pkg/cmd/server/server.go 读取并传入还原控制器。10.3 优先级规则独占优先当某次 restore 通过--resource-modifier-configmap显式指定了修饰器时只应用该修饰器默认修饰器不再应用默认兜底未指定 per-restore 修饰器时自动应用默认修饰器。对应逻辑见 restore_controller.go#L442-L458先检查restore.Spec.ResourceModifier为空再检查defaultResourceModifierConfigMap。10.4 单次还原跳过默认修饰器若某次还原既不想用 per-restore 修饰器也不想用默认修饰器可添加跳过标志velero restore create --from-backup my-backup --skip-default-resource-modifier对应 CLI 参数pkg/cmd/cli/restore/create.go#L176--skip-default-resource-modifier Skip applying the server-configured default resource modifier for this restore10.5 错误处理策略默认修饰器出错不阻塞若默认 ConfigMap 缺失或内容非法Velero 仅记录一条 warning 日志仍继续执行还原per-restore 修饰器出错是致命的显式指定的修饰器若加载或校验失败会导致该 restore 直接校验失败。两者在 loadResourceModifierConfigMap 处通过参数区分默认修饰器使用宽松warning模式per-restore 修饰器使用严格模式。建议在生产环境为默认修饰器配置监控告警避免悄悄失效。十一、常见问题与最佳实践先在kubectl patch中验证resource modifiers 的 JSON Patch 与kubectl patch --typejson语义一致先用 kubectl 在测试集群验证再固化到 ConfigMap。ConfigMap 只能有一个 data 键GetResourceModifiersFromConfig 会拒绝data超过一个键的 ConfigMap。version必须是v1v1以外的版本或空版本都会在校验阶段被拒绝。规则顺序即应用顺序多条规则、多条 Patch 都按声明顺序执行想先改 A 再基于 A 改 B时要留意顺序依赖。路径风格路径遵循 JSON Pointer 语法/分隔、数组用下标如/spec/template/spec/containers/0首字符必须是/。三种 Patch 类型按需选择精确路径用patchesRFC 6902按字段语义轻量合并用mergePatches处理内置资源的复杂列表如容器合并用strategicPatches。集群级资源不受namespaces约束配置了namespaces的规则对集群级资源如 ClusterRole、StorageClass仍会生效编写时注意预期。善用默认修饰器把每次还原都要做的清理如剥离 CNI 注解收敛为服务器级默认配置降低每个 restore 的配置负担。十二、相关源码与文档索引官方使用文档site/content/docs/main/restore-resource-modifiers.md核心实现internal/resourcemodifiers/resource_modifiers.go规则结构、条件匹配、规则应用JSON Patch 实现internal/resourcemodifiers/json_patch.goMerge Patch 实现internal/resourcemodifiers/json_merge_patch.goStrategic Merge Patch 实现internal/resourcemodifiers/strategic_merge_patch.go规则校验internal/resourcemodifiers/resource_modifiers_validator.go还原控制器集成pkg/controller/restore_controller.goCLI 参数定义pkg/cmd/cli/restore/create.go默认修饰器示例examples/default-resource-modifier-cni.yaml单元测试internal/resourcemodifiers/resource_modifiers_test.go、internal/resourcemodifiers/json_patch_test.go、internal/resourcemodifiers/strategic_merge_patch_test.go设计文档design/default-resource-modifier_design.md【免费下载链接】veleroBackup and migrate Kubernetes applications and their persistent volumes项目地址: https://gitcode.com/GitHub_Trending/ve/velero创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询