Kubernetes 的多种调度方法

label

通常在部署对机器有特殊需求的服务的时候,可以使用给 Node 贴上label 的方式来绑定这些服务:

# add label
kubectl label nodes node-name key1=value1

# show node label
kubectl get nodes --show-labels

# remove label
kubectl label nodes node-name key1-

接着在部署的 YAML 描述文件中spec字段添加nodeSelector即可:

spec:
  nodeSelector:
    key1: value1

Taint和Toleration

污点(Taint)和容忍(Toleration)是在 Kubernetes 1.6 加入的调度功能,其目的是优化 pod 在集群间的调度,这跟节点亲和性类似(Kubernetes 1.8中Affinity特性已进入Beta阶段),只不过它们作用的方式相反,具有 taint 的 node 和 pod 是互斥关系.

tainttoleration 相互配合, 可以用来避免 pod 被分配到不合适的节点上.

每个节点上都可以应用一个或多个 taint ,这表示对于那些不能容忍这些 taint 的 pod, 是不会被该节点接受的. 如果将 toleration 应用于 pod 上,则表示这些 pod 可以(但不要求)被调度到具有相应 taint 的节点上。

使用taint的命令形式如下:

# add taint
kubectl taint nodes node-name key=value:effect

# remove taint
kubectl taint nodes node-name key:effect-

其中 key 和 value 就是标签对, effect 则是污点的效果,有三个值可选:

  1. NoSchedule:表示 Pod 将不会被调度到具有该污点的 Node 上
  2. NoExecute:表示 Pod 将不会被调度到具有该污点的 Node 上,同时会驱逐 Node 上已有的 Pod
  3. PreferNoSchedule:表示 Pod 将会尽量避免具有该污点的 Node

当 Node 贴上了 taint 后,通常 Pod 是不会再调度到当前节点了,但有些特殊的 Pod 则需要继续运行,这时候可以给部署的 YAML 描述文件种添加 toleration字段,使其能够容忍具有taint的 Node.

tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoSchedule"
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoExecute"
- key: "node.alpha.kubernetes.io/unreachable"
  operator: "Exists"
  effect: "NoExecute"
  tolerationSeconds: 6000
  • value 的值可以为 NoSchedule,PreferNoScheduleNoExecute

  • tolerationSeconds 是当 pod 需要被驱逐时,可以继续在 node 上运行的时间

Reference

cordon和drain

在某些时候,比如 Kubernetes 要进行升级时或主机硬件升级时,通常需要将节点进行限制,禁止节点上继续调度 Pod 并需要对已有的 Pod 进行驱赶.Kubernetes 对此提供了一套优雅的方案.

# 首先对指定的 Node 进行封锁
kubectl cordon node-name

# 然后对节点上的Pod进行驱逐,使用 --grace-period 设置宽限时间,单位秒
kubectl drain node-name --grace-period=60

# 当升级完毕后,解除该 Node 的封锁
kubectl uncordon node-name

Reference