k8s 亲和反亲和污点容忍

知识为进步之母,而进步又为富强之源泉。这篇文章主要讲述k8s 亲和反亲和污点容忍相关的知识,希望能为你提供帮助。
个人觉得k8s 亲和、反亲和、污点、容忍其实没有明确的界限,主要还是看如何组合运用各种策略,来实现亲和或者反亲和。通常来说,污点就是用来实现反亲和的。
亲和、反亲和
亲和性的原理其实很简单,主要利用label标签结合nodeSelector选择器来实现:

  1. 首先,给节点打上label标签
#kubectl get nodes --show-labels |grep gray
qc-app-16-161Readygray205dv1.18.0beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=qc-app-16-161,kubernetes.io/os=linux,node-role.kubernetes.io/gray=gray
qc-app-16-244Readygray205dv1.18.0beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=qc-app-16-244,kubernetes.io/os=linux,node-role.kubernetes.io/gray=gray

【k8s 亲和反亲和污点容忍】 再通过nodeSelector匹配到打了相应label标签的节点
.........
nodeSelector:
node-role.kubernetes.io/gray: gray
..........

部署之后看下pod调度情况,很明显pod被调度到了匹配到label标签的节点上了
kubectl get pods -n company ai-action-statistic-gray-86465f9c4b-hdfk4 -owide
NAMEREADYSTATUSRESTARTSAGEIPNODENOMINATED NODEREADINESS GATES
ai-action-statistic-gray-86465f9c4b-hdfk42/2Running0172m10.83.60.214qc-app-16-244

需要注意的是:nodeSelector属于强制性的,就是说满足条件的就调度,不满足条件的就不调度,一直处于Pending状态,直到满足条件为止。
  • 优点:比较直观
  • 缺点:不够灵活,控制粒度不够细
不过不用担心,还用一种更灵活的方式,nodeAffinity(节点亲和性)(当然还有podAffinity:pod 亲和性、 podAntiAffinity:pod 反亲和性),它包括软策略和硬策略两种方式。
  • 软策略:尽量满足条件,是在满足不了那也无所谓,还是能完成最终调度
  • 硬策略:必须满足条件,否则就不调度,等着(Pending)。
但是不管哪种方式,最终还是要依赖label标签,具体配置如下:
kubectl get pods -n company ai-action-statistic-gray-86465f9c4b-hdfk4 -oyaml |grep nodeSelector -B 5 -A 5
uid: ed47f094-f70a-45ed-b7dd-d46f2d01986f
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:#硬策略,结合下面的“operator: In”,意思就是必须调度到满足条件的节点上,否则就等着(Pending)
nodeSelectorTerms:
- matchExpressions:
- key: node-role.kubernetes.io/gray
operator: In
values:
- gray
preferredDuringSchedulingIgnoredDuringExecution:# 软策略,结合下面的“operator: NotIn”,意思就是尽量不要将pod调度到匹配到的节点,但是如果没有不匹配的节点的话,也可以调度到匹配到的节点
- weight: 1
preference:
matchExpressions:
- key: pc-app
operator: NotIn
values:
- luna

污点(taint)、容忍
如果一个节点被标记为有污点,那么就意味着不允许将pod调度到该节点,除非pod也被标记为可以容忍污点节点。大家在使用kubeadm部署的k8s集群的时候应该会发现,通常情况下,应用是不会被调度到master节点的。什么原因呢? 因为,kubeadm部署的k8s集群默认给master节点加了Taints(污点)
#kubectl describe node test-k8s-master |grep Taints -A 5 -B 5


node.alpha.kubernetes.io/ttl: 0
projectcalico.org/IPv4Address: 192.168.1.123/23
projectcalico.org/IPv4IPIPTunnelAddr: 10.82.71.0
volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp:Mon, 12 Aug 2019 13:12:38 +0800
Taints:node-role.kubernetes.io/master:NoSchedule
Unschedulable:false
Conditions:
TypeStatusLastHeartbeatTimeLastTransitionTimeReasonMessage
----------------------------------------------------------
NetworkUnavailableFalseSun, 06 Jun 2021 00:58:16 +0800Sun, 06 Jun 2021 00:58:16 +0800CalicoIsUpCalico is running on this node

污点也有两种策略:
  • PreferNoSchedule:NoSchedule 的软策略版本,表示尽量不调度到污点节点上去
  • NoExecute:该选项意味着一旦 Taint 生效,如该节点内正在运行的 Pod 没有对应容忍(Tolerate)设置,则会直接被逐出
如果我们想任然希望pod能调度到污点节点,我们只要给pod添加容忍申明就可以了,如下:
...................
containerPort: 80
tolerations:
- key: "node-role.kubernetes.io/master"
operator: "Exists"
effect: "NoSchedule"
...................

注意: 对于 tolerations 属性的写法,其中的 key、value、effect 与 Node 的 Taint 设置需保持一致, 另外:
  • 如果 operator 的值是 Exists,则 value 属性可省略
  • 如果 operator 的值是 Equal,则表示其 key 与 value 之间的关系是 等于
  • 如果不指定 operator 属性,则默认值为 Equal
  • 空的 key 如果再配合 Exists 就能匹配所有的 key 与 value,也就是是能容忍所有节点的所有 Taints
  • 空的 effect 匹配所有的 effect

    推荐阅读