06.LabelSelector

Label

元数据围绕应用(Application)的概念进行组织,Kubernetes不是平台即服务(PaaS,没有或强制执行正式的应用程序概念相反,应用程序是非正式的,并使用元数据进行描述。应用程序包含的定义是松散的。一组通用的标签可以让多个工具之间相互操作,用所有工具都能理解的通用方式描述对象。

Label是附着到object上(例如Pod)的键值对。可以在创建object的时候指定,也可以在object创建后随时指定。Labels的值对系统本身并没有什么含义,只是对用户才有意义。

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

Kubernetes最终将对labels最终索引和反向索引用来优化查询和watch,在UI和命令行中会对它们排序。不要在label中使用大型、非标识的结构化数据,记录这样的数据应该用annotationLabel能够将组织架构映射到系统架构上(就像是康威定律,这样能够更便于微服务的管理,你可以给object打上如下类型的label

  • “release” : “stable”, “release” : “canary”
  • “environment” : “dev”, “environment” : “qa”, “environment” : “production”
  • “tier” : “frontend”, “tier” : “backend”, “tier” : “cache”
  • “partition” : “customerA”, “partition” : “customerB”
  • “track” : “daily”, “track” : “weekly”
  • “team” : “teamA”,“team:” : “teamB”

Label Selector

Label不是唯一的,很多object可能有相同的label。通过label selector,客户端/用户可以指定一个object集合,通过label selectorobject的集合进行操作。Label selector有两种类型:

  • equality-based:可以使用=、==、!=操作符,可以使用逗号分隔多个表达式
  • set-based:可以使用in、notin、!操作符,另外还可以没有操作符,直接写出某个labelkey,表示过滤有某个keyobject而不管该keyvalue是何值,!表示没有该labelobject
$ 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)'
$ kubectl get pods -l 'environment,environment notin (frontend)'

API Object

servicereplicationcontrollerobject中有对Podlabel selector,使用方法只能使用等于操作,例如:

selector:
  component: redis

Job、Deployment、ReplicaSetDaemonSet这些object中,支持set-based的过滤,例如:

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

Service通过label selector将同一类型的Pod作为一个服务expose出来。

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
        - matchExpressions:
            - key: kubernetes.io/e2e-az-name
              operator: In
              values:
                - e2e-az1
                - e2e-az2
    preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
            - key: another-node-label-key
              operator: In
              values:
                - another-node-label-value

推荐的标签

共享标签和注解都使用同一个前缀:app.kubernetes.io。没有前缀的标签是用户私有的。共享前缀可以确保共享标签不会干扰用户自定义的标签。为了充分利用这些标签,应该在每个资源对象上都使用它们:

描述 示例 类型
app.kubernetes.io/name 应用程序的名称 mysql 字符串
app.kubernetes.io/instance 用于唯一确定应用实例的名称 wordpress-abcxzy 字符串
app.kubernetes.io/version 应用程序的当前版本(例如,语义版本,修订版哈希等) 5.7.21 字符串
app.kubernetes.io/component 架构中的组件 database 字符串
app.kubernetes.io/part-of 此级别的更高级别应用程序的名称 wordpress 字符串
app.kubernetes.io/managed-by 用于管理应用程序的工具 helm 字符串

应用可以在Kubernetes集群中安装一次或多次。在某些情况下,可以安装在同一命名空间中。例如,可以不止一次地为不同的站点安装不同的WordPress。应用的名称和实例的名称是分别记录的。例如,某WordPress实例的app.kubernetes.io/namewordpress,而其实例名称表现为app.kubernetes.io/instance的属性值wordpress-abcxzy。这使应用程序和应用程序的实例成为可能是可识别的。应用程序的每个实例都必须具有唯一的名称。

案例:简单的无状态服务

考虑使用DeploymentService对象部署的简单无状态服务的情况。以下两个代码段表示如何以最简单的形式使用标签。下面的Deployment用于监督运行应用本身的pods

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/name: myservice
    app.kubernetes.io/instance: myservice-abcxzy

下面的Service用于暴露应用。

apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: myservice
    app.kubernetes.io/instance: myservice-abcxzy

案例:带有一个数据库的Web应用程序

考虑一个稍微复杂的应用:一个使用Helm安装的Web应用(WordPress,其中 使用了数据库(MySQL。以下代码片段说明用于部署此应用程序的对象的开始。以下Deployment的开头用于WordPress

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/name: wordpress
    app.kubernetes.io/instance: wordpress-abcxzy
    app.kubernetes.io/version: "4.9.4"
    app.kubernetes.io/managed-by: helm
    app.kubernetes.io/component: server
    app.kubernetes.io/part-of: wordpress

这个Service用于暴露WordPress

apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: wordpress
    app.kubernetes.io/instance: wordpress-abcxzy
    app.kubernetes.io/version: "4.9.4"
    app.kubernetes.io/managed-by: helm
    app.kubernetes.io/component: server
    app.kubernetes.io/part-of: wordpress

MySQL作为一个StatefulSet暴露,包含它和它所属的较大应用程序的元数据:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  labels:
    app.kubernetes.io/name: mysql
    app.kubernetes.io/instance: mysql-abcxzy
    app.kubernetes.io/version: "5.7.21"
    app.kubernetes.io/managed-by: helm
    app.kubernetes.io/component: database
    app.kubernetes.io/part-of: wordpress

Service 用于将MySQL作为WordPress的一部分暴露:

apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: mysql
    app.kubernetes.io/instance: mysql-abcxzy
    app.kubernetes.io/version: "5.7.21"
    app.kubernetes.io/managed-by: helm
    app.kubernetes.io/component: database
    app.kubernetes.io/part-of: wordpress

使用MySQLStatefulSetService,您会注意到有关MySQLWordpress的信息,包括更广泛的应用程序。

上一页