前言:
kubernetes集群不是简单的安装部署就完事了,还需要根据业务的性质设定一些策略,比如,某些pod不希望被调度到硬件条件比较差的节点,某些pod又希望调度到含有比如有特定的硬件GPU的节点上。又或者某个节点由于硬件资源比如CPU,内存并没有彻底耗尽,但如果在继续调度pod到此节点有造成集群崩溃的风险,如何阻止并驱逐此节点在运行的pod,以及集群需要检修或者重建某个节点,此时的节点上运行的pod应该如何处置等等各种各样的问题以及解决方案就形成了pod调度策略,驱逐策略,污点、容忍调度策略。
说人话,这些也可以说是kubernetes集群的优化策略。下面将就以上提出的情况和一些没有提到过的情况做一个总结吧!!!
主要的pod调度策略:
- 自由调度:pod运行在哪个节点完全由scheduler经过一系列算法计算得出(如果没有定向调度,亲和性,容忍策略,此策略就是默认的啦)
- 定向调度:采用nodeName、nodeSelector来实现pod定向调度(pod面向节点)
- 亲和性调度:NodeAffinityinity、PodAffinity、PodAntiAffinity
- 污点、容忍调度:Taints、Toleration(前面讲过了)
一,
节点维护状态(cordon,uncordon,drain):
节点情况举例:
例如有三个节点,k8s-node1,k8s-node2,k8s-master
[root@master ~]# k get no NAME STATUS ROLES AGE VERSION k8s-master Ready <none> 25d v1.18.3 k8s-node1 Ready <none> 25d v1.18.3 k8s-node2 Ready <none> 25d v1.18.3
现有两个pod在节点2运行,其中pod kube-flannel-ds-mlb7l是daemonsets方式部署,是核心组件:
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES default busybox-7bf6d6f9b5-jg922 1/1 Running 2 24d 10.244.0.11 k8s-master <none> <none> default nginx-7c96855774-28b5w 1/1 Running 2 24d 10.244.0.12 k8s-master <none> <none> default nginx-7c96855774-d592j 1/1 Running 0 4h44m 10.244.0.13 k8s-master <none> <none> default nginx1 1/1 Running 2 24d 10.244.2.11 k8s-node2 <none> <none> kube-system coredns-76648cbfc9-lb75g 1/1 Running 2 24d 10.244.2.10 k8s-node2 <none> <none> kube-system kube-flannel-ds-mhkdq 1/1 Running 7 24d 192.168.217.17 k8s-node1 <none> <none> kube-system kube-flannel-ds-mlb7l 1/1 Running 6 24d 192.168.217.18 k8s-node2 <none> <none> kube-system kube-flannel-ds-sl4qv 1/1 Running 2 24d 192.168.217.16 k8s-master <none> <none>
假如现在需要维护node2节点,那么,先需要驱逐node2节点上的所有pod,pod方式部署的直接驱逐,daemonsets的忽略:
[root@master ~]# k drain k8s-node2 --force --ignore-daemonsets node/k8s-node2 already cordoned WARNING: deleting Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet: default/nginx1; ignoring DaemonSet-managed Pods: kube-system/kube-flannel-ds-mlb7l evicting pod default/nginx1 evicting pod kube-system/coredns-76648cbfc9-lb75g pod/coredns-76648cbfc9-lb75g evicted pod/nginx1 evicted node/k8s-node2 evicted
结果是这样的:
可以看到,coredns这个pod漂移到了node1,pod方式部署的nginx直接销毁了,kube-flannel-ds-mlb7l没有变动
[root@master ~]# k get po -A -owide NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES default busybox-7bf6d6f9b5-jg922 1/1 Running 2 24d 10.244.0.11 k8s-master <none> <none> default nginx-7c96855774-28b5w 1/1 Running 2 24d 10.244.0.12 k8s-master <none> <none> default nginx-7c96855774-d592j 1/1 Running 0 4h52m 10.244.0.13 k8s-master <none> <none> kube-system coredns-76648cbfc9-z8kh5 1/1 Running 0 2m2s 10.244.1.8 k8s-node1 <none> <none> kube-system kube-flannel-ds-mhkdq 1/1 Running 7 24d 192.168.217.17 k8s-node1 <none> <none> kube-system kube-flannel-ds-mlb7l 1/1 Running 6 24d 192.168.217.18 k8s-node2 <none> <none> kube-system kube-flannel-ds-sl4qv 1/1 Running 2 24d 192.168.217.16 k8s-master <none> <none>
这个时候的节点是部分禁用的(这里的意思是scheduler服务不会调度新的pod到此节点,但,如果强制nodeselector,仍然会运行新pod)
此时的scheduler不会调度新pod到node2节点
[root@master ~]# k get no NAME STATUS ROLES AGE VERSION k8s-master Ready <none> 25d v1.18.3 k8s-node1 Ready <none> 25d v1.18.3 k8s-node2 Ready,SchedulingDisabled <none> 25d v1.18.3
节点维护状态和解除节点维护状态:
[root@master coredns]# k cordon k8s-node2 node/k8s-node2 cordoned [root@master coredns]# k uncordon k8s-node2 node/k8s-node2 uncordoned
小结:
cordon,uncordon,drain这三个命令主要是用在节点维护场景,drain有安全驱逐pod的功能,pod会实现漂移,但此驱逐并非硬性驱逐,管不了pod的指定调度策略。
适用范围是比较窄的哦,比如,使用了本地存储卷的pod或者有状态pod不适合使用drain,因为drain了相关服务就完蛋了。
二,
taints--节点污点
关于污点的解释:
[root@master coredns]# k 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- Required. The effect of the taint on pods that do not tolerate the taint. Valid effects are NoSchedule, PreferNoSchedule and NoExecute. key <string> -required- Required. The taint key to be applied to a node. timeAdded <string> TimeAdded represents the time at which the taint was added. It is only written for NoExecute taints. value <string> The taint value corresponding to the taint key.
taint的子选项effect有三个结果定义:
1,NoSchedule:表示k8s将不会将Pod调度到具有该污点的Node上 2,PreferNoSchedule:表示k8s将尽量避免将Pod调度到具有该污点的Node上 3,NoExecute:表示k8s将不会将Pod调度到具有该污点的Node上,同时会将Node上已经存在的Pod驱逐出去
污点的设置:
例如设置node2节点污点为NoExecute(这里的key=value 可以随意设置,比如,A=B:noExecute也是OK的,但最好有意义,后面的容忍会用到key和values的值):
kubectl taint nodes k8s-node2 key=value:NoExecute
查看节点和pod(可以看到,node2不可调度,并且其上的pod都被Terminating,因为busybox这个pod我是设置了nodeSelector ):
[root@master coredns]# k get no NAME STATUS ROLES AGE VERSION k8s-master Ready <none> 25d v1.18.3 k8s-node1 Ready <none> 25d v1.18.3 k8s-node2 Ready,SchedulingDisabled <none> 25d v1.18.3 [root@master coredns]# k get po -A -owide NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES default busybox-68c4f6755d-24f79 0/1 Terminating 0 18s <none> k8s-node2 <none> <none> default busybox-68c4f6755d-26f5j 0/1 Terminating 0 34s <none> k8s-node2 <none> <none> default busybox-68c4f6755d-28m4l 0/1 Terminating 0 42s <none> k8s-node2 <none> <none> default busybox-68c4f6755d-2bb7z 0/1 Terminating 0 39s <none> k8s-node2 <none> <none> default busybox-68c4f6755d-2gkss 0/1 Terminating 0 4s <none> k8s-node2 <none> <none> default busybox-68c4f6755d-2gpq4 0/1 Terminating 0 87s <none> k8s-node2 <none> <none> kube-system kube-flannel-ds-mlb7l 1/1 Terminating 6 25d 192.168.217.18 k8s-node2 <none> <none>
解除污点:
kubectl taint nodes k8s-node2 key:NoExecute- kubectl uncordon k8s-node2
污点的查看:
[root@master ~]# kubectl describe nodes k8s-node2 |grep Taints Taints: key=value:NoSchedule
OK,现在node2有污点,此节点不调度新pod,那么,我们来部署一个三副本的pod看看能否成功:
[root@master coredns]# cat test.yaml apiVersion: apps/v1 kind: Deployment metadata: name: busybox namespace: default spec: replicas: 3 selector: matchLabels: app: busybox template: metadata: labels: app: busybox spec: # nodeName: k8s-node2 containers: - name: busybox image: busybox:1.28.3 imagePullPolicy: IfNotPresent args: - /bin/sh - -c - sleep 10; touch /tmp/healthy; sleep 30000
可以看到,pod确实没有在node2上,即使副本数修改为10个,仍然是不会调度到node2这个节点。
[root@master coredns]# k get po -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES busybox-7bf6d6f9b5-5qzfn 1/1 Running 0 44s 10.244.1.10 k8s-node1 <none> <none> busybox-7bf6d6f9b5-j72q7 1/1 Running 0 44s 10.244.0.14 k8s-master <none> <none> busybox-7bf6d6f9b5-mgt8j 1/1 Running 0 44s 10.244.0.15 k8s-master <none> <none>
关于污点的小结:
污点存在的意义:
使用 kubectl taint 命令可以给某个 node节点设置污点,Node 被设置上污点之后就和 Pod 之间存在了一种互斥的关系,可以让 Node 拒绝 Pod 的调度执行,甚至将 Node 已经存在的 Pod 驱逐出去:
key=value:effect
通过给节点设置不同的污点,可以制定一个总的策略,例如,新节点使用effect NoExecute,那么,想在此节点运行pod就必须是有设置tolerations(容忍策略)的特定pod了,无疑安全性会大大提高,一般master节点是不建议运行非核心服务的pod的,因此,也可以给master打上NoSchedule污点,以保护master。
稍作总结,三种污点effect里,NoSchedule和PreferNoSchedule是比较温和的,NoExecute是最为严厉的,即使pod设置了nodeSelector或者nodeSelectorTerm,设置了此effect的节点也是不可使用的,也可以算是真正的节点禁用,因此,NoExecute是慎用的。
NoSchedule等于是节点维护状态,PreferNoSchedule等于是无所谓,你非要调度到这个节点也行。
以上都是面向某个节点内的所有pod调度,未免对于pod的调度不够精细,例如,NoExecute直接将节点内的pod全部清空,太暴力了(虽然这么做,整个节点的安全性非常高,和iptables防火墙一样的策略嘛,先禁止所有,然后在放开部分,相当于tolerations,其实这也是容忍存在的意义嘛)。那么,下面的调度策略将针对的是单个pod。
污点的effect可以设置多个
三,
容忍策略---tolerations
容忍是相对于污点来说的,容忍是在pod内设置的。光说不练假把式对吧,直接看kube-flannel的部署清单文件内的相关内容吧:
apiVersion: apps/v1 kind: DaemonSet metadata: name: kube-flannel-ds namespace: kube-system labels: tier: node app: flannel spec: selector: matchLabels: app: flannel template: metadata: labels: tier: node app: flannel spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/os operator: In values: - linux hostNetwork: true priorityClassName: system-node-critical tolerations: - operator: Exists effect: NoSchedule
此段容忍表示,默认的容忍污点的effec 是NoSchedule的节点,也就是说即使此node节点设置了NoSchedule,该pod仍然可以部署,为什么是这样设置呢?其实此清单文件是可以使用在kubeadmin部署的集群内,默认的kubeadmin部署的集群会对master节点设置NoSchedule的污点。
查看node2的污点(假设我已经提前设置好了污点):
[root@master coredns]# k describe node k8s-node2 |grep Taints Taints: key=values:NoExecute
此pod将不会被创建:
[root@master coredns]# cat nginx.yaml apiVersion: v1 kind: Pod metadata: name: pod-nodeaffinity-preferred namespace: default spec: containers: - name: nginx image: nginx:1.18 affinity: #亲和性设置 nodeAffinity: #设置node亲和性 preferredDuringSchedulingIgnoredDuringExecution: # 软限制 - weight: 1 preference: matchExpressions: # 匹配env的值在["xxx","yyy"]中的标签(当前环境没有) - key: nodeweb operator: In values: ["dsfsd","web"] nodeName: k8s-node2
修改成如下的pod才可以被创建(容忍三行):
apiVersion: v1 kind: Pod metadata: name: nginx namespace: default spec: containers: - name: nginx image: nginx:1.18 tolerations: - operator: Exists effect: NoExecute affinity: #亲和性设置 nodeAffinity: #设置node亲和性 preferredDuringSchedulingIgnoredDuringExecution: # 软限制 - weight: 1 preference: matchExpressions: # 匹配env的值在["xxx","yyy"]中的标签(当前环境没有) - key: nodeweb operator: In values: ["dsfsd","web"] nodeName: k8s-node2
容忍定义小结:
- 污点和容忍是相呼应的关系,也就是说有污点才有容忍,光有容忍是没有意义的。
- operator的值只有两个Equal和Exists两个,从字面翻译看,Equal表示必须相等,Exists表示默认情况。
- operator 的值为 Exists 时将会忽略 value 值,也可以直接省略values定义。
- operator 的值为 Exists 时可以省略key值,此时表示表示容忍所有的污点 key,例如:
tolerations: - operator: “Exists”
- effect可以省略,省略effect 值时,表示容忍所有的污点作用,例如:
tolerations: - key: “key” operator: “Exists”
下面是一个比较完整的示例:
tolerations: - key: “key1” operator: “Equal” value: “value1” effect: “NoSchedule” tolerationSeconds: 3600 - key: “key1” operator: “Equal” value: “value1” effect: “NoExecute” - key: “key2” operator: “Exists” effect: “NoSchedule”
三,
pod调度策略
这些策略都是写在资源清单文件内的,针对单独的pod
默认情况下,一个pod被调度到哪个node节点是由scheduler组件采用相应的算法计算出来的,这个过程是不受人工控制的,但是在实际使用中,这并不能满足所以要求,很多时候我们想控制某些pod到达某些节点,所以kubernetes就为我们提供了4种pod的调度策略来解决该问题。
(1)定向调度
主要是指定pod定向调度到哪个node节点上
a)
nodeName策略
注:kubectl集群节点名nodeName称可以通过kubectl get nodes查看,例如本例:
[root@master coredns]# k get no
NAME STATUS ROLES AGE VERSION
k8s-master Ready <none> 25d v1.18.3
k8s-node1 Ready <none> 25d v1.18.3
k8s-node2 Ready <none> 25d v1.18.3
资源清单文件内使用:
[root@master coredns]# cat nginx.yaml apiVersion: v1 kind: Pod metadata: name: pod-nodename namespace: default spec: containers: - name: nginx image: nginx:1.18 nodeName: k8s-node1 # 指定调度到node1节点上,注意此字段是pod属性,所以和containers在同一列
毫无疑问,此pod必定会在node2节点运行,即使有drain或者train设置了NoScheduler
b)
NodeSelector策略
NodeSelector用于将pod调度到添加了指定标签的node节点上。它是通过kubernetes的label-selector机制实现的,也就是说,在pod创建之前,会由scheduler使用MatchNodeSelector调度策略进行label匹配,找出目标node,然后将pod调度到目标节点,该匹配规则是强制约束。简单的说就是给kubectl集群的node节点打上标签,然后调度器将pod调度到指定标签的node上。
例如给node2节点设置标签,并查询标签:
kubectl label nodes k8s-node2 node=LAMP [root@master coredns]# k get nodes --show-labels NAME STATUS ROLES AGE VERSION LABELS k8s-master Ready <none> 25d v1.18.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master,kubernetes.io/os=linux k8s-node1 Ready <none> 25d v1.18.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node1,kubernetes.io/os=linux k8s-node2 Ready <none> 25d v1.18.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node2,kubernetes.io/os=linux,node=LAMP
截取资源清单文件相关部分:
volumes: - name: mysql-persistent-storage persistentVolumeClaim: claimName: mysql-pvc #对应到pvc的名字 nodeSelector: node: LAMP
这里说明一哈,比如kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node2,这个是kubernetes.io/arch架构相关的,因此,这个是没法使用的。而我们新建的标签是kubernetes.io/os级别,操作系统类的,因此可以使用。
(2)
亲和性pod调度
pod和node节点标签之间的定向调度
上面的定向调度还是比较粗糙的方式,因为如果我们设置了定向调度,但标签忘记打了,或者标签写错了,nodeSelector又设置了,那么部署将会变成pending。无疑,我们还是希望每次的部署都是成功的,因此,我们需要一种或者几种更为精细的pod调度。
a)
NodeAffinity(节点亲和性)
pod.spec.affinity.nodeAffinity requiredDuringSchedulingIgnoredDuringExecution Node节点必须满足指定的所有规则才可以,相当于硬限制(找不到会调度失败) nodeSelectorTerms 节点选择列表 matchFields 按节点字段列出的节点选择器要求列表 matchExpressions 按节点标签列出的节点选择器要求列表(推荐) key 键 values 值 operator 关系符 支持Exists(存在), DoesNotExist(不存在), In(范围), NotIn(范围取反), Gt(大于), Lt(小于) preferredDuringSchedulingIgnoredDuringExecution 优先调度到满足指定的规则的Node,相当于软限制 (倾向,找不到不会调度失败) preference 一个节点选择器项,与相应的权重相关联 matchFields 按节点字段列出的节点选择器要求列表 matchExpressions 按节点标签列出的节点选择器要求列表(推荐) key 键 values 值 operator 关系符 支持In, NotIn, Exists, DoesNotExist, Gt, Lt weight 倾向权重,在范围1-100。
关系符operator的使用说明:
- matchExpressions: - key: nodeenv # 匹配存在标签的key为nodeenv的节点,只匹配key就行 operator: Exists - key: nodeenv # 匹配标签的key为nodeenv,且value是"xxx"或"yyy"的节点,key和value都要匹配 operator: In values: ["xxx","yyy"] - key: nodeenv # 匹配标签的key为nodeenv,且value大于"xxx"的节点 operator: Gt values: "xxx"
例子1:
apiVersion: v1 kind: Pod metadata: name: nginx namespace: default spec: containers: - name: nginx image: nginx:1.18 tolerations: - operator: Exists effect: NoExecute nodeName: k8s-node2 affinity: #亲和性设置 nodeAffinity: #申明是node亲和策略 requiredDuringSchedulingIgnoredDuringExecution: # 硬限制 nodeSelectorTerms: - matchExpressions: # 匹配env的值在["web","dev"]中的标签,实际没有设置此标签,所以会匹配失败 - key: node operator: In values: ["web","dev"]
这个亲和策略表示只要node标签里有web或者dev就可以成功部署此pod,否则,必定不能部署,现在先运行一哈,查看pod的状态,可以看到状态是NodeAffinity ,部署不成功:
[root@master coredns]# k get po -A -owide NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES default nginx 0/1 NodeAffinity 0 18s <none> k8s-node2 <none> <none> kube-system coredns-76648cbfc9-87fc7 1/1 Running 1 12h 10.244.0.17 k8s-master <none> <none> kube-system kube-flannel-ds-2jqg2 1/1 Running 0 111m 192.168.217.17 k8s-node1 <none> <none> kube-system kube-flannel-ds-jd6p7 1/1 Running 0 111m 192.168.217.16 k8s-master <none> <none> kube-system kube-flannel-ds-k4qx9 1/1 Running 0 105m 192.168.217.18 k8s-node2 <none> <none>
那么,现在就给node1设置标签值为web吧:
kubectl label nodes k8s-node1 node=dev
再次部署就会成功了。
例子2:
[root@master coredns]# cat nginx.yaml apiVersion: v1 kind: Pod metadata: name: pod-nodeaffinity-preferred namespace: default spec: containers: - name: nginx image: nginx:1.18 affinity: #亲和性设置 nodeAffinity: #设置node亲和性 preferredDuringSchedulingIgnoredDuringExecution: # 软限制 - weight: 1 preference: matchExpressions: # 匹配env的值在["xxx","yyy"]中的标签(当前环境没有) - key: nodeenv operator: In values: ["3432","ewrew"]
这里设置的values是我随便乱写的,自然是随便调度到了某个节点,如果确实有,那自然会调度成功。
(3)
PodAffinity(Pod亲和性)
pod亲和性是相对pod来说的,比如,A pod已经在某个节点或者作用域运行了,现在B pod需要和A pod在同一个节点或者作用域运行,反亲和就是A pod不和B pod在同一个node或者作用域。
PodAffinity的可配置项:
pod.spec.affinity.podAffinity requiredDuringSchedulingIgnoredDuringExecution 硬限制 namespaces 指定参照pod的namespace topologyKey 指定调度作用域 labelSelector 标签选择器 matchExpressions 按节点标签列出的节点选择器要求列表(推荐) key 键 values 值 operator 关系符 支持In, NotIn, Exists, DoesNotExist. matchLabels 指多个matchExpressions映射的内容 preferredDuringSchedulingIgnoredDuringExecution 软限制 podAffinityTerm 选项 namespaces topologyKey labelSelector matchExpressions key 键 values 值 operator matchLabels weight 倾向权重,在范围1-100
topologyKey用于指定调度时作用域,例如: 如果指定为kubernetes.io/hostname,那就是以Node节点为区分范围 如果指定为beta.kubernetes.io/os,则以Node节点的操作系统类型来区分 这些都是node节点的标签在管理,例如有的集群有beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64 也可能有arrch架构的操作系统
这里weight权重的作用是,一个pod节点可以有多个软策略,每个软策略可以有不同的权重,然后根据权重由高到选择不同软策略,直到选中符合条件的节点。如果设置了多个软策略,权重价值就体现出来了。比如张三节点权重为4,先看看三节点符不符合选中条件,不符合,再看权重为3的李四节点符不符合选中条件...直到找到符合选中条件的节点。也就是说,权重按值高低来确定,越高越优先
例子1:
有一个A pod,此pod有如下pod标签并设置了nodename:
labels: podenv: pro #设置标签
硬策略B pod:
apiVersion: v1 kind: Pod metadata: name: pod-podaffinity-required namespace: default spec: containers: - name: nginx image: nginx:1.18 affinity: #亲和性设置 podAffinity: #设置pod亲和性 requiredDuringSchedulingIgnoredDuringExecution: # 硬限制 - labelSelector: #标签选择器 matchExpressions: # 匹配env的值在["xxx","yyy"]中的标签 - key: podenv operator: In values: ["fdsfdsf","pro"] topologyKey: kubernetes.io/hostname #调度作用域,即如果匹配到,就调度到目标pod同一节点上
上面配置表达的意思是:新Pod必须要与拥有标签podenv=fdsfdsf或者podenv=pro的pod在同一Node上
关于PodAffinity的 preferredDuringSchedulingIgnoredDuringExecution(软策略),这里不再演示,和硬策略基本一样。
,
(4)
PodAntiAffinity(Pod反亲和性)
PodAntiAffinity主要实现以运行的Pod为参照,让新创建的Pod跟参照pod不在一个区域中的功能。
它的配置方式和选项跟PodAffinty是基本一样的,只修改一个地方即可,其余的都一样
affinity: #亲和性设置 podAntiAffinity: #设置pod亲和性
那么,符合条件的Apod将不会和Bpod部署到一起。
资源限制策略:
资源限制策略指的是某些场景如节点 NotReady,或者某一个节点的硬件资源达到预设阈值后,节点内的pod就进入驱逐状态。
硬件资源限制主要是有kube-controller-manager和kubelet这两个核心服务来进行的,也就是它们的配置文件来设定阈值的,一般kube-controller-manager是不做设定,主要是由kubelet设定。
以二进制安装的集群为例,在config文件内配置:
kind: KubeletConfiguration apiVersion: kubelet.config.k8s.io/v1beta1 address: 0.0.0.0 port: 10250 readOnlyPort: 10255 cgroupDriver: cgroupfs clusterDNS: - 10.0.0.2 clusterDomain: cluster.local failSwapOn: false authentication: anonymous: enabled: false webhook: cacheTTL: 2m0s enabled: true x509: clientCAFile: /opt/kubernetes/ssl/ca.pem authorization: mode: Webhook webhook: cacheAuthorizedTTL: 5m0s cacheUnauthorizedTTL: 30s evictionHard: imagefs.available: 15% memory.available: 100Mi nodefs.available: 10% nodefs.inodesFree: 5% maxOpenFiles: 1000000 maxPods: 110
关于硬驱逐的阈值, nodefs.available: 10%表示节点服务器剩余磁盘空间小于百分之10就触发,那么,现在在node1节点上有两个pod在运行:
[root@master cfg]# k get po -A -owide NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES default pod-nodeaffinity-preferred 1/1 Running 0 133m 10.244.1.16 k8s-node1 <none> <none> kube-system coredns-76648cbfc9-z8kh5 1/1 Running 1 8h 10.244.1.9 k8s-node1 <none> <none> kube-system kube-flannel-ds-99lsb 1/1 Running 1 6h42m 192.168.217.16 k8s-master <none> <none> kube-system kube-flannel-ds-w2kjl 1/1 Running 6 6h42m 192.168.217.17 k8s-node1 <none> <none> kube-system kube-flannel-ds-xdm6r 1/1 Running 0 6h22m 192.168.217.18 k8s-node2 <none> <none>
将nodefs.available: 10%修改为nodefs.available: 90%,然后在重启node1节点上的kubelet会发生什么呢?
答案是该节点的所有pod会转成Terminating状态,因为这个节点有一个coredns服务。
未完待续@@@@@@!!!!!!!!!!!!