问题

在 CentOS 7.9 主机上部署了 k8s 1.21 集群。
因为改配置,需要重启 kubelet 。大部分主机都能一秒重启完 kubelet ,不影响容器运行。
但是在某个主机重启 kubelet 时,却一直阻塞无反应,然后报错超时。
于是看 kubelet 日志,发现报错:
请添加图片描述

google 搜了下这个报错 org.freedesktop.systemd1 ,发现可能是 systemd 出问题了。
于是看内核日志 less /var/log/messages ,发现几天前就有报错了:
请添加图片描述

报错表示 systemd 收到了 QUIT 信号,因此不能正常工作。虽然容器还能继续运行,但多个 systemd 托管的模块通信超时,执行 systemctl 命令也会超时。
日志中的 Started Session 可能是因为有用户登录,也可能是 cron 等系统进程引发的,并不说明被恶意用户 SSH 登录。
看了堡垒机监控,没人在这个主机上执行 kill 命令或什么奇怪命令。所以怀疑是 CentOS 或 k8s 的 bug 引发的。比如本来要发送 kill 信号给容器内 1 号进程,却发送给宿主机的 1 号进程。

解决办法

既然发现 systemd 不能正常工作,于是笔者重启主机,果然它自动恢复了。
如果重启主机不管用,还有其它解决方案:

  • 手动重启 systemd 进程。google能找到少量这方面的资料,但是可靠性低,毕竟 systemd 进程托管了很多系统服务。如果修复 systemd 失败,可能导致问题更严重。即使重启 systemd 成功,也不确定所有系统服务是否正常。
  • 最坏的情况下,如果 systemd 不能恢复,那就重装操作系统,反正是 k8s 节点,能轻松迁移。

问题复现

选一台测试主机,尝试手动发送 SIGTERM 信号给 systemd 进程,没有反应。
改为发送 QUIT 信号,果然能复现该问题。问题的负面影响包括:

  • systedmd 进程不能正常工作,导致执行各种 systemctl 命令都会超时失败。
  • 执行 reboot、shutdown、halt 命令也会超时失败,因为它们会调用 systemd 来关机。
  • SSH 登录这台主机的耗时增加到 20 多秒, 因为 systemd-logind 模块超时。
    请添加图片描述

后记

过了半年,问题再次复现。发现不是 bug ,只是有人误操作:想执行命令 jmap -dump:format=b,file=heapdump.hprof 1 来调试容器里的 1 号 java 进程,但实际上没进容器,而是在宿主机上执行了该命令。而 jmap 命令会发送 QUIT 信号(相当于执行 kill -3 命令),导致 systemd 进程停止工作。
执行该命令时的终端输出如下:

[root@CentOS ~]# jmap -dump:format=b,file=heapdump.hprof 1

Broadcast message from systemd-journald@CentOS (Tue 2022-12-12 12:31:01 CST):

systemd[1]: Caught <QUIT>, dumped core as pid 2935.


Broadcast message from systemd-journald@CentOS (Tue 2022-12-12 12:31:01 CST):

systemd[1]: Freezing execution.


Message from syslogd@[localhost] at Dec 12 12:31:01 ...
 systemd:Caught <QUIT>, dumped core as pid 2935.

Message from syslogd@[localhost] at Dec 12 12:31:01 ...
 systemd:Freezing execution.
1: Unable to open socket file: target process not responding or HotSpot VM not loaded
The -F option can be used when the target process is not responding
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐