YAZONG 我的开源

Kubernetes(九)资源对象(9.4)Label---小标签大作为

  , , ,
0 评论0 浏览

Label是什么,本质是什么

就是Key=value

那么KEY和value是自己定义的。

image.png

上述二者的用法很灵活。

可以贴到各种各样的资源上。贴很形象,贴标签,POD、deployment、service、NODE上。静态的。

这样的设置,可以利用标签做很多事情,同样的标签可以贴到多个资源上,可以有相同的标签。

同一个资源也可以有任意多个不同的标签。

这种规则的设定,就可以让K8S利用标签做很多的事情。

最常见的,每个deployments都配置了标签,给它启动的POD都打上了相同的标签,可以让副本控制器知道哪些POD是自己的。Service也是类似的。

标签也可以用来区分节点,比如计算能力非常强的节点,可以给其打一个标签如cpu=better,磁盘大的可以打一个标签如disk=better。

也可以用来区分一些类型,如前端的服务type=front,后端的服务type=backend,这样不同的应用就可以区分开,跑在不同的节点上。

上面这些场景,可能不能马上反映过来是如何实现的。

在实际场景中,看一下label是怎么用起来的。

Label是静态的。

K8S如何把label标签利用起来的呢?K8S设计了一个概念,叫selector选择器。

Selector选择器

原始配置文件:web-dev.yaml

[root@node-1 ~]# cd deep-in-kubernetes/3-label/
[root@node-1 3-label]# cat web-dev.yaml
#deploy
apiVersion: apps/v1
kind: Deployment
metadata:
#从上到下,web-demo这个名字最好保持一致!
#
  name: web-demo-new
  namespace: dev
spec:
#本质上,deployment跟POD之间还有一个叫RC(replication controller)副本控制器,这个在1.6之后的版本有意隐藏了这个概念,对用户可见的只有deployment。
#其实这里的selector是作用于RC上的,知道就行了,不用太多关注。
  selector:
#K8S如何把label标签利用起来的呢?K8S设计了一个概念,叫selector选择器。
#匹配的标签matchLabels,通过它标签的key:app=web-demo
    matchLabels:
#意思是这个deploy只负责具有app=web-demo这样标签的POD。
#这里selector的web-demo和template的web-demo名字必须一样!否则副本控制器RC就没法管理POD了。
      app: web-demo
  replicas: 1
  template:
#这个deploy在创建POD的时候,根据什么配置把这个模板创建起来。
#根据template模板配置把这个POD创建起来。
    metadata:
      labels:
        app: web-demo
#这里selector的web-demo和template的web-demo名字必须一样!否则副本控制器RC就没法管理POD了。
    spec:
      containers:
      - name: web-demo
        image: hub.mooc.com/kubernetes/web:v1
        ports:
        - containerPort: 8080
---
#service
apiVersion: v1
kind: Service
metadata:
  name: web-demo
  namespace: dev
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8080
  selector:
#service下也有一个selector,名字和值。
#通过这个selector就可以发现,带有这个label标签的POD。
    app: web-demo
  type: ClusterIP

---
#ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: web-demo
  namespace: dev
spec:
  rules:
  - host: web-dev.mooc.com
    http:
      paths:
      - path: /
        backend:
          serviceName: web-demo
          servicePort: 80




[root@node-1 3-label]# kubectl apply -f web-dev.yaml

测试:Deployment与selector

#不同的Deployment有两个相同的selector,它们之间是不冲突的。都是一个实例。
[root@node-1 3-label]# kubectl get deploy -n dev
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
web-demo       1/1     1            1           13m
web-demo-new   1/1     1            1           4m33s

(1)本质上,deployment跟POD之间还有一个叫RC(replication controller)副本控制器,这个在1.6之后的版本有意隐藏了这个概念,对用户可见的只有deployment,其实这里的selector是作用于RC上的,知道就行了,不用太多关注。

(2)虽然在dev环境也有label=web-demo的POD,新建的也是这个label,但是这俩没冲突,因为这一个selector副本控制器是属于一个deployment,在上一级就已经区分开了,不同的deployment,下层选择相同的key和value也没事,它们之间不可见,不冲突。

(3)这就是deployment里面和RC副本控制器里面是如何使用selector和label把它结合起来使用的。

[root@node-1 3-label]# kubectl get pods -n dev
NAME                            READY   STATUS    RESTARTS   AGE
web-demo-67d9dcc6fc-vsmrr       1/1     Running   0          10m
web-demo-new-6cd856cd4d-x692f   1/1     Running   0          100s

测试:Service与selector

#测试这个service下的selector会不会把新建的selector和旧的混在一起呢?

[root@node-1 3-label]# kubectl get pods
NAME                            READY   STATUS    RESTARTS   AGE
web-demo-67d9dcc6fc-vsmrr       1/1     Running   0          22m
web-demo-new-6cd856cd4d-x692f   1/1     Running   0          13m
#设置原有web-dev.yaml对应的POD中的内容
[root@node-1 3-label]# kubectl exec -it web-demo-67d9dcc6fc-vsmrr -n dev bash
bash-4.4# cd webapps/
bash-4.4# cd examples/
bash-4.4# echo "hello world" > index.html 
#访问web-dev.mooc.com

image.png

#这里出现了roundbin的负载均衡,说明service给负载到了两个deployment,说明跟deployment是无关的,它只是通过label选择了所有带这个标签的POD。

#两个不同的页面,当同一个服务有不同的版本的时候,可能给A用户看A版本,给B用户看B版本,这个时候就显得比较有用了。

label用法:In(Group)

#上述是service对label的selector的机制。

#上述都是app=xx相等的操作,除了这个相等的还有其他条件的操作。

比如in范围内、not in不在范围内、不等于,类似于这种操作。

[root@node-1 3-label]# vim web-dev.yaml
(这里的spec是最靠左边的spec)

image.png

spec:
  selector:
    matchLabels:
      app: web-demo
    matchExpressions:
      - {key: group, operator: In, values: [dev, test]}

(一定要注意空格!)

在matchLabels的同一级可以配置一个matchExpressions。

当这俩matchLabels和matchExpressions是同时存在的时候,这俩是一个和的关系,app必须=web-demo ,并且在其他配置项也要满足。比如上述values{}中的内容,group在这俩环境都可以。这些条件的操作,要在template模板里都有体现,才能执行成功这个文件。

[root@node-1 3-label]# kubectl apply -f web-dev.yaml

image.png

#这里的报错,意思是这个selector并没有选择下面template的POD,既然这个selector选中不了自己这个POD,那么这个selector就没什么用了。

#基于上述的错误,修改后测试

image.png

spec:
  selector:
    matchLabels:
      app: web-demo
    matchExpressions:
      - {key: group, operator: In, values: [dev, test]}
  replicas: 1
  template:
    metadata:
      labels:
        group: dev
        app: web-demo
    spec:
      containers:
      - name: web-demo
        image: hub.mooc.com/kubernetes/web:v1
        ports:
        - containerPort: 8080

#基于上述错误,那么在这里加入group: dev,来满足其要求。这样matchExpressions就可以选中这个值了。疑问:上面配置了,为啥下面还配置呢?这样配置一个地方不就好了?重复的配置了。其实大部分的情况是这样的,如果group组是一个整体的话,大家都配这一份,比如带这个label标签,就selector这个标签。

#再次测试

image.png

#说明Selector一旦创建就不能修改了。
[root@node-1 3-label]# kubectl delete -f web-dev.yaml
#先删除再创建。这也是K8S防止出错的一种措施。Selector一旦被定义了,其实就不应该被修改。
[root@node-1 3-label]# kubectl apply -f web-dev.yaml

PodPreset

但是K8S的这些设计比较灵活,有一种用法叫做POD的预设:PodPreset,允许把模板template里的一些东西交给一波人去维护。

K8S允许把template模板交给一部分人去维护 ,简单,更适合开发人员。

上面的是一些公有的、通用的东西,这些交给另一拨人,运维去维护。

当应用真正要去创建的时候,才会把这俩以某种方式组合在一起,放在一个配置文件里,这样的配置就可以起到一个很好的校验作用,预先避免一些问题的发生。

label用法:指定label

#除了在配置文件里使用label和selector之外,还可以通过kubectl命令来使用label和selector。

可以通过-l指定一个label。

#意思是可以通过标签来过滤资源。

[root@node-1 3-label]# kubectl get pods -l group=dev -n dev
NAME                            READY   STATUS    RESTARTS   AGE
web-demo-new-59c9749d74-45tvj   1/1     Running   0          98s
#选择另一个标签
[root@node-1 3-label]# kubectl get pods -l app=web-demo -n dev
NAME                            READY   STATUS    RESTARTS   AGE
web-demo-67d9dcc6fc-vsmrr       1/1     Running   0          81m
web-demo-new-59c9749d74-45tvj   1/1     Running   0          110s

#多个条件的过滤
[root@node-1 3-label]# kubectl get pods -l app=web-demo,group=dev -n dev 
NAME                            READY   STATUS    RESTARTS   AGE
web-demo-new-59c9749d74-45tvj   1/1     Running   0          2m38s

#更灵活的方法
[root@node-1 3-label]# kubectl get pods -l 'group in (dev, test)' -n dev
NAME                            READY   STATUS    RESTARTS   AGE
web-demo-new-59c9749d74-45tvj   1/1     Running   0          4m17s
[root@node-1 3-label]# kubectl get pods -l 'group notin (dev, test)' -n dev
NAME                        READY   STATUS    RESTARTS   AGE
web-demo-67d9dcc6fc-vsmrr   1/1     Running   0          83m

label用法:选择nodeSelector

#label其他用法(之前的label作用于deployment、POD)还可以作用于node,还可以选择node的selector。)

[root@node-1 3-label]# cat web-dev.yaml

image.png

spec:
  containers:
  - name: web-demo
	image: hub.mooc.com/kubernetes/web:v1
	ports:
	- containerPort: 8080
#containers同级配置一个nodeSelector。磁盘类型: ssd。这里每个node都没这个label。
  nodeSelector:
	disktype: ssd
[root@node-1 3-label]# kubectl apply -f web-dev.yaml -n dev

[root@node-1 3-label]# kubectl get pods -n dev
NAME                            READY   STATUS    RESTARTS   AGE
web-demo-67d9dcc6fc-vsmrr       1/1     Running   0          102m
web-demo-new-59c9749d74-45tvj   1/1     Running   0          23m
web-demo-new-78cc59778d-4vvgn   0/1     Pending   0          61s
[root@node-1 3-label]# kubectl describe pods web-demo-new-78cc59778d-4vvgn -n dev
  Warning  FailedScheduling  18s (x3 over 90s)  default-scheduler  0/2 nodes are available: 2 node(s) didn't match Pod's node affinity.

#这个pending的POD,说明没有找到合适的节点去调度(看describe、logs、节点),因为指定了disktype=ssd,所以需要给node也打一个标签,至少要有这样一个节点。

[root@node-1 3-label]# kubectl label node node-2 disktype=ssd
[root@node-1 3-label]# kubectl get nodes --show-labels

image.png

#label其他用法,其他的看官网。


标题:Kubernetes(九)资源对象(9.4)Label---小标签大作为
作者:yazong
地址:https://blog.llyweb.com/articles/2022/11/19/1668800559102.html