Kubernetes 集群上 CPU 使用率异常的 systemd 进程

Kubernetes 集群上 CPU 使用率异常的 systemd 进程

我在 CentOS 7 虚拟机中运行单主/节点 Kubernetes 集群,我意识到该systemd进程(PID 1)正在不断使用 CPU。

[root@ip-10-0-0-66 ~]# ps aux | head -n2
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  7.7  0.0 129088  7720 ?        Ss   Jun21 639:41 /usr/lib/systemd/systemd --switched-root --system --deserialize 22

此外,systemd还会生成数百万条这样的日志行:

[root@ip-10-0-0-66 ~]# tail -n 10 /var/log/messages
Jun 27 12:49:14 ip-10-0-0-66 systemd: Created slice libcontainer_6148_systemd_test_default.slice.
Jun 27 12:49:14 ip-10-0-0-66 systemd: Removed slice libcontainer_6148_systemd_test_default.slice.
Jun 27 12:49:15 ip-10-0-0-66 systemd: Created slice libcontainer_6155_systemd_test_default.slice.
Jun 27 12:49:15 ip-10-0-0-66 systemd: Removed slice libcontainer_6155_systemd_test_default.slice.
Jun 27 12:49:15 ip-10-0-0-66 systemd: Created slice libcontainer_6155_systemd_test_default.slice.
Jun 27 12:49:15 ip-10-0-0-66 systemd: Removed slice libcontainer_6155_systemd_test_default.slice.
Jun 27 12:49:15 ip-10-0-0-66 systemd: Created slice libcontainer_6162_systemd_test_default.slice.
Jun 27 12:49:15 ip-10-0-0-66 systemd: Removed slice libcontainer_6162_systemd_test_default.slice.
Jun 27 12:49:15 ip-10-0-0-66 systemd: Created slice libcontainer_6162_systemd_test_default.slice.
Jun 27 12:49:15 ip-10-0-0-66 systemd: Removed slice libcontainer_6162_systemd_test_default.slice.

每秒几乎有 50 行日志记录,这些日志充斥着文件/var/logs/messages

[root@ip-10-0-0-66 ~]# sudo wc -l /var/log/messages
5992826 /var/log/messages
[root@ip-10-0-0-66 ~]# sudo cat /var/log/messages | grep 'systemd_test_default' | wc -l
5987033

最终,该kubelet过程还会记录如下错误:

Jun 27 12:53:37 ip-10-0-0-66 systemd: Removed slice libcontainer_29206_systemd_test_default.slice.
Jun 27 12:53:37 ip-10-0-0-66 systemd: Created slice libcontainer_29206_systemd_test_default.slice.
Jun 27 12:53:37 ip-10-0-0-66 systemd: Removed slice libcontainer_29206_systemd_test_default.slice.
Jun 27 12:53:37 ip-10-0-0-66 kubelet: W0627 12:53:37.447052    5352 watcher.go:87] Error while processing event ("/sys/fs/cgroup/memory/libcontainer_29206_systemd_test_default.slice": 0x40000100 == IN_CREATE|IN_ISDIR): readdirent: no such file or directory
Jun 27 12:53:37 ip-10-0-0-66 kubelet: W0627 12:53:37.447117    5352 watcher.go:87] Error while processing event ("/sys/fs/cgroup/devices/libcontainer_29206_systemd_test_default.slice": 0x40000100 == IN_CREATE|IN_ISDIR): open /sys/fs/cgroup/devices/libcontainer_29206_systemd_test_default.slice: no such file or directory
Jun 27 12:53:37 ip-10-0-0-66 systemd: Created slice libcontainer_29225_systemd_test_default.slice.
Jun 27 12:53:37 ip-10-0-0-66 systemd: Removed slice libcontainer_29225_systemd_test_default.slice.
Jun 27 12:53:37 ip-10-0-0-66 systemd: Created slice libcontainer_29232_systemd_test_default.slice.
Jun 27 12:53:37 ip-10-0-0-66 systemd: Removed slice libcontainer_29232_systemd_test_default.slice.

我如何才能找出导致此systemdCPU 使用率和日志消息的原因?


附加信息

版本:

  • 操作系统:CentOS Linux 版本 7.6.1810(核心)
  • 核心:3.10.0-957.21.2.el7.x86_64
  • Kubernetes:v1.15.0
  • 码头工人:公元18.09.5
  • 系统:219

Cgroup 驱动程序配置:

$ docker info | grep -i cgroup
Cgroup Driver: systemd

$ cat /var/lib/kubelet/kubeadm-flags.env
KUBELET_KUBEADM_ARGS="--cgroup-driver=systemd"

答案1

这是目前 kuberneteskubelet进程中已知的错误,不仅限于基于 CentOS 的系统,还包括任何 Linux(包括 Ubuntu),您将其用作systemdkubelet 的 cgroup 驱动程序。它似乎在 1.14 版之后开始出现,但可能不仅仅是在 1.14 之前没有像 kubernetes 文档的官方建议那样普遍存在建议使用 systemd 作为 cgroup 驱动程序),原因如下:

当选择 systemd 作为 Linux 发行版的 init 系统时,init 进程会生成并使用根控制组 (cgroup) 并充当 cgroup 管理器。Systemd 与 cgroups 紧密集成,并将为每个进程分配 cgroups。您可以配置容器运行时和 kubelet 以使用 cgroupfs。将 cgroupfs 与 systemd 一起使用意味着将有两个不同的 cgroup 管理器。

控制组用于限制分配给进程的资源。单个 cgroup 管理器将简化分配资源的视图,并且默认情况下将对可用和正在使用的资源有更一致的视图。当我们有两个管理器时,我们最终会得到这些资源的两个视图。我们在现场看到过这样的情况:配置为使用 cgroupfs 来运行 kubelet 和 Docker 的节点,以及使用 systemd 来运行节点上运行的其他进程的节点在资源压力下变得不稳定。

更改设置,使容器运行时和 kubelet 使用 systemd 作为 cgroup 驱动程序,从而稳定系统。请注意下面 Docker 设置中的 native.cgroupdriver=systemd 选项。

来源:https://kubernetes.io/docs/setup/cri/

在此之前,其他 cgroup-drivercgroupfs似乎一直是公认的/默认的方法。事实上,我之所以切换,是因为几个月前在 kubeadm 初始化新的 1.14.x 集群时开始出现建议,这让我发现这个 github 问题正是针对这种情况。

基本上,这似乎是 kubelet 处理 systemd 和 cAdvisor 探测之间的不可靠交互,因此代码可能尚未完全准备好。完整的 gorey 技术解释可在此评论

“缺失”的部分是由 runc 的 systemd 代码创建这就是为什么只有当 systemd 配置为 cgroup 管理器时才会出现错误。

错误来自当 cadvisor 开始尝试收集和处理事件时来自新创建的“切片/容器”。

推测这里存在一个竞争条件,即 cadvisor 没有意识到它试图启动事件观察器的“切片/容器”已被 runc 删除。

该问题自四月份以来一直存在,但没有太多迹象表明它正在得到解决(因为它似乎优先级不高)。

最后一次触及此代码的提交是这个然而,看起来它主要改变了文件命名/目录结构和代码布局,并引入了 cadvisor 代码很久以前

最后,虽然切换到使用 cgroupfs 是一个选项(正如 @hanx 所评论的),但它可能会导致更严重的问题(负载下不稳定),而且官方文档也不推荐这样做。有些人仍然选择这种方式,只是为了摆脱(主要是良性) 错误消息。

相关内容