我在 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.
我如何才能找出导致此systemd
CPU 使用率和日志消息的原因?
附加信息
版本:
- 操作系统: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),您将其用作systemd
kubelet 的 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 所评论的),但它可能会导致更严重的问题(负载下不稳定),而且官方文档也不推荐这样做。有些人仍然选择这种方式,只是为了摆脱(主要是良性) 错误消息。