Velero 多标签选择器(OrLabelSelectors)备份与恢复设计解读
2026/9/15 11:17:44 网站建设 项目流程

Velero 多标签选择器(OrLabelSelectors)备份与恢复设计解读

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

本文以 Velero 官方设计文档 design/Implemented/multiple-label-selectors_design.md 为骨架,结合当前仓库源码,完整讲解OrLabelSelectors的设计动机、API 结构、实现原理与使用限制,帮助读者掌握如何用一份 Backup/Restore 配置完成"多标签 OR 逻辑"的资源筛选。

导读

Kubernetes 的 label selector 原生只支持 AND 逻辑(多个键值对同时匹配),而现实中很多应用以多套标签体系标记同一批资源(如app=gdprapp=wpaapp=ccpa),按任意一个标签命中就要纳入备份。Velero 通过新增OrLabelSelectors字段,让一个备份或恢复请求可以指定一组 label selector,资源只要命中其中任意一个即被选中。读完本文,你将理解该字段的 API 定义、与原有LabelSelector的互斥关系、备份与恢复两侧的底层实现调用链,以及直接使用 YAML 配置该功能的方法。

一、背景:单标签筛选的局限

Velero 的 Backup / Restore API 原本只有一个LabelSelector字段(*metav1.LabelSelector),用于在备份/恢复请求级别按标签过滤资源。例如指定labelSelector: {matchLabels: {data-protection-app: "true"}},Velero 只会把带该标签的资源纳入备份。

LabelSelector的匹配语义来自 Kubernetes 本身:多个标签键值对之间是 AND 关系,即必须同时满足全部条件。这带来两个问题:

  • 无法表达"标签集合中任意命中一个"(OR 逻辑);
  • 用户若想按 OR 规则备份,只能针对每个标签分别创建一份 Backup,规模一大就非常繁琐。

设计文档中给出的典型场景是:用户想备份一批 Secret,但这些 Secret 的标签并不统一,只要命中app=gdprapp=wpaapp=ccpa中任意一个就要备份。在旧方案下必须创建 3 份 Backup,每份对应一个标签规则。相关讨论见 Velero 仓库 issue #1508(对应设计文档内的 Related Issue 链接)。

二、设计目标与总体思路

该特性的核心目标是:

  1. 支持在单个 Backup 配置中按多标签 OR 逻辑筛选资源;
  2. 支持在单个 Restore 配置中按多标签 OR 逻辑筛选资源;
  3. 不改变现有LabelSelector的任何行为,二者作为相互独立的 API 功能并存。

关键设计决定是新增独立的OrLabelSelectors字段,而不是扩展LabelSelector的语义。设计文档同时明确了二者共存时的优先级规则:若同时指定两者(现实中不常见),OrLabelSelectors优先LabelSelector仅在未指定OrLabelSelectors时生效。

三、API 设计:BackupSpec 与 RestoreSpec 的新字段

3.1 结构定义

设计文档给出的原型为:BackupSpec 与 RestoreSpec 各自新增OrLabelSelectors []*metav1.LabelSelector,语义为"资源命中集合中任意一个 label selector 即被纳入"。当前仓库中的落地实现位于 pkg/apis/velero/v1/backup_types.go,并已带有明确的互斥注释:

// OrLabelSelectors is list of metav1.LabelSelector to filter with // when adding individual objects to the backup. If multiple provided // they will be joined by the OR operator. LabelSelector as well as // OrLabelSelectors cannot co-exist in backup request, only one of them // can be used. // +optional // +nullable OrLabelSelectors []*metav1.LabelSelector `json:"orLabelSelectors,omitempty"`

RestoreSpec 的对应字段定义在 pkg/apis/velero/v1/restore_types.go 中,语义为"从备份中恢复时,对象命中任意一个 selector 即被恢复"。

3.2 字段互斥校验

设计文档强调LabelSelectorOrLabelSelectors被视作两种独立功能,不应混用。这一约束在控制器层有强制校验:备份控制器在 pkg/controller/backup_controller.go 中,若发现请求同时携带两个字段,会向request.Status.ValidationErrors追加错误信息:

"encountered labelSelector as well as orLabelSelectors in backup spec, only one can be specified"

恢复侧同样遵循"二者不能共存,只能指定其一"的约束(见 pkg/restore/restore.go 的注释说明)。

四、YAML 使用示例

4.1 仅使用OrLabelSelectors(推荐方式)

下面的配置来自设计文档的用例:命名空间test内的资源只要命中app=gdprapp=wpaapp=ccpa中任意一个标签即被备份:

apiVersion: velero.io/v1 kind: Backup metadata: name: backup-101 namespace: openshift-adp spec: includedNamespaces: - test storageLocation: velero-sample-1 ttl: 720h0m0s orLabelSelectors: - matchLabels: app: gdpr - matchLabels: app: wpa - matchLabels: app: ccpa

注意:orLabelSelectors的每一项都是一个完整的metav1.LabelSelector,因此不仅可以使用matchLabels,也可以使用matchExpressions(如In/NotIn/Exists操作符)来表达更复杂的匹配条件,并可与原LabelSelector一样与 namespace 过滤、resource 过滤配合使用。

4.2 仅使用LabelSelector(原有行为)

apiVersion: velero.io/v1 kind: Backup metadata: name: backup-101 namespace: openshift-adp spec: includedNamespaces: - test storageLocation: velero-sample-1 ttl: 720h0m0s labelSelector: matchLabels: app: gdpr

此例仍保持原有语义:只匹配app=gdpr这一个标签。

4.3 语义对比小结

配置方式匹配语义命中条件
labelSelectorAND资源必须满足该 selector 的全部条件
orLabelSelectorsOR资源满足集合中任意一个 selector 即命中
两者同时指定非法控制器校验报错,只允许其一

Restore 的用法与 Backup 完全一致,只需将同样的字段写到kind: Restorespec下即可实现"按多标签 OR 逻辑恢复对象"。

五、源码级实现剖析

5.1 备份侧:item_collector 的双路查询

设计文档指出备份侧的改动集中在pkg/backup/item_collector.go。当前实现的核心逻辑在listResourceByLabelsPerNamespace函数(pkg/backup/item_collector.go),其处理流程如下:

  1. 初始化全局选择器:遍历backupRequest.Spec.OrLabelSelectors,用metav1.FormatLabelSelector逐个格式化为字符串并放入orLabelSelectors切片;若存在Spec.LabelSelector则格式化为labelSelector字符串(pkg/backup/item_collector.go)。
  2. 细粒度过滤覆盖:当配置了基于资源类型的细粒度过滤器(如 ResourcePolicies 的 per-kind filter)时,会用 filter 中携带的LabelSelector/OrLabelSelectors覆盖全局选择器(pkg/backup/item_collector.go),保证更精细的过滤策略优先。
  3. OR 列表优先查询:只要orLabelSelectors非空,就对其中每个 selector 分别执行一次 list 查询并合并结果(listItemsForLabel),实现"多次查询、结果取并集"的 OR 效果(pkg/backup/item_collector.go)。
  4. 仅当 OR 列表为空时才走单 label 查询:若len(orLabelSelectors) == 0,则回退到原来的labelSelector单次查询,完全保留旧行为(pkg/backup/item_collector.go)。

此外,在设计文档提到的collectResource路径上,命名空间对象同样会经过 label 选择器检查(见 pkg/backup/item_collector.go 附近关于 namespace 过滤的注释),而资源对象也会在写入备份前按 OR 集合做逐项判定(pkg/backup/item_collector.go),与 API Server 端的选择器查询形成双重保险。

备份请求中的选择器还会被转换为labels.Selector形式,用于 namespace 追踪器(nsTracker)的初始化(pkg/backup/item_collector.go),确保按 OR 规则选中的资源所在 namespace 也能被正确记录与处理。

5.2 恢复侧:restore.go 的逐对象判定

设计文档指出的恢复侧改动位于pkg/restore/restore.go。当前实现包含两处关键逻辑:

  • 选择器准备:在恢复流程入口,若req.Restore.Spec.OrLabelSelectors非空,则逐个通过metav1.LabelSelectorAsSelector转换为labels.Selector列表OrSelectors;同时将LabelSelector(为空时用空 selector 兜底,即匹配全部)转换为selector(pkg/restore/restore.go)。
  • 逐对象 OR 判定:恢复每个对象时,先按原有selector判断,再遍历ctx.OrSelectors:只要对象标签与任意一个OR selector 匹配,就保留该对象;若与全部 OR selector 都不匹配,则跳过(pkg/restore/restore.go)。

这样恢复侧就实现了"命中集合中任意一个标签即恢复,全部不命中则跳过"的语义,与备份侧完全对齐。

5.3 细粒度过滤(ResourcePolicies)中的 OR 支持

除了 Backup/Restore 顶层字段,OrLabelSelectors还被引入到细粒度资源过滤体系:在备份的资源策略过滤与恢复的资源策略过滤中,均可为某个资源类型配置LabelSelectorOrLabelSelectors(相关判定见 pkg/backup/item_collector.go 与 pkg/restore/restore.go),使多标签 OR 逻辑不仅能用于整份备份/恢复请求,还能用于对特定资源类型做精细控制。

六、CLI 支持情况与使用边界

设计文档明确说明:该特性不会通过 Velero CLI 暴露。从当前仓库看,虽然 pkg/cmd/util/flag/orlabelselector.go 提供了一个 Cobra 兼容的OrLabelSelectorflag 包装器(支持以or分隔解析多个 selector,例如app=gdpr or app=wpa),并且 pkg/cmd/cli/backup/create.go、pkg/cmd/cli/restore/create.go、pkg/cmd/cli/schedule/create.go 等 CLI 代码中都有OrLabelSelectors相关引用,但作为 API 层字段,它最稳定、最推荐的使用方式是直接编写 Backup / Restore 的 YAML 清单提交给集群,通过kubectl applyvelero backup create --from-backup等清单化方式使用。

使用时请注意以下几点边界:

  • labelSelectororLabelSelectors互斥,二者同时出现会被控制器校验拒绝;
  • orLabelSelectors中每一项都是独立的metav1.LabelSelector,单项内部仍是 AND 语义,多项之间才是 OR 语义;
  • 该字段同时适用于 Backup 与 Restore,也适用于 Schedule 触发的备份(底层仍是 Backup 资源);
  • 字段可选(+optional)、可空(+nullable),为空或 nil 时行为等同于不筛选,即所有对象纳入。

七、测试与验证

仓库为这一特性提供了完整的单元测试覆盖,可作为理解语义的补充证据:

  • 备份侧:pkg/backup/backup_test.gopkg/backup/item_collector.go相关的 OR 选择器测试,验证多 selector 合并查询与逐项判定逻辑;
  • 恢复侧:pkg/restore/restore_test.go中覆盖了OrLabelSelectors场景的恢复筛选测试;
  • 构建器与 CLI:pkg/builder/backup_builder.gopkg/builder/restore_builder.go提供了在测试或代码中构造OrLabelSelectors的便捷方式,pkg/cmd/util/flag/orlabelselector_test.go验证了 flag 解析行为。

八、总结

OrLabelSelectors以"新增独立字段、不改旧行为、二者互斥、OR 优先"为原则,解决了 Kubernetes 标签选择器只支持 AND 语义的天然限制,让 Velero 用户可以:

  • 用一份 Backup 配置覆盖"多套标签中的任意一套";
  • 用一份 Restore 配置按同样规则恢复对象;
  • 将多标签 OR 逻辑扩展到细粒度的 ResourcePolicies 过滤场景。

从实现上看,备份侧通过"每个 selector 分别 list、结果取并集"实现 OR 查询,恢复侧通过"逐对象遍历 OR selector 集合、全部不命中才跳过"实现 OR 判定,二者语义一致、边界清晰。若你需要对一批标签不统一但"命中任一标签即需保护"的资源做备份与恢复,可以直接参考本文第四节 YAML 示例,将orLabelSelectors写入 Backup / Restore 清单投入使用。

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

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

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

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

立即咨询