主要概念
主机层
nodeSelector
备注:
- 如果
nodeSelectorTerms
下面有多个选项的话,满足任何一个条件就可以了;如果matchExpressions
有多个选项的话,则必须同时满足这些条件才能正常调度 POD。 - 如果我们的目标节点没有可用的资源,我们的 Pod 就会一直处于 Pending 状态
pod层
亲和性:
节点亲和性(nodeAffinity
)、podAffinity(pod 亲和性) 以及 podAntiAffinity(pod 反亲和性)
策略:
软策略(preferredDuringSchedulingIgnoredDuringExecution)
就是如果你没有满足调度要求的节点的话,pod 就会忽略这条规则,继续完成调度过程,说白了就是满足条件最好了,没有的话也无所谓了的策略硬策略(requiredDuringSchedulingRequiredDuringExecution)
就比较强硬了,如果没有满足条件的节点的话,就不断重试直到满足条件为止,简单说就是你必须满足我的要求,不然我就不干的策略
whenUnsatisfiable(topologySpreadConstraints)
- DoNotSchedule (默认) 告诉调度器不要调度该 Pod,因此 DoNotSchedule 也可以叫作硬需求 (hard requirement);
- ScheduleAnyway 告诉调度器根据每个 Node 的 skew 值打分排序后仍然调度,因此 ScheduleAnyway 也可以叫作软需求 (soft requirement);
强制性
nodeSelector、硬策略、topologySpreadConstraints(DoNotSchedule、topologyKey 、maxSkew)…
非强制性
软策略、ScheduleAnyway …
污点(taints)与容忍(tolerations)
对于nodeAffinity
无论是硬策略还是软策略方式,都是调度 pod 到预期节点上,而Taints
恰好与之相反,如果一个节点标记为 Taints ,除非 pod 也被标识为可以容忍污点节点,否则该 Taints 节点不会被调度 pod。
比如用户希望把 Master 节点保留给 Kubernetes 系统组件使用,或者把一组具有特殊资源预留给某些 pod,则污点就很有用了,pod 不会再被调度到 taint 标记过的节点。
打污点: kubectl taint nodes node02 test=node02:NoSchedule
去污点: kubectl taint nodes node02 test-
每一个污点都可以关联一个效果, 效果包含了以下三种:
- NoSchedule 表示如果 pod 没有容忍这些污点, pod 则不能被调度到包含 这些污点的节点上。
- PreferNoSchedule 是 NoSchedule 的一个宽松的版本, 表示尽量阻止pod 被调度到这个节点上, 但是如果没有其他节点可以调度, pod 依然会被调度到这个节点上。
- NoExecute 不同于 NoSchedule 以及 PreferNoSchedule, 后两者只在调度期间起作用, 而 NoExecute 也会影响正在节点上运行着的 pod。 如果 在一个节点上添加了 NoExecute 污点, 那些在该节点上运行着的 pod, 如果没有容忍这个 NoExecute 污点, 将会从这个节点去除。
对于 tolerations 属性的写法,其中的 key、value、effect 与 Node 的 Taint 设置需保持一致, 还有以下几点说明:
-
如果 operator 的值是 Exists,则 value 属性可省略
-
如果 operator 的值是 Equal,则表示其 key 与 value 之间的关系是 equal(等于)
-
如果不指定 operator 属性,则默认值为 Equal
另外,还有两个特殊值:
- 空的 key 如果再配合 Exists 就能匹配所有的 key 与 value,也是是能容忍所有 node 的所有 Taints
- 空的 effect 匹配所有的 effect
调度使用
10.9.22.31 Ready node 9d v1.15.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=10.9.22.31,kubernetes.io/os=linux,kubernetes.io/role=node
10.9.22.38 Ready node 9d v1.15.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=10.9.22.38,kubernetes.io/os=linux,kubernetes.io/role=node
10.9.22.39 Ready node 9d v1.15.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=10.9.22.39,kubernetes.io/os=linux,kubernetes.io/role=node
nodeSelector:
kubernetes.io/hostname: 10.9.22.39
指定主机组
nodeSelector:
kubernetes.io/role: node
独占主机
nodeSelector:
kubernetes.io/hostname: 10.9.22.38
tolerations:
- key: kubernetes.io/hostname
operator: Equal
value: 10.9.22.38
effect: NoSchedule
亲和性
默认部署
亲和
affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
run: busybox
topologyKey: kubernetes.io/hostname
反亲和
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
run: busybox
topologyKey: kubernetes.io/hostname
案例
背景:生产集群中, 有大数据的3个pod非常耗用cpu(limit: 25core),导致cpu负载经常超过80%, 运维组收到告警并影响该node中已跑的项目
需求:经过与运维商量,需将该3个pod独立运行至分离出来的4台node
解决办法:在分离出来的4台node上打上污点:node.kubernetes.io/unschedulable 标签:zto/big-data=true
配置pod的模板添加对带有标签(big-data: job)的pod反亲和
...
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: zto/big-data
operator: In
values:
- 'true'
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
big-data: job
topologyKey: kubernetes.io/hostname
tolerations:
- key: node.kubernetes.io/unschedulable
operator: Exists