Velero Restore API 的 ExistingResourcePolicy:控制已存在 Kubernetes 资源的还原行为
2026/9/16 10:42:47 网站建设 项目流程

Velero Restore API 的 ExistingResourcePolicy:控制已存在 Kubernetes 资源的还原行为

【免费下载链接】veleroBackup and migrate Kubernetes applications and their persistent volumes项目地址: https://gitcode.com/GitHub_Trending/ve/velero

导读

当目标集群中已存在与备份中同名的 Kubernetes 资源时,Velero 默认会直接跳过还原——即使集群里的版本与备份中的版本不一致。ExistingResourcePolicy是 Velero 为 Restore API 新增的可选字段,它让用户能够显式决定:备份中的资源是否应覆盖(patch)集群中已存在的同名资源。本文基于 existing-resource-policy_design.md 设计文档,结合当前仓库中的 API 类型定义、CLI 实现与还原执行逻辑,完整讲解该策略的设计演进、最终落地形态与实战用法。读完本文,你将掌握noneupdate两种策略的语义差异、如何通过 YAML 或velero create restore命令配置它,以及 Velero 在还原阶段如何处理"已存在且内容不同"的资源。

背景:Velero 原有的"已存在即跳过"行为

在设计该功能之前,Velero 对集群中已存在资源的还原流程(以备份中的Service为例)如下:

  1. Velero 尝试还原该Service
  2. 先从集群中获取同名的Service
  3. 若该Service已存在,则比较集群实例与备份实例:
    • 两者不相同:跳过还原,并添加一条还原警告(ServiceAccount对象除外);
    • 两者相同:跳过还原,并在日志中记录"还原被跳过"。

也就是说,无论备份中的资源与集群中的资源是否一致,Velero 都一律跳过,用户没有任何手段让备份中的版本覆盖集群中的版本。相关需求记录于 Velero 的 issue #4066。这一局限使得 Velero 难以胜任"用备份持续同步/刷新目标集群"这类场景,因此社区提出了为 Restore API 增加ExistingResourcePolicy的增强提案。

设计目标与明确排除的范围

设计文档对本提案划定了清晰的边界:

目标

  • 为 Restore API 增加ExistingResourcePolicy,让用户决定备份资源是否覆盖集群中已存在的资源。

非目标(本次不实现)

  • 不改变ServiceAccount对象既有的还原工作流;
  • 不支持recreate(先删除再重建)策略,该选项仅作为未来扩展方向保留。

与提案无关、明确排除的功能

  • 对非 Kubernetes 资源的还原策略;
  • PersistentVolume数据的还原策略(PV 数据策略由独立的existingVolumeDataPolicy字段负责)。

典型使用场景

场景 A:用备份集群持续同步生产集群

假设存在一个与生产集群相同的备份集群。经过一段时间的运行,生产集群发生了变化——新增了 Deployment、部分 Secret 被更新。为了让备份集群的 Kubernetes 资源(PV 数据除外)与生产集群保持同步,用户可以定期创建新备份,再通过 Velero restore 将最新状态还原到备份集群。此时必须允许备份中的资源覆盖备份集群中已存在的旧版本,这正是update策略的用武之地。

场景 B:帮助识别资源增量(delta)

这里"delta"指的是上一次备份还原出来的资源、但已不在最新备份中的资源。例如:

  • 集群 A 有 P1、P2、P3 三个资源,先创建 Backup1(含 P1、P2、P3)并还原到集群 B;
  • 随后集群 A 删除了 P1、更新了 P2;
  • 再创建 Backup2(此时只含 P2' 和 P3);
  • 于是 delta = |集群 B − Backup2|,即"删除 P1、更新 P2"。

在第二次还原时,用户希望借助还原过程来识别这些资源增量,从而判断集群 B 与最新备份之间的差异。

三种候选设计方案的权衡

设计文档提出了三种 API 形态,最终实现选择了方案一。

方案一:在 Restore API 增加existingResourcePolicy字段

不改变 Velero 既有行为,仅新增一个可选的existingResourcePolicy字段,取值如下:

取值行为
none维持现有行为:资源在集群中已存在时直接跳过还原
update对已存在的资源尝试打补丁(patch):若补丁成功,集群资源被更新为备份版本并打上最新的 backup/restore 标签;若补丁失败,记录还原警告,并退而求其次仅更新资源的 backup/restore 标签,标签更新再失败则记录还原错误
recreate若资源已存在则先删除再重建(本提案的非目标,列为未来范围)

需要强调的是:该设计中任何策略都不会删除资源update策略只是通过 patch 更新资源。

示例 A——对velero-protection命名空间中的servicesdeployments执行none策略:

Kind: Restore … includeNamespaces: velero-protection includeResources: - services - deployments existingResourcePolicy: none

示例 B——对gdpr-application命名空间中的secretsdaemonsets执行update策略:

Kind: Restore … includeNamespaces: gdpr-application includeResources: - secrets - daemonsets existingResourcePolicy: update

方案二:增加existingResourcePolicyConfig字段(按资源类型细粒度配置)

该方案允许用户为不同的资源类型指定不同的行为,形成"资源类型 → 行为"的映射:

existingResourcePolicyConfig: - patch: includedResources: [ ]string - recreate: includedResources: [ ]string

注意:

  • 该方案中没有none行为,因为不配置即等价于当前/默认的 Velero 还原行为;
  • recreate同样被列为未来范围。

示例——对inventory-app命名空间中的secretsdaemonsets执行patch

Kind: Restore … includeNamespaces: inventory-app existingResourcePolicyConfig: patch: includedResources: - secrets - daemonsets

方案三:方案一与方案二的组合(默认策略 + 按资源覆盖)

同时新增existingResourceDefaultPolicyexistingResourcePolicyOverrides两个字段:前者描述本次还原的默认行为,后者可针对特定资源显式覆盖默认策略。

示例——默认patch,但对secrets覆盖为none

Kind: Restore … includeNamespaces: inventory-app existingResourceDefaultPolicy: patch existingResourcePolicyOverrides: none: includedResources: - secrets

实现决策

最终团队选择实现方案一,理由如下:

  • 更易于实现;
  • 更易于扩展,为未来演进到方案三保留了空间;
  • 提供了保留 Velero 既有还原工作流的选项。

当前仓库中的最终落地实现

Restore API 类型定义

方案一落地为RestoreSpec中的ExistingResourcePolicy字段,类型为ResourcePolicyType,定义在 pkg/apis/velero/v1/restore_types.go:

// ExistingResourcePolicy specifies the restore behavior for the Kubernetes resource to be restored // +optional // +nullable ExistingResourcePolicy ResourcePolicyType `json:"existingResourcePolicy,omitempty"`

策略常量定义于同一文件的第 337–343 行附近:

// ResourcePolicyTypeNone means velero will not overwrite the resource ResourcePolicyTypeNone ResourcePolicyType = "none" // ResourcePolicyTypeUpdate means velero will try to attempt a patch on // the resource to overwrite the in-cluster one ResourcePolicyTypeUpdate ResourcePolicyType = "update"

ResourcePolicyType本身是字符串别名类型:

// ResourcePolicyType helps specify the ExistingResourcePolicy type ResourcePolicyType string

需要注意的是,设计文档中草案曾使用PolicyTypePolicyTypeUpdate = "update"的命名,而当前仓库实际落地的类型名为ResourcePolicyType,字符串取值仍为none/update

CRD 中的字段声明

该字段同样体现在生成的 CRD 定义中,见 config/crd/v1/bases/velero.io_restores.yaml:

existingResourcePolicy: description: ExistingResourcePolicy specifies the restore behavior for the Kubernetes resource to be restored nullable: true type: string

还原执行逻辑

还原时对"已存在资源"的处理集中在 pkg/restore/restore.go 中。核心分支逻辑如下:

  • existingResourcePolicy存在且为none:记录警告"could not restore, ... already exists",将该项标记为ItemRestoreResultSkipped(跳过);
  • 若存在且为update:调用processUpdateResourcePolicy对已存在的资源执行 patch;
  • 若未设置该字段:保留 Velero 原有的行为——跳过还原并记录警告。

未变化资源(集群内版本与备份版本相同)的处理在 pkg/restore/restore.go:当策略为update时,先移除旧的 restore 标签,再调用updateBackupRestoreLabels仅更新 backup/restore 标签。

processUpdateResourcePolicy的具体流程见 pkg/restore/restore.go:

  1. 从集群实例上移除 restore 标签,以便应用最新的 backup/restore 名称;
  2. generatePatch(fromCluster, obj)生成集群实例与备份实例之间的补丁;
  3. 若补丁为空,说明集群内与期望状态一致,直接跳过;
  4. 调用resourceClient.Patch打补丁(同时包含资源差异与最新标签);
  5. 若 patch 失败:记录警告,并降级为仅更新 backup/restore 标签(updateBackupRestoreLabels),标签更新也失败则追加还原错误。

此外,ServiceAccount分支(pkg/restore/restore.go)同样考虑了update策略:patch 失败时先移除 restore 标签再尝试仅更新标签,成功则将该项标记为ItemRestoreResultUpdated

测试验证

仓库中的单元测试对两种策略均有覆盖,例如 pkg/restore/restore_test.go 中通过 Builder 分别构造ExistingResourcePolicy("update")ExistingResourcePolicy("none")的 Restore 来验证不同策略下的还原结果。对应 Builder 方法定义于 pkg/builder/restore_builder.go:

// ExistingResourcePolicy sets the Restore's resource policy. func (b *RestoreBuilder) ExistingResourcePolicy(policy string) *RestoreBuilder { b.object.Spec.ExistingResourcePolicy = velerov1api.ResourcePolicyType(policy) return b }

CLI:--existing-resource-policy标志

标志定义与校验

设计文档规划了 CLI 变更(落地位置 pkg/cmd/cli/restore/create.go),当前实现中标志定义如下:

flags.StringVar(&o.ExistingResourcePolicy, "existing-resource-policy", "", "Restore Policy to be used during the restore workflow for Kubernetes resources, can be - none or update")

并在还原创建前进行取值校验(pkg/cmd/cli/restore/create.go):

if len(o.ExistingResourcePolicy) > 0 && !restore.IsResourcePolicyValid(o.ExistingResourcePolicy) { return errors.New("existing-resource-policy has invalid value, it accepts only none, update as value") }

即传入除noneupdate之外的值会被直接拒绝。

使用示例

velero create restore <restore_name> --existing-resource-policy=update

描述器(describer)输出

velero restore describe也会展示该策略。普通描述器在 pkg/cmd/util/output/restore_describer.go 中仅在策略非空时输出;结构化描述器(-o json等)在 pkg/cmd/util/output/restore_structured_describer.go 中将其写入specInfo["existingResourcePolicy"]

实战配置指南

方式一:通过 Restore YAML 配置

直接创建/编辑 Restore 对象并指定策略,例如对gdpr-application命名空间中的secretsdaemonsets执行覆盖更新:

apiVersion: velero.io/v1 kind: Restore metadata: name: my-restore namespace: velero spec: backupName: my-backup includeNamespaces: - gdpr-application includeResources: - secrets - daemonsets existingResourcePolicy: update

应用后执行velero restore describe my-restore(或带-o json的结构化输出)即可确认策略是否生效。

方式二:通过 CLI 创建

velero create restore my-restore \ --from-backup my-backup \ --include-namespaces gdpr-application \ --include-resources secrets,daemonsets \ --existing-resource-policy=update

行为速查

集群内资源状态未设置策略(默认)noneupdate
不存在正常创建正常创建正常创建
存在且与备份相同跳过(日志记录)跳过(日志记录)仅更新 backup/restore 标签
存在且与备份不同跳过 + 警告跳过 + 警告(标记为 Skipped)先 patch 资源差异与标签;patch 失败则降级仅更新标签并给出警告

总结

ExistingResourcePolicy在不破坏 Velero 既有"已存在即跳过"默认行为的前提下,为用户提供了显式覆盖已存在资源的入口:none保持默认跳过语义,update则通过"先 patch 资源差异、失败后降级仅更新标签"的容错链路尽量将集群资源同步为备份版本。该功能已在 Restore API(existingResourcePolicy字段)、CRD(config/crd/v1/bases/velero.io_restores.yaml)、CLI(--existing-resource-policy)与还原执行逻辑(pkg/restore/restore.go)中完整落地,可用于备份集群同步、资源增量识别等场景;而recreate(先删后建)与"按资源类型细粒度指定策略"则被明确列为未来扩展方向。

【免费下载链接】veleroBackup and migrate Kubernetes applications and their persistent volumes项目地址: https://gitcode.com/GitHub_Trending/ve/velero

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询