0
点赞
收藏
分享

微信扫一扫

K8s Pod 驱逐调度时间窗口(按需调整参数使节点故障后可以快速转移Pod)


在 Kubernetes 中,当一个 Pod 所属的宿主机宕机后,这个 Pod 被驱逐并调度到其他节点上是需要一个时间窗口的,它不是立刻进行的(与 Pod 自己挂了不同,这里说的是节点服务器直接宕机的情况)。

要弄清楚这个调度问题,还得从区分不同版本的 K8s 说起,主要分为 ​​小于 v1.13 版本​​​,​​大于等于 v1.13且小于 v1.18 版本​​​ 和 ​​大于等于 v1.18 版本​​。

就目前来说,大家基本上都是在用大于 v1.18 的版本了,所以如果你不想了解区别,可以根据目录直接查看大于等于 v1.18 的配置方法。

小于 v1.13 版本

在 Kubernetes 小于 v1.13 版本之前,默认没有启用基于污点的驱逐,因此 Pod 最终迁移的时间由 ​​node-monitor-period​​​、​​node-monitor-grace-period​​​、​​node-startup-grace-period​​​、​​pod-eviction-timeout​​ 几个参数同时决定。

K8s 中与节点状态、Pod状态的主要参数如下说明:

参数

说明

​--node-status-update-frequency​

kubelet 定期上报频率,默认​​10s​

​--node-monitor-period​

节点控制器定期检查 kubelet 状态,默认​​5s​

​--node-monitor-grace-period​

节点失联指定时间后,将 ​​Readey​​​ 变成为 ​​NotReady​​​ 的时间窗口,默认​​40s​

​--node-startup-grace-period​

节点失联指定时间后,判定为 ​​Unhealthy​​​ 状态,默认​​1m​​​(即 ​​NotReady​​​ 后再过 ​​20s​​​ 变为 ​​Unhealthy​​)

​--pod-eviction-timeout​

节点 ​​NotReady​​​ 后,再过 ​​--pod-eviction-timeout​​​ 时长后删除 Node 上的 Pod,默认​​300s​

所以,如果你对一个 Node 进行关机或断电操作,默认需要经过 ​​5+40+300​​ 秒后,这个 Node 上的 Pod 才会被驱逐并更新状态。

在 Node 状态为 ​​NotReady​​​ 时,​​--pod-eviction-timeout​​​ 时长内 Pod 的状态是不发生变更的,本来是 Running 的话,这个期间就一直就是,当超过这个时长后会变成 ​​Nodelost​​​(DaemonSet) 或 ​​Unknown​​(Deployment)。

调度过程解说:

  1. Master 每隔一段时间和 Node 联系一次,判定Node 是否失联,这个时间周期配置项为 node-monitor-period,默认5s
  2. 当 Node 失联后一段时间后,Kubernetes 判定 Node 为 NotReady 状态,这段时长的配置项为 node-monitor-grace-period,默认40s
  3. 当 Node 失联后一段时间后,Kubernetes 判定 Node 为 Unhealthy,这段时长的配置项为 node-startup-grace-period,默认1m0s
  4. 当 Node 状态为 NotReady 一段时间后,Kubernetes 开始删除原 Node 上的 Pod,这段时长配置项为 pod-eviction-timeout,默认5m0s

几组参考配置:

参数

快速更新和快速响应

中等更新和平均响应

低更新和慢响应

​-–node-status-update-frequency​

4s

20s

1m

​-–node-monitor-period​

2s

5s

5s

​-–node-monitor-grace-period​

20s

2m

5m

​-–pod-eviction-timeout​

30s

1m

1m

注意不同的配置对Master和数据库的压力区别,按需配置。

RKE 配置示例:

services:
kube-controller:
<其他参数已省略>
extra_args:
node-monitor-period: "5s" # (默认 5s)
node-monitor-grace-period: "40s" # Node Notready (默认 40s)
node-startup-grace-period: "1m0s" # Node Unhealthy (默认 1m0s)
pod-eviction-timeout: "5m0s" # 开始驱逐 Pod (默认 5m0s)

大于等于 v1.13 且小于 v1.18 版本

K8s 基于污点的驱逐

  1. 在 kubernetes 1.13 之前,基于污点的驱逐(​​TaintBasedEvictions​​)处于 ​​Alpha​​ 阶段,默认是禁用状态(​​TaintBasedEvictions=false​​)。所以在 kubernetes 1.13 之前的版本中只需要配置 kube-controller 的参数即可控制节点不可用时 Pod 的迁移时间。
  2. 从 kubernetes 1.13 开始,基于污点的驱逐(​​TaintBasedEvictions​​)处于 ​​Beta​​ 阶段,默认是被开启状态(​​TaintBasedEvictions=true​​)。当修改 kube-controller 参数后手动停止一个节点,发现 Pod 还是需要等很久才能被迁移。
  3. 在 基于污点的驱逐(​​TaintBasedEvictions​​)开启的状态下,​​node-startup-grace-period​​ 和 ​​pod-eviction-timeout​​ 参数配置的时间​​不再生效​​。相应的我们可以在 Pod 的 yaml 配置文件中看到如下的参数:

tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300

  1. 因为 kubernetes 节点控制器根据 kubelet 的不同状态,将自动为节点添加不同的 污点。当节点具有 ​​node.kubernetes.io/not-ready​​​ 或者 ​​node.kubernetes.io/unreachable​​​ 污点时,将会等待 ​​tolerationSeconds​​​ 所配置的时长。tolerations 是由 API SERVER 控制生成,从 Kubernetes v1.13 开始可以通过以下参数来配置 ​​tolerationSeconds​​ 时间值。

kube-apiserver (Kubernetes v1.13 版本及以后)

  • ​default-not-ready-toleration-seconds​​​:表示 ​​notReady:NoExecute​​ 容忍的时间。​​notReady:NoExecute​​ 默认添加到所有 Pod。默认 300 秒)
  • ​default-unreachable-toleration-seconds​​​:表示 ​​unreachable:NoExecute​​ 容忍的时间。​​unreachable:NoExecute​​ 默认添加到所有 Pod。(默认 300 秒)

注意: notReady 和 unreachable 两个污点匹配到一个就会触发驱逐,notReady 的时间可以适当设置长一点。

节点污点

从 Kubernetes 1.6 开始,kubernetes 的节点控制器根据 kubelet 的不同状态,将自动为节点添加不同的污点。

这类污点有:

  • ​node.kubernetes.io/not-ready​​​: 节点未就绪。对应着 NodeCondition ​​Ready​​ 为 False 的情况。
  • ​node.kubernetes.io/unreachable​​​: 节点不可触达。对应着 NodeCondition ​​Ready​​​ 为 ​​Unknown​​ 的情况。
  • ​node.kubernetes.io/out-of-disk​​:节点磁盘空间已满。
  • ​node.kubernetes.io/memory-pressure​​:节点内存吃紧。
  • ​node.kubernetes.io/disk-pressure​​:节点磁盘吃紧。
  • ​node.kubernetes.io/network-unavailable​​:节点网络不可用。
  • ​node.kubernetes.io/unschedulable​​:节点不可调度。
  • ​node.cloudprovider.kubernetes.io/uninitialized​​:如果 kubelet 是由 “外部” 云服务商启动的,该污点用来标识某个节点当前为不可用的状态。在 “云控制器”(cloud-controller-manager)初始化这个节点以后,kubelet 将此污点移除。

rke 配置示例

在 Kubernetes 大于等于 v1.13 小于 v1.18 的版本中,基于污点的驱逐(​​TaintBasedEvictions​​​)处于 ​​Beta​​ 阶段,可选择以下两种方式来配置。

  • 禁用 基于污点的驱逐

services:
kube-controller:
<其他参数已省略>
extra_args:
node-monitor-period: "5s" # (默认 5s)
node-monitor-grace-period: "40s" # Node Notready (默认 40s)
node-startup-grace-period: "1m0s" # Node Unhealthy (默认 1m0s)
pod-eviction-timeout: "5m0s" # 开始驱逐 Pod (默认 5m0s)
feature-gates: "TaintBasedEvictions=false" # 禁用 基于污点的驱逐

  • 启用 基于污点的驱逐

services:
kube-api:
<其他参数已省略>
extra_args:
default-not-ready-toleration-seconds: '60' # 默认 300 秒
default-unreachable-toleration-seconds: '30' # 默认 300 秒
kube-controller:
<其他参数已省略>
extra_args:
node-monitor-period: "5s" # (默认 5s)
node-monitor-grace-period: "40s" # Node Notready (默认 40s)

大于等于 v1.18

在 Kubernetes 1.18 及以上版本中,​​TaintBasedEvictions​​​ 默认设置为 true 并且不能修改。如果强制在 rke 配置中指定 ​​TaintBasedEvictions=false​​,如下配置:

services:
kube-controller:
extra_args:
feature-gates: "TaintBasedEvictions=false"

那么 kube-controller-manager 将无法正常运行,日志中会看到如下的错误提示:

Error: invalid argument "TaintBasedEvictions=false" for "--feature-gates" flag: cannot set feature gate TaintBasedEvictions to false, feature is locked to true

rke 配置示例

services:
kube-api:
<其他参数已省略>
extra_args:
default-not-ready-toleration-seconds: '60' # 默认 300 秒
default-unreachable-toleration-seconds: '30' # 默认 300 秒
kube-controller:
<其他参数已省略>
extra_args:
node-monitor-period: "5s"
node-monitor-grace-period: "30s" # Unavailable

为指定的 Deployment 自定义配置

tolerations:
- key: node.kubernetes.io/unreachable
operator: Exists
effect: NoExecute
tolerationSeconds: 10
- key: node.kubernetes.io/not-ready
operator: Exists
effect: NoExecute
tolerationSeconds: 10

(END)


举报

相关推荐

0 条评论