1. Kubernetes 中的调度器
kube-scheduler 是 Kubernetes 中决定 Pending 状态的 Pod 运行在哪个 Node 的组件,被称之为调度器。Kubernetes 中内置了大量的调度策略,也提供了一些高级调度策略(nodeAffinity、podAffinity 等),以供用户使用,基本能够满足绝大部分的业务需求。前面的文档 Kubernetes 之 Labels、Selectors 中提到, Labels、Selectors 是 Kubernetes 中非常重要的功能。Labels 关联了 Pod 、Deployment 、Service ,也用于调度策略,下面我们就来看看怎么使用 Labels 定制调度策略。
2. nodeSelector
首先查看,Node 有哪些 Labels :
|
|
回顾一下 Labels 的基本操作:
- 增加标签
|
|
- 修改标签
|
|
- 删除标签
|
|
在使用 nodeSelector 时,在 Pod 的 Spec 字段中增加 nodeSelector ,说明 Node 需要同时满足的全部 Label 条件即可。下面这个例子,将 Pod 调度到具有 kubernetes.io/hostname=node1
Label 的 Node 上。
spec:
containers:
- ...
nodeSelector:
kubernetes.io/hostname: node1
在 1.2 版本之后,Kubernetes 引入了 nodeAffinity ,功能上类似 nodeSelector ,nodeSelector 在后续版本中将被废除。
3. nodeAffinity
nodeAffinity 主要用于控制 Pod 应该运行在哪个 Node 上。亲和性调度有两种方式:
- 软策略,尽量满足
- 硬策略,必须满足
这些策略是通过 Label 匹配进行判断的,Kubernetes 提供了几种操作符:
- In, Label 在某个列表中
- NotIn, Label 不在某个列表中
- Gt, Label 大于某个值
- Lt, Label 小于某个值
- Exists, Label 存在
- DoesNotExist,Label 不存在
通过这些操作符和 Label ,我们就可以定制自己的调度策略。下面是一个官方的示例:
|
|
在 Pod 的 Spec 字段中,新增 nodeAffinity 字段进行描述。如果同时指定多个 nodeSelectorTerms ,那么 Node 只要满足其中一个条件即可调度。如果指定多个 matchExpressions ,那么 Node 必须满足所有条件才可以调度。
4. podAffinity
podAffinity 与 nodeAffinity 类似,只不过 nodeAffinity 描述的是 Pod 对 Node 的选择,而 podAffinity 描述的是 Pod 对 Pod 的选择。podAffinity 多了一个 topologyKey (拓扑域),这相当于给 Pod 的调度策略增加了一个选择 Node 的维度。首先 Node 的 Label 需要满足 topologyKey 的要求,再考察运行中的 Pod 带的 Label 是否满足亲和性的要求。下面这个例子要求 Pod 调度需要满足:
- Node 的 Label 必须有 failure-domain.beta.kubernetes.io/zone
- Node 上运行的 Pod Label 必须有 security=S1
- 尽量不要调度到 Label 有 kubernetes.io/hostname ,并且 Pod Label 有 security=S2 的 Node 上
|
|
5. taints、tolerations
taints 针对的是 Node , tolerations 针对的是 Pod。如果一个 Node 被标记为 taint ,那么这个 Node 将不被调度,除非 Pod 被设置 tolerations 容忍这个 taint。taints、tolerations 通常用在一些特殊的 Node 调度上,比如 master 、具有 GPU 的 Node 、SSD 硬盘的 Node 、内存很大的 Node 等。taint 的格式为:<key>=<value>:<effect>
。其中 key、value(均可为空) 用于 tolerations 匹配,而 effect 有三个值:
- PreferNoSchedule ,尽量不要调度
- NoSchedule ,不能调度
- NoExecute ,不能调度,同时驱逐已有 Pod
- 给 Node 增加一个 taint
|
|
- 查看 Node 的 taint
|
|
- 给 Node 去掉 taint
|
|
- Pod 容忍 taint
在 Pod 的 Spec 字段,新增 tolerations 描述容忍的 taint 。下面的例子,正好可以容忍上面打的 taint :
|
|
6. 参考
- https://k8smeetup.github.io/docs/concepts/configuration/assign-pod-node/
- https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/