写在前面
节点优雅关闭(Graceful node shutdown)已经在kubernetes 1.21进入beta状态,开启节点优雅关闭可以使kubelet在节点关闭期间正常的终止pod。
Kuberentes是一个多节点的分布式系统,各种意外情况都可能出现,比如可能某人或某个操作系统事件,在没有先排空节点的情况下关闭了节点,那么pod将会等待节点被判定为NotReady后,再遵循配置的驱逐时间(没有配置的话默认为5m),这样可能会影响服务访问的连续性。
在关闭之前最佳的流程应该是可以自动的安全的排干节点,确保节点上的pod被安全的终止,并在pod中接收SIGTERM信号或运行preStop。
Kubernetes的Graceful node shutdown能力可以我们更好的控制一些意外关闭的情况,开启功能后kubelet能够意识到底层系统的关闭事件,并将关闭事件传播到pod,确保pod能够尽可能优雅的关闭。
原理
节点优雅关闭功能依赖systemd,利用了systemd抑制锁来延迟节点关闭的时间。
systemd抑制锁可以覆盖到许多不同的节点关闭场景,如:
- 运行shutdown、shutdown now -h、reboot、systemctl reboot、systemctl poweroff等
- 物理机按电源键
- 公有云停止VM实例或抢占式VM被动关闭
开启了Graceful node shutdown能力后,kubelet会在启动时获得一个延迟型的Inhibitor Lock,当系统即将关闭时,kubelet会指示systemd推迟一段时间关闭系统,让kubelet有时间终止pod,并且pod也将收到一个SIGTERM触发preStop。
终止设计上将pod分为了两类:
-
critical pod
:关键pod,那些将priorityClassName设置为system-cluster-critical或者system-node-critical的pod -
regular pod
:普通pod,除critical pod以外的pod
在系统关闭期间时,会先终止regular pod,然后再终止critical pod,比如我们把日志服务设置为critical pod,这样的终止顺序可以让日志服务尽可能的收集到普通服务在终止之前的日志信息。
使用
Kubernetes的Graceful node shutdown能力,涉及三个配置:
-
GracefulNodeShutdown
: kubelet功能门,配置为true启动优雅关闭功能 -
shutdownGracePeriod
:指定节点延迟关闭的总持续时间,关键pod和普通pod终止的总宽限期 -
shutdownGracePeriodCriticalPods
:指定节点延迟关闭期间关键pod终止的持续时间,配置时值要小于shutdownGracePeriod
相应时间计算方式为:如果shutdownGracePeriod
配置为30s,shutdownGracePeriodCriticalPods
配置为10s,那就意味着关键pod有10s的终止时间,普通pod有20s(30-10)的终止时间。
注意,在默认情况下,上面描述的两个配置选项 ShutdownGracePeriod 和 ShutdownGracePeriodCriticalPods 都被设置为零,因此你需要根据你的环境对它们进行适当的配置,以激活优雅的节点关闭功能。
shutdownGracePeriod和shutdownGracePeriodCriticalPods 需要在kubelet config文件中配置,建议使用–config的方式启动kubelet
示例
在k8s的集群中,配置一个节点开启Graceful node shutdown,在kubelet config.yaml中添加如下参数:
# 开启GracefulNodeShutdown功能门
featureGates:
GracefulNodeShutdown: true
# 配置终止时间
# - 配置总宽限时间
shutdownGracePeriod: 60s
# - 配置关键pod终止时间
shutdownGracePeriodCriticalPods: 30s
配置完成并重启kubelet后,可以通过如下命令查看是否生效:
systemd-inhibit --list
cat /etc/systemd/logind.conf.d/99-kubelet.conf
调度一个服务到此节点
在此节点执行reboot查看各类信息:
- 系统日志
可以看到在节点reboot后,kubelet已经感知,并通过延迟型的Inhibitor Lock,让节点延迟关闭,在此期间开始执行相应pod的终止工作。
- pod日志
可以看到nginx服务收到了终止信号,并关闭相关连接
- pod事件
在终止pod后,可以查看到服务立即调度到了健康的节点,并在原节点留下Completed状态的pod:
查看Completed pod的Message,可以看到因节点关闭而终止:
遇到的问题
Graceful node shutdown依赖是systemd抑制锁,所以对systemd版本有要求,官方说明183版本开始就支持,在使用的过程中发现开启了节点优雅关闭后并不能生效或者生效效果不理想,如:
- 在centos7中(systemd 219版本),节点优雅关闭直接不生效
- 在centos8中(systemd 239版本)只有
shutdown
执行正常等待1分钟后pod才会终止,reboot和shutdown now等立即执行类的直接不生效
目前测试下来在将systemd升级到251版本后,各项表现正常。
参考资料
- Kubernetes官方说明:https://kubernetes.io/docs/concepts/architecture/nodes/#graceful-node-shutdown
- system抑制锁机制:https://www.freedesktop.org/wiki/Software/systemd/inhibit/