Docker

Kubernetes 集群上 CPU 使用率不高的 systemd 程序

  • July 24, 2019

我在 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 CE
  • 系統化: 219

Cgroup 驅動配置:

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

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

這是目前 kuberneteskubelet程序中的一個已知錯誤,不僅限於基於 CentOS 的系統,還包括任何 Linux(包括 Ubuntu),您在其中systemd用作 kubelet 的 cgroup-driver。它似乎在 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 刪除。

該問題自 4 月以來一直開放,但沒有太多解決的跡象(因為它似乎優先級較低)。

上一次接觸此程式碼的送出是這個,但看起來它主要改變的是文件命名/目錄結構和程式碼佈局,並且很久以前就引入了cadvisor 程式碼。

最後,雖然切換到使用 cgroupfs 是一種選擇(正如@hanx 評論的那樣),但它可能會導致更糟糕的問題(負載下的不穩定),並且官方文件也不建議這樣做。有些人仍然選擇這條路線,只是為了擺脫(大部分是良性的)錯誤消息。

引用自:https://serverfault.com/questions/973131