k8s中label和label selector的基本概念及使用方法
1、概述
在k8s中,有一个非常核心的概念,就是label(标签),以及对label的使用,label selector。
本文档中,我们就来看看:1、什么是标签,2、如何定义标签,3、什么是标签选择器,4、如何使用标签选择器
2、label(标签)
2.1、定义
标签这个概念和现实生活中的标签也没有什么两样,如,苹果是水果,冰箱是家电,都是一种标签,类似的,在k8s中,一个label就是一个key/value对(envronment:online)。
这个标签可以由使用者自己来进行定义,然后附加到k8s中的资源对象上,比如,pod上,node上等等。
2.2、特性
label有如下的一些特点:
- label可以被附加到各种资源对象上
- 一个资源对象可以定义任意数量的label
- 同一个label可以被添加到任意数量的资源对象上
这些特性,在稍后的实验中,我们会通过一个个的示例进行展示··· ···
3、label selector(标签选择器)
当我们给一组对象,比如有10个pod,打上了不同的标签之后,当我们要选择其中的部分,或者全部作为使用目标的时候,就可以使用label selector来实现这个操作,标签选择器中指定具体的过滤的条件,然后,就能在10个pod中过滤出满足我们要求的这些pod
4、实验
我们在这里通过一系列的实验来看下label的一些特性和使用的方法
4.1、定义标签
可以在创建pod的定义文件中,指定标签
apiVersion: apps/v1 kind: Deployment metadata: name: pod-label spec: selector: matchLabels: app: nginx env: prod replicas: 1 template: metadata: labels: app: nginx env: prod spec: containers: - image: 172.20.58.152/middleware/nginx:1.21.4 name: nginx
在pod的模板中,通过以下的方式来定义label
labels: app: nginx env: prod
创建pod,并且查看标签
[root@nccztsjb-node-23 ~]# kubectl get pod --show-labels NAME READY STATUS RESTARTS AGE LABELS pod-label-794855697c-5xllw 1/1 Running 0 2m17s app=nginx,env=prod,pod-template-hash=794855697c [root@nccztsjb-node-23 ~]#
可以看到pod的不同的标签。
在另外多创建几个pod包含不同的标签
kubectl apply -f - <<eof apiVersion: apps/v1 kind: Deployment metadata: name: pod-label02 spec: selector: matchLabels: app: nginx02 env: prod replicas: 1 template: metadata: labels: app: nginx02 env: prod spec: containers: - image: 172.20.58.152/middleware/nginx:1.21.4 name: nginx eof
kubectl apply -f - <<eof apiVersion: apps/v1 kind: Deployment metadata: name: pod-label03 spec: selector: matchLabels: app: nginx03 env: dev replicas: 1 template: metadata: labels: app: nginx03 env: dev spec: containers: - image: 172.20.58.152/middleware/nginx:1.21.4 name: nginx eof
kubectl apply -f - <<eof apiVersion: apps/v1 kind: Deployment metadata: name: pod-label04 spec: selector: matchLabels: app: nginx04 env: dev replicas: 1 template: metadata: labels: app: nginx04 env: dev release: stable spec: containers: - image: 172.20.58.152/middleware/nginx:1.21.4 name: nginx eof
创建完pod之后,可以看到pod对应的标签,和pod ip
[root@nccztsjb-node-23 ~]# kubectl get pod --show-labels -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS pod-label-794855697c-5xllw 1/1 Running 0 11m 172.39.157.195 nccztsjb-node-24 <none> <none> app=nginx,env=prod,pod-template-hash=794855697c pod-label02-6c65d6c4dc-vs7mb 1/1 Running 0 6m59s 172.39.157.196 nccztsjb-node-24 <none> <none> app=nginx02,env=prod,pod-template-hash=6c65d6c4dc pod-label03-b7b6c5bc4-wwkqj 1/1 Running 0 4m11s 172.39.157.198 nccztsjb-node-24 <none> <none> app=nginx03,env=dev,pod-template-hash=b7b6c5bc4 pod-label04-648998c747-km45q 1/1 Running 0 5s 172.39.21.90 nccztsjb-node-25 <none> <none> app=nginx04,env=dev,pod-template-hash=648998c747,release=stable [root@nccztsjb-node-23 ~]#
4.2、label selector
我们可以通过标签选择器,或者说标签选择来筛选出来满足我们要求的对象。
所谓的标签选择就是过滤。有几种方式,可以使用,比如在命令行中,或者在资源对象的定义文件中
这里,我们就以命令行作为实验,列出来几个场景:
- 过滤出所有包含,env=dev的pod
[root@nccztsjb-node-23 ~]# kubectl get pod -l env=dev --show-labels NAME READY STATUS RESTARTS AGE LABELS pod-label03-b7b6c5bc4-wwkqj 1/1 Running 0 8m56s app=nginx03,env=dev,pod-template-hash=b7b6c5bc4 pod-label04-648998c747-km45q 1/1 Running 0 4m50s app=nginx04,env=dev,pod-template-hash=648998c747,release=stable [root@nccztsjb-node-23 ~]#
从结果来看,也确实是我们需要的。
- 过滤出来,包含env=prod,app=nginx的pod
[root@nccztsjb-node-23 ~]# kubectl get pod -l 'env=prod,app=nginx' --show-labels NAME READY STATUS RESTARTS AGE LABELS pod-label-794855697c-5xllw 1/1 Running 0 18m app=nginx,env=prod,pod-template-hash=794855697c [root@nccztsjb-node-23 ~]#
env=prod,app=nginx 2个标签中间通过逗号隔开,表示2个条件要同时的满足,也就是AND的关系。
- 过滤出来包含app=nginx或者app=nginx02或者app=nginx03的pod
[root@nccztsjb-node-23 ~]# kubectl get pod -l 'app in (nginx,nginx02,nginx03)' --show-labels NAME READY STATUS RESTARTS AGE LABELS pod-label-794855697c-5xllw 1/1 Running 0 21m app=nginx,env=prod,pod-template-hash=794855697c pod-label02-6c65d6c4dc-vs7mb 1/1 Running 0 16m app=nginx02,env=prod,pod-template-hash=6c65d6c4dc pod-label03-b7b6c5bc4-wwkqj 1/1 Running 0 13m app=nginx03,env=dev,pod-template-hash=b7b6c5bc4 [root@nccztsjb-node-23 ~]#
'app in (nginx,nginx02,nginx03)' 通过in的方式进行选择,与SQL一样
- 过滤出来包含app=nginx或者app=nginx02或者app=nginx03,同时env=prod的pod
[root@nccztsjb-node-23 ~]# kubectl get pod -l 'env=prod,app in (nginx,nginx02,nginx03)' --show-labels NAME READY STATUS RESTARTS AGE LABELS pod-label-794855697c-5xllw 1/1 Running 0 23m app=nginx,env=prod,pod-template-hash=794855697c pod-label02-6c65d6c4dc-vs7mb 1/1 Running 0 18m app=nginx02,env=prod,pod-template-hash=6c65d6c4dc [root@nccztsjb-node-23 ~]#
'env=prod,app in (nginx,nginx02,nginx03)',逗号分隔2个条件,表示要同时的满足
- 过滤出来不包含app=nginx01和app=nginx03的pod
[root@nccztsjb-node-23 ~]# kubectl get pod -l 'app notin (nginx,nginx03)' --show-labels NAME READY STATUS RESTARTS AGE LABELS pod-label02-6c65d6c4dc-vs7mb 1/1 Running 0 21m app=nginx02,env=prod,pod-template-hash=6c65d6c4dc pod-label04-648998c747-km45q 1/1 Running 0 14m app=nginx04,env=dev,pod-template-hash=648998c747,release=stable [root@nccztsjb-node-23 ~]#
语法:'app notin (nginx,nginx03)' ,用notin来实现
- 过滤出来不是env=dev的pod
[root@nccztsjb-node-23 ~]# kubectl get pod -l 'env != dev' --show-labels NAME READY STATUS RESTARTS AGE LABELS pod-label-794855697c-5xllw 1/1 Running 0 43m app=nginx,env=prod,pod-template-hash=794855697c pod-label02-6c65d6c4dc-vs7mb 1/1 Running 0 39m app=nginx02,env=prod,pod-template-hash=6c65d6c4dc [root@nccztsjb-node-23 ~]#
语法:'env != dev'
这样,就通过标签实现了一个基本的过滤,同时,当一个资源对象要和另外的对象进行关联的时候,比如,service要关联pod,也是通过label过滤的方式来实现的。
上面是在命令行中的一个基本的使用。
在yaml中的使用也是类似的,只是要放在Selector的部分。
5、yaml配置中的标签选择表达式
5.1、基于等式的匹配
在上面的命令行的实验中,我们看了在命令行中,如何来进行选择,其实在yaml定义中的使用是类似的,主要是定义在selector的部分
在后面的例子中,我们以service为示例,来测试下标签的选择
我们上面的实验中,已经创建了几个pod,我们这里创建service来进行关联
- 创建service,关联env=prod的pod
apiVersion: v1 kind: Service metadata: name: service-label spec: ports: - name: 80-80 port: 80 protocol: TCP targetPort: 80 selector: env: prod
查看创建好的service和对应的endpoint
[root@nccztsjb-node-23 ~]# kubectl get svc service-label -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR service-label ClusterIP 10.105.151.148 <none> 80/TCP 72s env=prod [root@nccztsjb-node-23 ~]# kubectl get endpoints service-label NAME ENDPOINTS AGE service-label 172.39.157.195:80,172.39.157.196:80 78s [root@nccztsjb-node-23 ~]# kubectl get pod -l 'env=prod' NAME READY STATUS RESTARTS AGE pod-label-794855697c-5xllw 1/1 Running 0 49m pod-label02-6c65d6c4dc-vs7mb 1/1 Running 0 45m [root@nccztsjb-node-23 ~]# kubectl get pod -l 'env=prod' -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-label-794855697c-5xllw 1/1 Running 0 49m 172.39.157.195 nccztsjb-node-24 <none> <none> pod-label02-6c65d6c4dc-vs7mb 1/1 Running 0 45m 172.39.157.196 nccztsjb-node-24 <none> <none> [root@nccztsjb-node-23 ~]#
可以看到,service恰好就是关联到了这2个pod上了。
所以,service中的label selector就是放到selector的部分了
selector: env: prod
- 选择env=prod,并且app=nginx的pod
kubectl apply -f - <<eof apiVersion: v1 kind: Service metadata: name: service-label01 spec: ports: - name: 80-80 port: 80 protocol: TCP targetPort: 80 selector: env: prod app: nginx eof
这里的过滤条件是2个,就是同时满足的意思
selector: env: prod app: nginx
查看service关联的pod的结果
这里正好是关联到了一个pod上。
5.2、基于集合的匹配
注意:job,deployment,replicaset,daemonset不仅仅支持基于等式的匹配,也支持基于集合的匹配。
在yaml中使用基于集合的方式的标签的匹配
kubectl apply -f - <<eof apiVersion: apps/v1 kind: Deployment metadata: name: pod-label05 spec: selector: matchLabels: app: nginx05 env: online replicas: 1 template: metadata: labels: app: nginx05 env: online release: stable spec: containers: - image: 172.20.58.152/middleware/nginx:1.21.4 name: nginx eof
matchlabels用于匹配一组的标签,与直接在selector中的作用相同
[root@nccztsjb-node-23 ~]# kubectl get deployment pod-label05 -o wide NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR pod-label05 1/1 1 1 65s nginx 172.20.58.152/middleware/nginx:1.21.4 app=nginx05,env=online [root@nccztsjb-node-23 ~]# kubectl get pod pod-label05-575777f4dd-r7ndb -o wide --show-labels NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS pod-label05-575777f4dd-r7ndb 1/1 Running 0 67s 172.39.157.193 nccztsjb-node-24 <none> <none> app=nginx05,env=online,pod-template-hash=575777f4dd,release=stable [root@nccztsjb-node-23 ~]#
这样,deployment就和要控制、管理的pod进行了关联。
另外,在集合的方式里,matchExpression也可以作为匹配的操作
比如:
kubectl apply -f - <<eof apiVersion: apps/v1 kind: Deployment metadata: name: pod-label06 spec: selector: matchLabels: app: nginx06 env: online matchExpressions: - {key: release, operator: In, values: [stable] } - {key: app,operator: NotIn, values: [nginx02,nginx03] } replicas: 1 template: metadata: labels: app: nginx06 env: online release: stable spec: containers: - image: 172.20.58.152/middleware/nginx:1.21.4 name: nginx eof
语法:
matchExpressions: - {key: release, operator: In, values: [stable] } - {key: app,operator: NotIn, values: [nginx02,nginx03] }
在这里面用表达式进行label的匹配
OK,以上就介绍了label和label selector的用法