# Labels 和 Selectors

Labels 其实就一对 key/value,被关联到对象上,标签的使用我们倾向于能够标示对象的特殊特点,并且对用户而言是有意义的(就是一眼就看出了这个 Pod 是尼玛数据库),但是标签对内核系统是没有直接意义的。标签可以用来划分特定组的对象(比如,所有女的),标签可以在创建一个对象的时候直接给与,也可以在后期随时修改,每一个对象可以拥有多个标签,但是,key 值必须是唯一的

"labels": {
  "key1" : "value1",
  "key2" : "value2"
}

我们最终会索引并且反向索引(reverse-index)labels,以获得更高效的查询和监视,把他们用到 UI 或者 CLI 中用来排序或者分组等等。我们不想用那些不具有指认效果的 label 来污染 label,特别是那些体积较大和结构型的的数据。不具有指认效果的信息应该使用 annotation 来记录。

# Motivation

Labels 可以让用户将他们自己的有组织目的的结构以一种松耦合的方式应用到系统的对象上,且不需要客户端存放这些对应关系(mappings)。

服务部署和批处理管道通常是多维的实体(例如多个分区或者部署,多个发布轨道,多层,每层多微服务)。管理通常需要跨越式的切割操作,这会打破有严格层级展示关系的封装,特别对那些是由基础设施而非用户决定的很死板的层级关系。

示例标签:

  • "release" : "stable","release" : "canary"
  • "environment" : "dev","environment" : "qa","environment" : "production"
  • "tier" : "frontend","tier" : "backend","tier" : "cache"
  • "partition" : "customerA","partition" : "customerB"
  • "track" : "daily","track" : "weekly"

这些只是常用 Labels 的例子,你可以按自己习惯来定义,需要注意,每个对象的标签 key 具有唯一性。

# 语法和字符集

Label 其实是一对 key/value。有效的标签键有两个段:可选的前缀和名称,用斜杠(/)分隔,名称段是必需的,最多 63 个字符,以[a-z0-9A-Z]带有虚线(-)、下划线(_)、点(.)和开头和结尾必须是字母或数字(都是字符串形式)的形式组成。前缀是可选的。如果指定了前缀,那么必须是 DNS 子域:一系列的 DNSlabel 通过”.”来划分,不超过 253 个字符,以斜杠(/)结尾。如果前缀被省略了,这个 Label 的 key 被假定为对用户私有的。自动化系统组件有(例如 kube-scheduler,kube-controller-manager,kube-apiserver,kubectl,或其他第三方自动化),这些添加标签终端用户对象都必须指定一个前缀。Kuberentes.io 前缀是为 k8s 内核部分保留的。

有效的标签值最长为 63 个字符。要么为空,要么使用[a-z0-9A-Z]带有虚线(-)、下划线(_)、点(.)和开头和结尾必须是字母或数字(都是字符串形式)的形式组成。

# Labels 选择器

与 Name 和 UID 不同,标签不需要有唯一性。一般来说,我们期望许多对象具有相同的标签。

通过标签选择器(Labels Selectors),客户端/用户 能方便辨识出一组对象。标签选择器是 k8s 中核心的组成部分。

API 目前支持两种选择器:equality-based(基于平等)和 set-based(基于集合)的。标签选择器可以由逗号分隔的多个 requirements 组成。在多重需求的情况下,必须满足所有要求,因此逗号分隔符作为 AND 逻辑运算符。

一个为空的标签选择器(即有 0 个必须条件的选择器)会选择集合中的每一个对象。

一个 null 型标签选择器(仅对于可选的选择器字段才可能)不会返回任何对象。

注意:两个控制器的标签选择器不能在命名空间中重叠。

# Equality-based requirement 基于相等的要求

基于相等的或者不相等的条件允许用标签的 keys 和 values 进行过滤。匹配的对象必须满足所有指定的标签约束,尽管他们可能也有额外的标签。有三种运算符是允许的,“=”,“==”和“!=”。前两种代表相等性(他们是同义运算符),后一种代表非相等性。例如:

environment = production
tier != frontend

第一个选择所有 key 等于 environment 值为 production 的资源。后一种选择所有 key 为 tier 值不等于 frontend 的资源,和那些没有 key 为 tier 的 label 的资源。要过滤所有处于 production 但不是 frontend 的资源,可以使用逗号操作符,

frontend:environment=production,tier!=frontend

# Set-based requirement

Set-based 的标签条件允许用一组 value 来过滤 key。支持三种操作符: in,notin 和 exists(仅针对于 key 符号)。例如:

environment in (production, qa)
tier notin (frontend, backend)
partition
!partition

第一个例子,选择所有 key 等于 environment,且 value 等于 production 或者 qa 的资源。 第二个例子,选择所有 key 等于 tier 且值是除了 frontend 和 backend 之外的资源,和那些没有标签的 key 是 tier 的资源。 第三个例子,选择所有有一个标签的 key 为 partition 的资源;value 是什么不会被检查。 第四个例子,选择所有的没有 lable 的 key 名为 partition 的资源;value 是什么不会被检查。

类似的,逗号操作符相当于一个 AND 操作符。因而要使用一个 partition 键(不管 value 是什么),并且 environment 不是 qa 过滤资源可以用 partition,environment notin (qa)。

Set-based 的选择器是一个相等性的宽泛的形式,因为 environment=production 相当于 environment in (production),与 != and notin 类似。

Set-based 的条件可以与 Equality-based 的条件结合。例如,partition in (customerA,customerB),environment!=qa。

# API

# LIST 和 WATCH 过滤

LIST 和 WATCH 操作可以指定标签选择器来过滤使用查询参数返回的对象集。这两个要求都是允许的(在这里给出,它们会出现在 URL 查询字符串中):

LIST 和 WATCH 操作,可以使用 query 参数来指定 label 选择器来过滤返回对象的集合。两种条件都可以使用:

  • Set-based 的要求:?labelSelector=environment%3Dproduction,tier%3Dfrontend
  • Equality-based 的要求:?labelSelector=environment+in+%28production%2Cqa%29%2Ctier+in+%28frontend%29

两个标签选择器样式都可用于通过 REST 客户端列出或观看资源。例如,apiserver 使用 kubectl 和使用基于平等的人可以写:

两种标签选择器样式,都可以通过 REST 客户端来 list 或 watch 资源。比如使用 kubectl 来针对 apiserver,并且使用 Equality-based 的条件,可以用:

$ kubectl get pods -l environment=production,tier=frontend

或使用 Set-based 要求:

$ kubectl get pods -l 'environment in (production),tier in (frontend)'

如已经提到的 Set-based 要求更具表现力。例如,它们可以对 value 执行 OR 运算:

$ kubectl get pods -l 'environment in (production, qa)'

或者通过 exists 操作符进行否定限制匹配:

$ kubectl get pods -l 'environment,environment notin (frontend)'

# API 对象中引用

一些 k8s 对象,例如 services 和 replicationcontrollers,也使用标签选择器来指定其他资源的集合,如 pod。

# Service 和 ReplicationController

一个 service 针对的 pods 的集合是用标签选择器来定义的。类似的,一个 replicationcontroller 管理的 pods 的群体也是用标签选择器来定义的。

对于这两种对象的 Label 选择器是用 map 定义在 json 或者 yaml 文件中的,并且只支持 Equality-based 的条件:

"selector": {
    "component" : "redis",
}

要么

selector:
    component: redis

此选择器(分别为 json 或 yaml 格式)等同于 component=redis 或 component in (redis)。

# 支持 set-based 要求的资源

Job,Deployment,Replica Set,和 Daemon Set,支持 set-based 要求。

selector:
  matchLabels:
    component: redis
  matchExpressions:
    - {key: tier, operator: In, values: [cache]}
    - {key: environment, operator: NotIn, values: [dev]}

matchLabels 是一个{key,value}的映射。一个单独的 {key,value} 相当于 matchExpressions 的一个元素,它的 key 字段是”key”,操作符是 In,并且 value 数组 value 包含”value”。 matchExpressions 是一个 pod 的选择器条件的 list。有效运算符包含 In, NotIn, Exists, 和 DoesNotExist。在 In 和 NotIn 的情况下,value 的组必须不能为空。所有的条件,包含 matchLabels andmatchExpressions 中的,会用 AND 符号连接,他们必须都被满足以完成匹配。

Last Updated: 6/17/2023, 6:57:19 PM