标签和选择器
标签是附加到 对象(例如 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-scheduler
、kube-controller-manager
、kube-apiserver
、kubectl
或其他第三方自动化)必须指定前缀。
kubernetes.io/
和 k8s.io/
前缀是 为 Kubernetes 核心组件保留的。
有效的标签值
- 必须不超过 63 个字符(可以为空),
- 除非为空,否则必须以字母数字字符 (
[a-z0-9A-Z]
) 开头和结尾, - 可以包含破折号 (
-
)、下划线 (_
)、点 (.
) 和字母数字字符。
例如,下面是一个 Pod 的清单,该 Pod 具有两个标签 environment: production
和 app: nginx
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 当前支持两种类型的选择器:基于相等性和基于集合。标签选择器可以由多个用逗号分隔的要求组成。在多个要求的情况下,所有要求都必须满足,因此逗号分隔符充当逻辑与 (&&
) 运算符。
空选择器或未指定选择器的语义取决于上下文,使用选择器的 API 类型应记录其有效性和含义。
注意
对于某些 API 类型(例如 ReplicaSet),两个实例的标签选择器在命名空间内不得重叠,否则控制器可能会将其视为冲突指令,并且无法确定应该存在的副本数量。警告
对于基于相等性和基于集合的条件,都没有逻辑或 (||
) 运算符。请确保您的筛选器语句的结构正确。基于相等性的要求
基于相等性或基于不等性的要求允许按标签键和值进行筛选。匹配的对象必须满足所有指定的标签约束,但它们也可能具有其他标签。允许使用三种运算符:=
、==
、!=
。前两个表示相等性(并且是同义词),而后者表示不等性。例如
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
基于集合的要求
基于集合的标签要求允许根据一组值筛选键。支持三种运算符:in
、notin
和 exists
(仅限键标识符)。例如
environment in (production, qa)
tier notin (frontend, backend)
partition
!partition
- 第一个示例选择键等于
environment
且值等于production
或qa
的所有资源。 - 第二个示例选择键等于
tier
且值不是frontend
和backend
的所有资源,以及没有带有tier
键的标签的所有资源。 - 第三个示例选择包含带有键
partition
的标签的所有资源;不检查值。 - 第四个示例选择没有带有键
partition
的标签的所有资源;不检查值。
类似地,逗号分隔符充当与运算符。因此,可以使用 partition,environment notin (qa)
来筛选具有 partition
键(无论值是什么)并且 environment
不等于 qa
的资源。基于集合的标签选择器是相等性的一般形式,因为 environment=production
等价于 environment in (production)
;!=
和 notin
也是如此。
基于集合的要求可以与基于相等性的要求混合使用。例如:partition in (customerA, customerB),environment!=qa
。
API
LIST 和 WATCH 筛选
LIST 和 WATCH 操作可以指定标签选择器,以使用查询参数筛选返回的对象集。两种要求都是允许的(此处显示的是它们在 URL 查询字符串中的显示方式)
- 基于相等性的要求:
?labelSelector=environment%3Dproduction,tier%3Dfrontend
- 基于集合的要求:
?labelSelector=environment+in+%28production%2Cqa%29%2Ctier+in+%28frontend%29
两种标签选择器样式都可以用于通过 REST 客户端列出或监视资源。例如,以 apiserver
为目标并使用 kubectl
和基于相等性的选择器,可以编写
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 对象,例如 服务
和 复制控制器
,也使用标签选择器来指定其他资源集,例如 Pod。
服务和复制控制器
服务
所针对的 Pod 集是使用标签选择器定义的。类似地,复制控制器
应管理的 Pod 群体也是使用标签选择器定义的。
两个对象的标签选择器都在 json
或 yaml
文件中使用映射定义,并且仅支持基于相等性的要求选择器
"selector": {
"component" : "redis",
}
或
selector:
component: redis
此选择器(分别为 json
或 yaml
格式)等效于 component=redis
或 component in (redis)
。
支持基于集合的要求的资源
较新的资源,例如 Job
、Deployment
、ReplicaSet
和 DaemonSet
,也支持基于集合的要求。
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 的情况下,值集必须为非空。来自 matchLabels
和 matchExpressions
的所有要求都进行 AND 运算 - 它们必须全部满足才能匹配。
选择节点集
选择标签的一个用例是限制 Pod 可以调度到的节点集。有关更多信息,请参阅有关 节点选择 的文档。
有效使用标签
您可以将单个标签应用于任何资源,但这并不总是最佳实践。在许多情况下,应该使用多个标签来区分资源集。
例如,不同的应用程序将对 app
标签使用不同的值,但多层应用程序(例如 留言板示例)还需要区分每一层。前端可以带有以下标签
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。
下一步
- 了解如何 向节点添加标签
- 查找 众所周知的标签、注释和污点
- 查看 推荐的标签
- 使用命名空间标签实施 Pod 安全标准
- 阅读有关 为 Pod 标签编写控制器 的博客