调度是啥?
在 K8S 中,调度 是指将 Pod 放置到合适的节点上,以便对应节点上的 Kubelet 能够运行这些 Pod。
调度器通过 K8S 的监测(Watch)机制来发现集群中新创建且尚未被调度到节点上的 Pod,把它调度到一个合适的节点上运行。
K8S调度分为两个阶段:过滤和打分。过滤阶段会将所有满足 Pod 调度需求的节点选出来;在打分阶段会为 Pod 从所有可调度节点中选取一个最合适的节点。最后,会将pod调度到得分最高的节点上。
我们可以约束一个 Pod 限制其只能在特定的节点上运行,或优先在特定的节点上运行。具体方法包括:
- nodeName
- label和nodeSelector
- 亲和性与反亲和性
- Pod 拓扑分布约束
我们也可以约束一些 Pod 不能在特定的节点上运行。具体方法是使用污点(taint)和容忍(tolerations)。
参考文档:
调度规则
每个节点具有每种资源类型的最大容量:可为 Pod 提供的 CPU 和内存量。调度程序确保对于每种资源类型,调度的容器的资源请求的总和小于节点的容量。
哪怕节点上实际CPU或内存的资源使用量非常低,但如果容量检查失败,则调度程序仍然拒绝在该节点上放置 Pod。
参考文档:管理容器的计算资源
nodeName
pod想要指定调度到某个node,可以直接在spec下制定nodeName字段
1 | spec: |
label和nodeSelector
添加label
kubectl label nodes node1 key1=value1,key2=value2
添加nodeSelector
node添加label后,pod想要指定调度到这个node,可以在spec下添加nodeSelector字段
1 | spec: |
删除label
如果不再使用某个label,可以进行删除。kubectl label nodes node1 key2-
亲和性与反亲和性
节点亲和性
添加label
kubectl label nodes node1 key1=value1,key2=value2
添加affinity
node添加label后,pod想要指定调度到这个node,也可以在spec下添加affinity字段
1 | spec: |
pod亲和性
pod反亲和性
参考文档Pod 打散调度
相同服务的pod必须打散,强反亲和
1 | apiVersion: apps/v1 |
相同服务的pod尽量打散,弱反亲和
1 | apiVersion: apps/v1 |
Pod 拓扑分布约束
污点和容忍
添加taint
1 | kubectl taint nodes node1 key1=value1:NoSchedule |
添加tolerations
node添加taint后,pod想要调度到这个node,需要在spec下添加tolerations字段:
1 | spec: |
删除taint
kubectl taint nodes node1 value1:NoSchedule-
node封锁
如果node存在问题,或者node需要升级维护,这时需要对node进行封锁,并且驱除pod。
封锁node,不允许分配pod
kubectl cordon nodename
从指定node驱除pod
kubectl drain nodename --ignore-daemonsets
解除node的封锁,允许分配pod
kubectl uncordon nodename