目录
在 Kubernetes 中 Pod 的调度都是由 Scheduler 组件来完成的,整个调度过程都是自动完成的,也就是说我们并不能确定 Pod 最终被调度到了哪个节点上。而在实际环境中,可能需要将 Pod 调度到指定的节点上。官方文档
这时,我们便可以通过 K8s 提供的节点选择器、亲和、反亲和等配置来实现 Pod 到节点的定向调度。
1、调度通过kubernetes的list-watch机制来发现集群中新创建且尚未被调度到Node上的Pod。调度器会将发现的每一个未调度的Pod调度到一个合适的Node上运行Node上来运行。
2、kube-scheduler是Kubernetes集群的默认调度器,并且是集群的默认调度器,并且是集群控制面的一部分。如果你真的希望或者有这方面的需求,kube-scheduler在设计上是运行你自己写一个调度组件并替换原有的kube-scheduler。
3、在做调度决定时需要考虑的因素包括:单独和整体的资源请求,硬件/软件/策略限制、亲和以及反亲和要求、数据局域性、负载间的干扰等等。
| 调度策略 | 作用 |
|---|---|
nodeSelector | 节点选择器,通过匹配节点标签的方式,调度到存在该标签的节点上。 |
nodeAffinity | 节点亲和,通过匹配节点标签的方式,调度到存在该标签的节点上。 |
podAffinity | Pod 亲和,通过匹配 Pod 标签的方式,使 Pod 和 Pod 调度在同一台节点上。 |
podAntiAffinity | Pod 反亲和,通过匹配 Pod 标签的方式,使 Pod 和 Pod 调度在不同的节点上。 |
Taint & Toleration | 污点和容忍,污点可以将节点和 Pod 达到互斥的效果,而容忍则可以让 Pod 调度到带有污点的节点上。 |
preferredDuringSchedulingIgnoredDuringExecution 软亲和
软策略:结合下面的 “operator: NotIn”,意思就是尽量不要将 pod 调度到匹配到的节点,但是如果没有不匹配的节点的话,也可以调度到匹配到的节点。
requiredDuringSchedulingIgnoredDuringExecution 硬亲和
硬策略:结合下面的 “operator: In”,意思就是必须调度到满足条件的节点上,否则就等着 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: #硬策略
- nodeSelectorTerms:
- - matchExpressions:
- - key: node-role.kubernetes.io/gray
- operator: In
- values:
- - gray
- preferredDuringSchedulingIgnoredDuringExecution: #软策略
- - weight: 1
- preference:
- matchExpressions:
- - key: pc-app
- operator: NotIn
- values:
- - luna
operator 匹配条件:
In:标签值存在某个列表中;NotIn:标签值不存在某个列表中;Gt:标签值大于某个值;Lt:标签值小于某个值;Exists:某个标签存在;DoesNotExist:某个标签不存在;K8s每个节点上都可以应用一个或多个taint,这表示对于那些不能容忍这些taint的pod,是不会被该节点接受的。如果将toleration应用于pod上,则表示这些pod可以(但不要求)被调度到具有相应taint的节点上。

effect 可选配置:
NoSchedule:表示 Pod 将不会被调度到具有该污点的节点上。PreferNoSchedule:表示 Pod 将尽量避免调度到具有该污点的节点上(类似于软策略)NoExecute:表示 Pod 将不会被调度到具有该污点的节点上,同时将节点上预警存在的 Pod 进行驱逐。使用kubectl设置和去除污点的命令实例如下:
- # 设置污点
- kubectl taint nodes node1 key1=value1:NoSchedule
- # 去除污点
- kubectl taint nodes node1 key1:NoSchedule-
接下来看一个具体的例子,使用kubeadm部署和初始化的Kubernetes集群,master节点被设置了一个node-role.kubernetes.io/master:NoSchedule的污点,可以使用kubectl describe node命令查看。这个污点表示默认情况下master节点将不会调度运行Pod,即不运行工作负载。对于使用二进制手动部署的集群设置和移除这个污点的命令如下:
kubectl taint nodes
node-role.kubernetes.io/master=:NoSchedule
kubectl taint nodesnode-role.kubernetes.io/master:NoSchedule-
设置了污点的Node将根据taint的effect:NoSchedule、PreferNoSchedule、NoExecute和Pod之间产生互斥的关系,Pod将在一定程度上不会被Node上,但我们可以在Pod上设置容忍(Toleration),意思是设置了容忍的Pod将可以容忍污点的存在,可以被调度到存在污点的Node上。
pod 的 Toleration 声明中的 key 和 effect 需要与 Taint 的设置保持一致,并且满足以下条件之一:
另外还有如下两个特例:
上面的例子中 effect 的取值为 NoSchedule,下面对 effect 的值作下简单说明:
NoExecute 这个 Taint 效果对节点上正在运行的 pod 有以下影响:
- 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"
系统允许在同一个 node 上设置多个 taint,也可以在 pod 上设置多个 Toleration。**Kubernetes 调度器处理多个 Taint 和 Toleration 能够匹配的部分,剩下的没有忽略掉的 Taint 就是对 Pod 的效果了。下面是几种特殊情况:
容忍多种配置:
1)可以被调度到带有 key/value:NoExecute 污点的节点上。
- tolerations:
- - key: ""
- operator: "Equal"
- value: ""
- effect: "NoExecute"
- tolerationSeconds: 3600
tolerationSeconds:表示当 Pod 被驱逐时,还可以在节点上继续运行的时间(仅可以和 NoExecute 配合使用)2)可以被调度到带有指定 key 污点的节点上。
- tolerations:
- - key: ""
- operator: "Exists"
3)可以被调度到带有任何污点的节点上。
- tolerations:
- - operator: "Exists"