标签和选择器

标签是附加到 对象(例如 Pod)的键/值对。标签旨在用于指定对象的可识别属性,这些属性对用户有意义且相关,但不直接对核心系统产生语义影响。标签可用于组织和选择对象子集。标签可以在创建时附加到对象,随后可以随时添加和修改。每个对象可以定义一组键/值标签。对于给定的对象,每个键必须是唯一的。

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

标签允许进行高效的查询和监视,非常适合在 UI 和 CLI 中使用。非识别信息应使用 注释记录。

动机

标签使用户能够以松散耦合的方式将自己的组织结构映射到系统对象,而无需客户端存储这些映射。

服务部署和批量处理流水线通常是多维实体(例如,多个分区或部署、多个发布轨道、多个层级、每个层级多个微服务)。管理通常需要跨领域的操作,这打破了严格层次表示的封装,特别是基础设施而不是用户确定的严格层次结构。

示例标签

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

这些是 常用标签的示例;您可以自由开发自己的约定。请记住,对于给定的对象,标签键必须是唯一的。

语法和字符集

标签是键/值对。有效的标签键有两个部分:一个可选的前缀和一个名称,用斜杠 (/) 分隔。名称部分是必需的,必须少于或等于 63 个字符,以字母数字字符 ([a-z0-9A-Z]) 开头和结尾,中间可以包含连字符 (-)、下划线 (_)、点 (.) 和字母数字。前缀是可选的。如果指定,前缀必须是 DNS 子域:一系列用点 (.) 分隔的 DNS 标签,总长度不超过 253 个字符,后跟一个斜杠 (/)。

如果省略前缀,则标签键被假定为用户私有的。自动化系统组件(例如 kube-schedulerkube-controller-managerkube-apiserverkubectl 或其他第三方自动化)将标签添加到最终用户对象时,必须指定前缀。

kubernetes.io/k8s.io/ 前缀是 为 Kubernetes 核心组件保留的

有效的标签值

  • 必须少于或等于 63 个字符(可以为空),
  • 如果不为空,必须以字母数字字符 ([a-z0-9A-Z]) 开头和结尾,
  • 可以包含连字符 (-)、下划线 (_)、点 (.) 和字母数字。

例如,这是一个具有两个标签 environment: productionapp: nginx 的 Pod 的清单

apiVersion: v1
kind: Pod
metadata:
  name: label-demo
  labels:
    environment: production
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

标签选择器

名称和 UID 不同,标签不提供唯一性。通常,我们期望许多对象携带相同的标签。

通过标签选择器,客户端/用户可以识别一组对象。标签选择器是 Kubernetes 中的核心分组原语。

API 当前支持两种类型的选择器:基于相等性的基于集合的。标签选择器可以由多个需求组成,这些需求用逗号分隔。在多个需求的情况下,所有需求都必须满足,因此逗号分隔符充当逻辑 AND (&&) 运算符。

空或未指定的选择器的语义取决于上下文,并且使用选择器的 API 类型应记录其有效性和含义。

基于相等性的需求

基于相等性或不等性的需求允许按标签键和值进行筛选。匹配的对象必须满足所有指定的标签约束,尽管它们可能具有其他标签。允许三种运算符 ===!=。前两个表示相等性(并且是同义词),而后者表示不等性。例如

environment = production
tier != frontend

前者选择键等于 environment 且值等于 production 的所有资源。后者选择键等于 tier 且值不等于 frontend 的所有资源,以及没有 tier 键标签的所有资源。可以使用逗号运算符过滤 production 中排除 frontend 的资源:environment=production,tier!=frontend

基于相等性的标签要求的用例之一是 Pod 指定节点选择标准。例如,下面的 Pod 选择具有 accelerator 标签且设置为 nvidia-tesla-p100 的节点。

apiVersion: v1
kind: Pod
metadata:
  name: cuda-test
spec:
  containers:
    - name: cuda-test
      image: "registry.k8s.io/cuda-vector-add:v0.1"
      resources:
        limits:
          nvidia.com/gpu: 1
  nodeSelector:
    accelerator: nvidia-tesla-p100

基于集合的需求

基于集合的标签要求允许根据一组值筛选键。支持三种运算符:innotinexists(仅键标识符)。例如

environment in (production, qa)
tier notin (frontend, backend)
partition
!partition
  • 第一个示例选择键等于 environment 且值等于 productionqa 的所有资源。
  • 第二个示例选择键等于 tier 且值不等于 frontendbackend 的所有资源,以及没有 tier 键标签的所有资源。
  • 第三个示例选择包含键 partition 的所有资源;不检查任何值。
  • 第四个示例选择不包含键 partition 的所有资源;不检查任何值。

同样,逗号分隔符充当 AND 运算符。因此,可以使用 partition,environment notin (qa) 过滤具有 partition 键(无论值如何)且 environment 不等于 qa 的资源。基于集合的标签选择器是相等性的通用形式,因为 environment=production 等效于 environment in (production);同样适用于 !=notin

基于集合的需求可以与基于相等性的需求混合。例如:partition in (customerA, customerB),environment!=qa

API

LIST 和 WATCH 过滤

对于 listwatch 操作,您可以指定标签选择器以过滤返回的对象集;您使用查询参数指定过滤器。(要详细了解 Kubernetes 中的监视,请阅读 高效检测更改)。允许两种需求(此处显示为它们在 URL 查询字符串中显示的方式)

  • 基于相等性的需求?labelSelector=environment%3Dproduction,tier%3Dfrontend
  • 基于集合的需求?labelSelector=environment+in+%28production%2Cqa%29%2Ctier+in+%28frontend%29

可以使用这两种标签选择器样式通过 REST 客户端列出或监视资源。例如,使用 kubectl 针对 apiserver 并使用基于相等性的样式,可以编写

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

或使用基于集合的需求

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

如前所述,基于集合的需求更具表现力。例如,它们可以实现值上的运算符

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

或者通过notin 运算符限制否定匹配

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

API 对象中的集合引用

一些 Kubernetes 对象,例如 servicesreplicationcontrollers,也使用标签选择器来指定其他资源集合,例如 pods

服务和复制控制器

服务的目标 Pod 集合由标签选择器定义。 同样,复制控制器应该管理的 Pod 集合也由标签选择器定义。

对于这两个对象,标签选择器都定义在 jsonyaml 文件中使用映射,并且仅支持基于相等的需求选择器

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

或者

selector:
  component: redis

此选择器(分别以 jsonyaml 格式)等效于 component=rediscomponent in (redis)

支持基于集合的需求的资源

较新的资源,例如 JobDeploymentReplicaSetDaemonSet,也支持基于集合的需求。

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

matchLabels{key,value} 对的映射。 matchLabels 映射中的单个 {key,value} 等效于 matchExpressions 的一个元素,其 key 字段为“key”,operator 为“In”,并且 values 数组仅包含“value”。 matchExpressions 是 Pod 选择器需求的列表。 有效的运算符包括 In、NotIn、Exists 和 DoesNotExist。 对于 In 和 NotIn,值集必须非空。 来自 matchLabelsmatchExpressions 的所有需求都是通过 AND 连接的——它们都必须满足才能匹配。

选择 Pod 集合

使用标签选择的一个用例是约束 Pod 可以调度的节点集合。 有关更多信息,请参阅有关 节点选择的文档。

有效使用标签

您可以将单个标签应用于任何资源,但这并不总是最佳实践。 在许多情况下,应使用多个标签来区分资源集合。

例如,不同的应用程序将对 app 标签使用不同的值,但多层应用程序(例如 guestbook 示例)还需要区分每个层级。 前端可以携带以下标签

labels:
  app: guestbook
  tier: frontend

而 Redis 主节点和副本将具有不同的 tier 标签,甚至可能还有一个额外的 role 标签

labels:
  app: guestbook
  tier: backend
  role: master

labels:
  app: guestbook
  tier: backend
  role: replica

标签允许沿着标签指定的任何维度对资源进行切片和分类

kubectl apply -f examples/guestbook/all-in-one/guestbook-all-in-one.yaml
kubectl get pods -Lapp -Ltier -Lrole
NAME                           READY  STATUS    RESTARTS   AGE   APP         TIER       ROLE
guestbook-fe-4nlpb             1/1    Running   0          1m    guestbook   frontend   <none>
guestbook-fe-ght6d             1/1    Running   0          1m    guestbook   frontend   <none>
guestbook-fe-jpy62             1/1    Running   0          1m    guestbook   frontend   <none>
guestbook-redis-master-5pg3b   1/1    Running   0          1m    guestbook   backend    master
guestbook-redis-replica-2q2yf  1/1    Running   0          1m    guestbook   backend    replica
guestbook-redis-replica-qgazl  1/1    Running   0          1m    guestbook   backend    replica
my-nginx-divi2                 1/1    Running   0          29m   nginx       <none>     <none>
my-nginx-o0ef1                 1/1    Running   0          29m   nginx       <none>     <none>
kubectl get pods -lapp=guestbook,role=replica
NAME                           READY  STATUS   RESTARTS  AGE
guestbook-redis-replica-2q2yf  1/1    Running  0         3m
guestbook-redis-replica-qgazl  1/1    Running  0         3m

更新标签

有时您可能希望在创建新资源之前重新标记现有的 Pod 和其他资源。 这可以使用 kubectl label 来完成。 例如,如果您想将所有 NGINX Pod 标记为前端层级,请运行

kubectl label pods -l app=nginx tier=fe
pod/my-nginx-2035384211-j5fhi labeled
pod/my-nginx-2035384211-u2c7e labeled
pod/my-nginx-2035384211-u3t6x labeled

这首先过滤掉带有标签 "app=nginx" 的所有 Pod,然后用 "tier=fe" 标记它们。 要查看您标记的 Pod,请运行

kubectl get pods -l app=nginx -L tier
NAME                        READY     STATUS    RESTARTS   AGE       TIER
my-nginx-2035384211-j5fhi   1/1       Running   0          23m       fe
my-nginx-2035384211-u2c7e   1/1       Running   0          23m       fe
my-nginx-2035384211-u3t6x   1/1       Running   0          23m       fe

这将输出所有 "app=nginx" Pod,以及一个带有 Pod 的层级的附加标签列(使用 -L--label-columns 指定)。

有关更多信息,请参阅 kubectl label

接下来

最后修改时间为 2025 年 9 月 24 日下午 7:20 PST:修复 guestbook 示例的损坏链接 (67ca9a9898)