在Kubernetes中,节点可以分为优雅关闭(Graceful node shutdown)及非优雅关闭(Non-graceful node shutdown)。优雅关闭可以理解为有计划的关闭节点;而非优雅关闭,一般就出现在断电或一些集群外在因素导致节点所在宿主机异常。
优雅关闭(Graceful node shutdown)
kubelet会去检测os系统的关机事件,并且终结节点上的所有pod。此外,节点也不再接收新的pod创建请求。
节点优雅关闭功能开始于v1.21版本的特性GracefulNodeShutdown,此特性默认为true。
一旦kubelet检测到os系统的关机事件,则会把节点状态改为NotReady,且reason配置为node is shutting down。此时,kube-scheduler发现这个节点状态,将不再调度pod到该节点。而且,kubelet会在PodAdmission阶段拒绝pod的相关请求,即使pod打上了node.kubernetes.io/not-ready:NoSchedule的容忍。接着kubelet会驱逐节点上的所有pod.
一般地,节点优雅关闭受限于以下2个配置参数,参数配置为0时,则不启动节点优雅关闭功能
shutdownGracePeriod
控制优雅关闭节点的时间shutdownGracePeriodCriticalPods
控制优雅关闭关键pod的时间,该时间要比shutdownGracePeriod小。这里,非关键pod会比关键pod更快驱逐。如何定义关键pod
此外,还有一种更细粒度控制节点优雅关闭的能力,基于kubelet configuration文件配置shutdownGracePeriodByPodPriority,这个是基于pod优先级来控制pod的驱逐顺序。此能力需要kubelet打开名为GracefulNodeShutdownBaseOnPodPriority的feature gate,此feature gate在版本v1.23进入Alpha阶段,在版本v1.31进入Beta阶段并默认配置为enabled。
具体的配置示例如下:
1 | shutdownGracePeriodByPodPriority: |
kubelet监控指标,用于提供节点关闭的指标数据
- graceful_shutdown_start_time_seconds
- graceful_shutdown_end_time_seconds
非优雅关闭(Non-graceful node shutdown)
在非优雅关闭的场景下,节点上的StatefulSet的pod会转变为terminating状态,但pod不会被delete以及不会调度重新运行一个新的。这是因为在非优雅关闭的场景下,kubelet无法感知关闭事件,并作出正确的delete操作。与此同时,如果pod关联了存储卷,该存储卷也无法完成解绑。所以这会导致StatefulSet应用无法提供正常的服务。
要解决上述的问题,Kubernetes已经无法自动完成处理,需要引入人工操作。在kube-controller-manager打开NodeOutOfServiceVolumeDetach的特性下,可以通过给节点打上污点:node.kubernetes.io/out-of-service,来表明节点已经无法提供服务了。此时当节点被非优雅关闭了,pod能直接自动被强制删除,并且关联存储卷也会被立即解绑,从而触发新的pod在其他节点重新拉起,StatefulSet重新提供正常的服务。
随后,一旦节点回复运行后,需要手动移除节点上node.kubernetes.io/out-of-service的污点,pod才会正常地再调度到此节点上。
(•̀ᴗ•́)و ̑̑