宿主机时间跳变超1秒会导致Kubelet的PLEG模块死锁,引发Pod状态停滞、无法删除及新建卡住;需通过node描述和journal日志确认clock jump,强制stop kubelet、chronyc makestep校时后再start,并配置chrony smoothtime或panic阈值根治。

宿主机时间突然快进或倒退超过1秒,会直接导致Kubelet内部PLEG(Pod Lifecycle Event Generator)模块陷入死锁,容器状态停滞、Pod无法删除、新Pod卡在ContainerCreating,且kubectl get nodes仍显示Ready——因为kubelet进程本身没崩溃,只是逻辑卡死在时钟校验循环里。
确认是否为时间跳变引发的PLEG死锁
执行kubectl describe node <node-name>,重点检查Conditions中Ready状态的LastHeartbeatTime与LastTransitionTime是否长时间未更新(超过30秒);同时在节点上运行journalctl -u kubelet -n 100 --no-pager | grep -E "(clock|time|PLEG)",若出现PLEG is not healthy并伴随clock jump detected或time moved backwards字样,即可确认。
这一步不能跳过:PLEG死锁不会触发kubelet进程退出,systemctl status kubelet永远显示active (running),仅靠服务状态无法判断真实健康度。
立即止血:强制重启kubelet并同步系统时间
先停止kubelet:systemctl stop kubelet。
用chrony强制纠正时间偏差:chronyc makestep——这一步【必须执行】,否则重启kubelet后它会立刻再次检测到跳变而重入死锁;chrony默认禁止makestep,需确保/etc/chrony.conf中已启用make_step 1.0 -1(允许任意方向±1秒以上跳变)。
再启动kubelet:systemctl start kubelet。
根治方案:chrony配置防跳变熔断
方法一:禁用NTP自动步进,改用平滑调整
编辑/etc/chrony.conf,注释掉make_step行,添加smoothtime 400 0.001——表示最大容忍400秒偏差,以每秒0.001秒的速度缓慢追赶,彻底规避跳变。
方法二:启用chrony的panic阈值保护
在/etc/chrony.conf末尾追加panic 0.1,即当检测到时间跳变超过100毫秒时,chronyd进程主动退出并由systemd拉起,避免将错误时间传播给kubelet;配合Restart=on-failure的systemd unit配置,实现自动兜底。
注意:不要在生产环境使用ntpd -gq替代chrony,ntpd的-g参数仅允许首次启动时修正,后续跳变仍会拒绝同步,且无panic机制。
验证修复效果
第一步:确认chrony同步状态正常:chronyc tracking输出中Leap status应为Normal,System time与Offset绝对值小于50ms。
第二步:检查PLEG恢复情况:journalctl -u kubelet -n 50 --no-pager | grep "PLEG is healthy"——只要看到这条日志,说明死锁已解除,kubelet重新进入正常事件轮询。
第三步:观察节点Condition更新频率:kubectl get node <node> -o jsonpath='{.status.conditions[?(@.type=="Ready")].lastHeartbeatTime}',返回时间戳应每10秒左右刷新一次。

















