k8s label & Selectors

k8s label & Selectors

label简介

在部署实际应用时,每个人创建的pod越来越多,把他们分类到子集的需求开始明显,我们需要一种能基于任意标准,将上述pod组织成更小群体的方式,标签满足了上述需求,不仅可以组织pod,也可以组织k8s的其他资源,确切来说,标签就是附着在资源上的键值对,一个资源可以有多个标签,就像一件商品上打了多个标签,标签1:牛肉,标签2:产地中国,Labels其实就一对 key/value ,被关联到对象上,标签的使用我们倾向于能够标示对象的特殊特点
app:指定pod属于那个应用,组件或者微服务
rel:它显示在pod中运行的程序版本是stable,beta还是canary

Labels选择器

与Name和UID 不同,标签不需要有唯一性。一般来说,我们期望许多对象具有相同的标签。
通过标签选择器(Labels Selectors),客户端/用户 能方便辨识出一组对象。标签选择器是kubernetes中核心的组成部分。
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的条件可以与Equality-based的条件结合。例如, partition in (customerA,customerB),environment!=qa 。

API

LIST和WATCH过滤

两个标签选择器样式都可用于通过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对象中引用

一些Kubernetes对象,例如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符号连接,他们必须都被满足以完成匹配。

创建pod时指定标签

我们可以将pod调度到某个确定的节点,由于每个节点都有一个 唯 一标签 , 其中键为kuberne七es.io/hostname, 值为该 节点的实际主机名,因此我们也可以将pod调度到某个确定的节点。但如果节点处于离线状态,pod就没法调度,环境起不来了,所以不能指定固定机器。

apiVersion: v1
kind: ReplicationController
metadata:
  name: frontend
spec:
  replicas: 3
  selector:
    app: nginx //这里的nginx是下面app的子集
	//version: v1  //这里加个标签,如果下面的template里面没有version,那就会报错
  template:
    metadata:
      labels:
        app: nginx //这里的标签可以比上面多,这里可以有的,上面不可以没有
    spec:
      containers:
      - name: php-redis
        image: wangyanglinux/myapp:v1
        env:
        - name: GET_HOSTS_FROM
          value: dns
          name: zhangsan
          value: "123"
        ports:
        - containerPort: 80

根据标签查询资源

列出pod的标签
rancher kubectl get pods --show-labels --namespace=liuyinghui22041901

根据两个标签得到key筛选pod
rancher kubectl get pods -L app,pod-template-hash --namespace=liuyinghui22041901

给pod添加一个标签
rancher kubectl label pod redis-6fbf8768c8-jpqjt type=redis --namespace=liuyinghui22041901
给pod修改一个标签

如果修改已经存在的一个标签,在添加标签的基础上加个 --overwrite就可以了

rancher kubectl label pod redis-6fbf8768c8-jpqjt type=redis --overwrite --namespace=liuyinghui22041901
获取指定标签的pod

注意这里的l是小写

rancher kubectl get pods -l app=redis --namespace=liuyinghui22041901
筛选排除不带type标签的pod
rancher kubectl get pods -l  '!type' --namespace=liuyinghui22041901
给node添加标签

前面说到可以给k8s的各个资源添加标签,给node加标签后可以控制pod部署在哪台node上

kubectl label node slave01  productline=ecs2
posted @ 2022-04-21 16:13  liwenchao1995  阅读(273)  评论(0编辑  收藏  举报