k8s-标签/亲和性/污点和容忍度

root
233
文章
0
评论
2021年8月8日00:25:50 评论 8780字阅读29分16秒

k8s-标签/亲和性/污点和容忍度

什么是标签?

标签其实就一对 key/value ,被关联到对象上,比如Pod,标签的使用我们倾向于能够表示对象的特殊特点,就是一眼就看出了这个Pod是干什么的,标签可以用来划分特定的对象(比如版本,服务类型等),标签可以在创建一个对象的时候直接定义,也可以在后期随时修改,每一个对象可以拥有多个标签,但是,key值必须是唯一的。创建标签之后也可以方便我们对资源进行分组管理。如果对pod打标签,之后就可以使用标签来查看、删除指定的pod。

在k8s中,大部分资源都可以打标签。

给pod资源打标签

#查看pod资源标签

[root@master01 ~]# kubectl get pod -o wide --show-labels 
NAME      READY   STATUS    RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES   LABELS
busybox   1/1     Running   0          33h   172.16.196.134   node01   <none>           <none>            run=busybox

#对已经存在的pod打标签

[root@master01 ~]# kubectl label pod -n default busybox hwf=123
pod/busybox labeled

 

#查看资源标签

#列出默认名称空间下标签值是的pod,不显示标签

[root@master01 ~]# kubectl get pod -l hwf
NAME      READY   STATUS    RESTARTS   AGE
busybox   1/1     Running   0          33h

#列出默认名称空间下标签key是的pod,不显示标签

[root@master01 ~]# kubectl get pod -L 123
NAME      READY   STATUS    RESTARTS   AGE   123
busybox   1/1     Running   0          33h

#给node打工作标签

[root@master01 ~]# kubectl label node node01 node-role.kubernetes.io/node01= 
node/node01 labeled
[root@master01 ~]# kubectl get node
NAME       STATUS     ROLES                  AGE    VERSION
master01   Ready      control-plane,master   2d9h   v1.21.3
master02   Ready      control-plane,master   2d9h   v1.21.3
node01     Ready      node01                 2d9h   v1.21.3
node02     NotReady   <none>                 2d9h   v1.21.3

#删除node标签

[root@master01 ~]# kubectl label node node01 node-role.kubernetes.io/node01-
node/node01 labeled

 

node节点选择器

我们在创建pod资源的时候,pod会根据schduler进行调度,那么默认会调度到随机的一个工作节点,如果我们想要pod调度到指定节点或者调度到一些具有相同特点的node节点,怎么办呢?

可以使用pod中的nodeName或者nodeSelector字段指定要调度到的node节点

1、nodeName:

指定pod节点运行在哪个具体node上

[root@master1 ~]# cat pod-node.yaml 
apiVersion: v1
kind: Pod
metadata:
     name: demo-pod
     namespace: default
     labels:
        app: myapp
        env: dev
    spec:
        nodeName: node1
        containers:
         -  name:  tomcat-pod-java
             ports:
             -  containerPort: 8080
             image: tomcat:8.5-jre8-alpine
             imagePullPolicy: IfNotPresent
             - name: busybox
             image: busybox:latest
             command:
             - "/bin/sh"
             - "-c"
             - "sleep 3600"

2、nodeSelector:[这种方法你node上要有对应的标签,标签选择器里填写]

指定pod调度到具有哪些标签的node节点上

[root@master1 ~]# cat pod-1.yaml 
apiVersion: v1
kind: Pod
metadata:
     name: demo-pod-1
     namespace: default
     labels:
         app: myapp
         env: dev
    spec:
         nodeSelector:
             disk: ceph
        containers:
        - name:  tomcat-pod-java
           ports:
           - containerPort: 8080
           image: tomcat:8.5-jre8-alpine
           imagePullPolicy: IfNotPresent

 

亲和性

node节点亲和性

基于node节点所打的标签,把pod调度到node上

node节点亲和性调度:nodeAffinity

space:
    affinity:                          #亲和性
       nodeAffinity:      <Object>      #node亲和性
           preferredDuringSchedulingIgnoredDuringExecution:       <[]Object> #表示有节点尽量满足这个位置定义的亲和性,这不是一个必须的条件,软亲和性
           requiredDuringSchedulingIgnoredDuringExecution:        <Object> #表示必须有节点满足这个位置定义的亲和性,这是个硬性条件,硬亲和性
               nodeSelectorTerms:                   #node 标签
               -   matchExpressions:      <[]Object>  #匹配表达式的
                    -   key: hwf       <string> -required- #检查label
                        operator:   <string> -required- #做等值选则还是不等值选则
                        values:     <[]string>          #给定值
                        -  123
                        -   xx
                -   matchFields:   <[]Object>    #匹配字段的
                     -   key:        <string> -required-
                         values:     <[]string>

例1:使用requiredDuringSchedulingIgnoredDuringExecution硬亲和性

[root@master1 ~]# cat pod-nodeaffinity-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
     name: pod-node-affinity-demo
     namespace: default
     labels:
         app: myapp
         tier: frontend
spec:
    containers:
    -  name: myapp
        image: ikubernetes/myapp:v1
    affinity:
        nodeAffinity:
            requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                 - matchExpressions:
                    -  key: zone
                       operator: In
                       values:
                       -  foo
                       -  bar

我们检查当前节点中有任意一个节点拥有zone标签的值是foo或者bar,就可以把pod调度到这个node节点的foo或者bar标签上的节点上

[root@master1 ~]# kubectl apply -f pod-nodeaffinity-demo.yaml 
[root@master1 ~]# kubectl get pods -o wide | grep pod-node
pod-node-affinity-demo             0/1     Pending     0   xianchaonode1          

status的状态是pending,上面说明没有完成调度,因为没有一个拥有zone的标签的值是foo或者bar,而且使用的是硬亲和性,必须满足条件才能完成调度

[root@master1 ~]# kubectl label nodes xianchaonode1 zone=foo

给这个xianchaonode1节点打上标签zone=foo,在查看

[root@xianchaomaster1 ~]#kubectl get pods -o wide 显示如下:
pod-node-affinity-demo             1/1     Running  0   xianchaonode1

例2:使用preferredDuringSchedulingIgnoredDuringExecution软亲和性

[root@xianchaomaster1 ~]# cat pod-nodeaffinity-demo-2.yaml 
apiVersion: v1
kind: Pod
metadata:
     name: pod-node-affinity-demo-2
     namespace: default
     labels:
         app: myapp
         tier: frontend
spec:
    containers:
    - name: myapp
       image: ikubernetes/myapp:v1
    affinity:
       nodeAffinity:
            preferredDuringSchedulingIgnoredDuringExecution:
             -  preference:
                 matchExpressions:
                 -  key: zone1
                    operator: In
                    values:
                    -  foo1
                    -  bar1
                 weight: 60
[root@xianchaomaster1 ~]# kubectl apply -f pod-nodeaffinity-demo-2.yaml
[root@xianchaomaster1 ~]# kubectl get pods -o wide |grep demo-2
pod-node-affinity-demo-2           1/1     Running     0        xianchaonode1

上面说明软亲和性是可以运行这个pod的,尽管没有运行这个pod的节点定义的zone1标签

 

Node节点亲和性针对的是pod和node的关系,Pod调度到node节点的时候匹配的条件

 

Pod节点亲和性

第一个pod随机选则一个节点,做为评判后续的pod能否到达这个pod所在的节点上的运行方式,这就称为pod亲和性;我们怎么判定哪些节点是相同位置的,哪些节点是不同位置的;我们在定义pod亲和性时需要有一个前提,哪些pod在同一个位置,哪些pod不在同一个位置,这个位置是怎么定义的,标准是什么?以节点名称为标准,这个节点名称相同的表示是同一个位置,节点名称不相同的表示不是一个位置。

  • 节点名称
  • 节点标签

 

pod自身的亲和性调度有两种表示形式:

  • podaffinity:pod和pod更倾向腻在一起,把相近的pod结合到相近的位置,如同一区域,同一机架,这样的话pod和pod之间更好通信,比方说有两个机房,这两个机房部署的集群有1000台主机,那么我们希望把nginx和tomcat都部署同一个地方的node节点上,可以提高通信效率;

例1:pod节点亲和性

定义两个pod,第一个pod做为基准,第二个pod跟着它走

[root@xianchaomaster1 ~]# cat pod-required-affinity-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
     name: pod-first
     labels:
        app2: myapp2
        tier: frontend
spec:
    containers:
    -   name: myapp
         image: ikubernetes/myapp:v1
---
apiVersion: v1
kind: Pod
metadata:
     name: pod-second
     labels:
        app: backend
        tier: db
spec:
    containers:
    -  name: busybox
        image: busybox:latest
        imagePullPolicy: IfNotPresent
        command: ["sh","-c","sleep 3600"]
    affinity:
        podAffinity:
            requiredDuringSchedulingIgnoredDuringExecution:
            -   labelSelector:
                    matchExpressions:
                    -   {key: app2, operator: In, values: ["myapp2"]}
                topologyKey: kubernetes.io/hostname

topologyKey: kubernetes.io/hostname

  • 不写具体表示第一个pod调度到哪个节点,第二个pod跟着调度到相同节点
  • 节点名称
  • 节点标签

#上面表示创建的pod必须与拥有app=myapp标签的pod在一个节点上

[root@master1 ~]# kubectl apply -f pod-required-affinity-demo.yaml 
kubectl get pods -o wide 显示如下:
pod-first              running        node1
pod-second           running       node1

 

  • podunaffinitypod和pod更倾向不腻在一起,如果部署两套程序,那么这两套程序更倾向于反亲和性,这样相互之间不会有影响。

例2:pod节点反亲和性

定义两个pod,第一个pod做为基准,第二个pod跟它调度节点相反

[root@master1 ~]# cat pod-required-anti-affinity-demo.yaml
apiVersion: v1
kind: Pod
metadata:
     name: pod-first
     labels:
        app1: myapp1
        tier: frontend
spec:
    containers:
    -  name: myapp
       image: ikubernetes/myapp:v1
---
apiVersion: v1
kind: Pod
metadata:
     name: pod-second
     labels:
        app: backend
        tier: db
spec:
    containers:
    -  name: busybox
        image: busybox:latest
        imagePullPolicy: IfNotPresent
        command: ["sh","-c","sleep 3600"]
    affinity:
       podAntiAffinity:
           requiredDuringSchedulingIgnoredDuringExecution:
           -  labelSelector:
                 matchExpressions:
                  -  {key: app1, operator: In, values: ["myapp1"]}
                 topologyKey: kubernetes.io/hostname

显示两个pod不在一个node节点上,这就是pod节点反亲和性

[root@master1 ~]# kubectl apply -f pod-required-anti-affinity-demo.yaml
[root@master1 ~]# kubectl get pods -o wide 显
pod-first            running       node1
pod-second           running        node2

例3:换一个topologykey,换成node标签【使用这种有可能一个对于pod创建先后顺序有要求】

[root@master1 ~]# kubectl label nodes  xianchaonode2  zone=foo
[root@master1 ~]# kubectl label nodes  xianchaonode1  zone=foo --overwrite
[root@xianchaomaster1]# cat pod-first-required-anti-affinity-demo-1.yaml
apiVersion: v1
kind: Pod
metadata:
     name: pod-first
     labels:
        app3: myapp3
        tier: frontend
spec:
    containers:
    -  name: myapp
        image: ikubernetes/myapp:v1
---
apiVersion: v1
kind: Pod
metadata:
     name: pod-second
     labels:
        app: backend
        tier: db
spec:
    containers:
    -   name: busybox
        image: busybox:latest
        imagePullPolicy: IfNotPresent
        command: ["sh","-c","sleep 3600"]
    affinity:
       podAntiAffinity:
           requiredDuringSchedulingIgnoredDuringExecution:
           -  labelSelector:
               matchExpressions:
                -   {key: app3 ,operator: In, values: ["myapp3"]}
               topologyKey:  zone
[root@master1 ~]#kubectl get pods -o wide 显示如下:
pod-first              running         xianchaonode1
pod-second           pending         <none>

第二个节点现是pending,因为两个节点是同一个位置,现在没有不是同一个位置的了,而且我们要求反亲和性,所以就会处于pending状态,如果在反亲和性这个位置把required改成

污点、容忍度

给了节点选则的主动权,我们给节点打一个污点,不容忍的pod就运行不上来,污点就是定义在节点上的键值属性数据,可以定决定拒绝那些pod;

taints是键值数据,用在节点上,定义污点;

tolerations是键值数据,用在pod上,定义容忍度,能容忍哪些污点

pod亲和性是pod属性;但是污点是节点的属性,污点定义在nodeSelector上

#查看节点的污点

[root@master01 ~]# kubectl describe nodes master01 |grep Taints:
Taints:             node-role.kubernetes.io/master:NoSchedule

Taint 给某个node节点设置污点

Taint 排斥效果

  • NoSchedule 仅影响调度过程,对现存的pod对象不产生影响;但容忍的pod同时也能够被分配到集群中的其它节点
  • NoExecute: 即影响调度过程,也影响现在的Pod对象;不容忍的Pod对象将被驱逐
  • PreferNoSchedule: 最好别调度过来,实在没地方了来这里也行
添加污点
Kubectl taint node node1 item-name=assistant:NoExecute
 
Kubectl taint node node2 item-name=sca:NoExecute
 
Kubectl taint node node3 item-name=xx:NoExecute

 

删除污点
kubectl taint node node1 item-name-
 
Kubectl taint node node2 item-name-
 
Kubectl taint node node3 item-name-

Pod容忍度

你只要pod上配置的策略和节点上的策略一致就能容忍你

[root@xianchaomaster1 ~]# kubectl explain node.spec.taints
KIND:     Node
VERSION:  v1
RESOURCE: taints <[]Object>
DESCRIPTION:
     If specified, the node's taints.
     The node this Taint is attached to has the "effect" on any pod that does
     not tolerate the Taint.
FIELDS:
   effect	<string> -required-
   key	<string> -required-
   timeAdded	<string>
   value	<string>

taints的effect用来定义对pod对象的排斥等级(效果):

  • NoSchedule 仅影响调度过程,对现存的pod对象不产生影响;但容忍的pod同时也能够被分配到集群中的其它节点
  • NoExecute: 即影响调度过程,也影响现在的Pod对象;不容忍的Pod对象将被驱逐
  • PreferNoSchedule: 最好别调度过来,实在没地方了来这里也行
 #两个值:Exists表示只要节点有这个污点的key,pod都能容忍,值是什么都行;Equal表示只要节点必须精确匹配污点的key和value才能容忍;

写法一:Equal等值,必须所有都匹配pod才会创建

  tolerations:                         #Pod容忍度
  -  key: "node-type"                   #key值
      operator: "Equal"                  #等值关系,等于
      value: "production"                #node-type/production:NoSchedule
      effect: "NoExecute"                #策略
      tolerationSeconds: 3600            #表示可以多存活3600秒,一般不用

写法二:Exists表示只要节点有这个污点的key,pod都能容忍,值是什么都行;

  tolerations:                                #Pod容忍度
   - key: "node-type"                   #key值
      operator: "Exists"                  #非等值关系
      value: ""                                 #node-type/production:NoSchedule
      effect: "NoExecute"               #策略

写法三:Exists表示只要节点有这个污点的key,pod都能容忍,值是什么都行;

  tolerations:                                #Pod容忍度
   - key: "node-type"                   #key值
     operator: "Exists"                   #非等值关系
     value: ""                                  #node-type/production:NoSchedule
     effect: ""                                 #策略

 

 

 

 

 

 

 

 

 

 

 

继续阅读
weinxin
我的微信
这是我的微信扫一扫
  • 文本由 发表于 2021年8月8日00:25:50
  • 除非特殊声明,本站文章均为原创,转载请务必保留本文链接
k8s-Service Account Kubernetes

k8s-Service Account

k8s-Service Account的授权管理 Service Account也是一种账号,是给运行在Pod里的进程提供了必要的身份证明。需要在Pod定义中指明引用的Service Account,...
k8s-RBAC Kubernetes

k8s-RBAC

k8s-RBAC认证授权策略 RBAC介绍 在Kubernetes中,所有资源对象都是通过API进行操作,他们保存在etcd里。而对etcd的操作我们需要通过访问 kube-apiserver 来实现...
k8s-Secret Kubernetes

k8s-Secret

配置管理中心Secret Secret是什么? Configmap一般是用来存放明文数据的,如配置文件,对于一些敏感数据,如密码、私钥等数据时,要用secret类型 Secret解决了密码、token...
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: