在 systemd 中使用控制組管理資源
作為一個系統管理員,沒有事情比意外地耗盡計算資源讓我更覺得沮喪。我曾不止一次填滿了一個分區的所有可用磁碟空間、耗盡內存、以及沒有足夠的 CPU 時間在合理的時間內處理我的任務。資源管理是系統管理員最重要的工作之一。
資源管理的關鍵是保證所有的進程能夠相對公平的訪問需要的系統資源。資源管理還包括確保在需要時添加內存、硬碟驅動器空間、還有 CPU 處理能力;或者在無法添加時限制資源的使用。此外,應該阻止獨佔系統資源的用戶,無論其是否有意。
系統管理員可以通過一些工具監控和管理不同的系統資源。例如,top 和類似的工具允許你監控內存、I/O、存儲(磁碟、SSD 等)、網路、交換空間、CPU 的用量等。這些工具,尤其是那些以 CPU 為中心的工具,大部分基於以運行的進程為基本單位進行控制的模型。它們最多只是提供了一種方式來調整 nice
數字,從而修改優先順序,或者殺死一個運行的進程。(要了解 nice
數字的信息,查看 使用 Glances 監控 Linux 和 Windows 主機)。
SystemV 環境中基於傳統的資源管理的其他工具,由 /etc/security/limits.conf
文件和 /etc/security/limits.d
中的本地配置文件控制。資源可以按照用戶或組以一種相對粗糙但實用的方式限制。可以管理的資源包括內存的各個方面、每日的總 CPU 時間、數據總量、優先順序、nice
數字、並發登錄的數量、進程數、文件大小的最大值等。
使用控制組管理進程
systemd 和 SystemV 之間的一個主要差異是管理進程的方式。SystemV 將每個進程視作一個獨立的實體。systemd 將相關的進程集中到一個控制組,簡寫做 cgroup,並將控制組作為一個整體管理系統資源。這意味著資源能夠基於應用管理,而不是由組成應用的各個進程來管理。
控制組的控制單元稱作 切片單元 。切片是允許 systemd 以樹狀格式控制程序次序,從而簡化管理的概念化。
查看控制組
我將從一些允許你查看不同類型控制組信息的命令開始。 systemctl status <service>
命令顯示一個特定服務的切片信息,包括服務的切片。這個例子展示了 at
守護進程:
[root@testvm1 ~]# systemctl status atd.service
● atd.service - Deferred execution scheduler
Loaded: loaded (/usr/lib/systemd/system/atd.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2020-09-23 12:18:24 EDT; 1 day 3h ago
Docs: man:atd(8)
Main PID: 1010 (atd)
Tasks: 1 (limit: 14760)
Memory: 440.0K
CPU: 5ms
CGroup: /system.slice/atd.service
└─1010 /usr/sbin/atd -f
Sep 23 12:18:24 testvm1.both.org systemd[1]: Started Deferred execution scheduler.
[root@testvm1 ~]#
這是一個我感到 systemd 比 SystemV 和舊的初始化程序更好用的原因的絕佳示例。這裡的信息遠比 SystemV 能夠提供的豐富。CGroup
項包括的層級結構中,system.slice
是 systemd(PID 1),atd.service
在下一層,是 system.slice
的一部分。CGroup
項的第二行還顯示了進程 ID(PID)和啟動守護進程使用的命令。
systemctl
命令可以列出多個控制組項,--all
參數列出所有的切片,包括當前沒有激活的切片:
[root@testvm1 ~]# systemctl -t slice --all
UNIT LOAD ACTIVE SUB DESCRIPTION
-.slice loaded active active Root Slice
system-getty.slice loaded active active system-getty.slice
system-lvm2x2dpvscan.slice loaded active active system-lvm2x2dpvscan.slice
system-modprobe.slice loaded active active system-modprobe.slice
system-sshdx2dkeygen.slice loaded active active system-sshdx2dkeygen.slice
system-systemdx2dcoredump.slice loaded inactive dead system-systemdx2dcoredump.slice
system-systemdx2dfsck.slice loaded active active system-systemdx2dfsck.slice
system.slice loaded active active System Slice
user-0.slice loaded active active User Slice of UID 0
user-1000.slice loaded active active User Slice of UID 1000
user.slice loaded active active User and Session Slice
LOAD = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB = The low-level unit activation state, values depend on unit type.
11 loaded units listed.
To show all installed unit files use 'systemctl list-unit-files'.
[root@testvm1 ~]#
關於這個數據,第一個需要注意的是數據顯示了 UID 0(root)和 UID 1000 的用戶切片,UID 1000 是我登錄的用戶。這裡列出了組成每個切片的切片部分,而不是服務。還說明了每個用戶登錄時都會為其創建一個切片,這為將一個用戶的所有任務作為單個控制組項進行管理提供了一種方式。
探索控制組的層次結構
目前為止一切順利,但是控制組是分層的,所有的服務單元作為其中一個控制組的成員運行。要查看這個層次結構很簡單,使用一個舊命令和 systemd 的一個新命令即可。
ps
命令可以用於映射進程的和其所處的控制組層次。注意使用 ps
命令時需要指明想要的數據列。我大幅削減了下面命令的輸出數量,但是試圖保留足夠的數據,以便你能夠對自己系統上的輸出有所感受:
[root@testvm1 ~]# ps xawf -eo pid,user,cgroup,args
PID USER CGROUP COMMAND
2 root - [kthreadd]
3 root - _ [rcu_gp]
4 root - _ [rcu_par_gp]
6 root - _ [kworker/0:0H-kblockd]
9 root - _ [mm_percpu_wq]
10 root - _ [ksoftirqd/0]
11 root - _ [rcu_sched]
12 root - _ [migration/0]
13 root - _ [cpuhp/0]
14 root - _ [cpuhp/1]
<刪節>
625406 root - _ [kworker/3:0-ata_sff]
625409 root - _ [kworker/u8:0-events_unbound]
1 root 0::/init.scope /usr/lib/systemd/systemd --switched-root --system --deserialize 30
588 root 0::/system.slice/systemd-jo /usr/lib/systemd/systemd-journald
599 root 0::/system.slice/systemd-ud /usr/lib/systemd/systemd-udevd
741 root 0::/system.slice/auditd.ser /sbin/auditd
743 root 0::/system.slice/auditd.ser _ /usr/sbin/sedispatch
764 root 0::/system.slice/ModemManag /usr/sbin/ModemManager
765 root 0::/system.slice/NetworkMan /usr/sbin/NetworkManager --no-daemon
767 root 0::/system.slice/irqbalance /usr/sbin/irqbalance --foreground
779 root 0::/system.slice/mcelog.ser /usr/sbin/mcelog --ignorenodev --daemon --foreground
781 root 0::/system.slice/rngd.servi /sbin/rngd -f
782 root 0::/system.slice/rsyslog.se /usr/sbin/rsyslogd -n
<刪節>
893 root 0::/system.slice/sshd.servi sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
1130 root 0::/user.slice/user-0.slice _ sshd: root [priv]
1147 root 0::/user.slice/user-0.slice | _ sshd: root@pts/0
1148 root 0::/user.slice/user-0.slice | _ -bash
1321 root 0::/user.slice/user-0.slice | _ screen
1322 root 0::/user.slice/user-0.slice | _ SCREEN
1323 root 0::/user.slice/user-0.slice | _ /bin/bash
498801 root 0::/user.slice/user-0.slice | | _ man systemd.resource-control
498813 root 0::/user.slice/user-0.slice | | _ less
1351 root 0::/user.slice/user-0.slice | _ /bin/bash
123293 root 0::/user.slice/user-0.slice | | _ man systemd.slice
123305 root 0::/user.slice/user-0.slice | | _ less
1380 root 0::/user.slice/user-0.slice | _ /bin/bash
625412 root 0::/user.slice/user-0.slice | | _ ps xawf -eo pid,user,cgroup,args
625413 root 0::/user.slice/user-0.slice | | _ less
246795 root 0::/user.slice/user-0.slice | _ /bin/bash
625338 root 0::/user.slice/user-0.slice | _ /usr/bin/mc -P /var/tmp/mc-root/mc.pwd.246795
625340 root 0::/user.slice/user-0.slice | _ bash -rcfile .bashrc
1218 root 0::/user.slice/user-1000.sl _ sshd: dboth [priv]
1233 dboth 0::/user.slice/user-1000.sl _ sshd: dboth@pts/1
1235 dboth 0::/user.slice/user-1000.sl _ -bash
<刪節>
1010 root 0::/system.slice/atd.servic /usr/sbin/atd -f
1011 root 0::/system.slice/crond.serv /usr/sbin/crond -n
1098 root 0::/system.slice/lxdm.servi /usr/sbin/lxdm-binary
1106 root 0::/system.slice/lxdm.servi _ /usr/libexec/Xorg -background none :0 vt01 -nolisten tcp -novtswitch -auth /var/run/lxdm/lxdm-:0.auth
370621 root 0::/user.slice/user-1000.sl _ /usr/libexec/lxdm-session
370631 dboth 0::/user.slice/user-1000.sl _ xfce4-session
370841 dboth 0::/user.slice/user-1000.sl _ /usr/bin/ssh-agent /bin/sh -c exec -l bash -c "/usr/bin/startxfce4"
370911 dboth 0::/user.slice/user-1000.sl _ xfwm4 --display :0.0 --sm-client-id 2dead44ab-0b4d-4101-bca4-e6771f4a8ac2
370930 dboth 0::/user.slice/user-1000.sl _ xfce4-panel --display :0.0 --sm-client-id 2ce38b8ef-86fd-4189-ace5-deec1d0e0952
370942 dboth 0::/user.slice/user-1000.sl | _ /usr/lib64/xfce4/panel/wrapper-2.0 /usr/lib64/xfce4/panel/plugins/libsystray.so 6 23068680 systr
ay Notification Area Area where notification icons appear
370943 dboth 0::/user.slice/user-1000.sl | _ /usr/lib64/xfce4/panel/wrapper-2.0 /usr/lib64/xfce4/panel/plugins/libpulseaudio-plugin.so 8 2306
8681 pulseaudio PulseAudio Plugin Adjust the audio volume of the PulseAudio sound system
370944 dboth 0::/user.slice/user-1000.sl | _ /usr/lib64/xfce4/panel/wrapper-2.0 /usr/lib64/xfce4/panel/plugins/libxfce4powermanager.so 9 2306
8682 power-manager-plugin Power Manager Plugin Display the battery levels of your devices and control the brightness of your display
370945 dboth 0::/user.slice/user-1000.sl | _ /usr/lib64/xfce4/panel/wrapper-2.0 /usr/lib64/xfce4/panel/plugins/libnotification-plugin.so 10 2
3068683 notification-plugin Notification Plugin Notification plugin for the Xfce panel
370948 dboth 0::/user.slice/user-1000.sl | _ /usr/lib64/xfce4/panel/wrapper-2.0 /usr/lib64/xfce4/panel/plugins/libactions.so 14 23068684 acti
ons Action Buttons Log out, lock or other system actions
370934 dboth 0::/user.slice/user-1000.sl _ Thunar --sm-client-id 2cfc809d8-4e1d-497a-a5c5-6e4fa509c3fb --daemon
370939 dboth 0::/user.slice/user-1000.sl _ xfdesktop --display :0.0 --sm-client-id 299be0608-4dca-4055-b4d6-55ec6e73a324
370962 dboth 0::/user.slice/user-1000.sl _ nm-applet
<刪節>
你可以使用 systemd-cgls
命令查看整個層次結構,這個命令不需要任何的複雜參數,更加簡單。
我也大幅縮短了這個樹狀結構,但是保留了足夠多的輸出,以便你能夠了解在自己的系統上執行這個命令時應該看到的數據總量和條目類型。我在我的一個虛擬機上執行了這個命令,輸出大概有 200 行;我的主要工作站的輸出大概有 250 行。
[root@testvm1 ~]# systemd-cgls
Control group /:
-.slice
├─user.slice
│ ├─user-0.slice
│ │ ├─session-1.scope
│ │ │ ├─ 1130 sshd: root [priv]
│ │ │ ├─ 1147 sshd: root@pts/0
│ │ │ ├─ 1148 -bash
│ │ │ ├─ 1321 screen
│ │ │ ├─ 1322 SCREEN
│ │ │ ├─ 1323 /bin/bash
│ │ │ ├─ 1351 /bin/bash
│ │ │ ├─ 1380 /bin/bash
│ │ │ ├─123293 man systemd.slice
│ │ │ ├─123305 less
│ │ │ ├─246795 /bin/bash
│ │ │ ├─371371 man systemd-cgls
│ │ │ ├─371383 less
│ │ │ ├─371469 systemd-cgls
│ │ │ └─371470 less
│ │ └─user@0.service …
│ │ ├─dbus-broker.service
│ │ │ ├─1170 /usr/bin/dbus-broker-launch --scope user
│ │ │ └─1171 dbus-broker --log 4 --controller 12 --machine-id 3bccd1140fca488187f8a1439c832f07 --max-bytes 100000000000000 --max-fds 25000000000000 --max->
│ │ ├─gvfs-daemon.service
│ │ │ └─1173 /usr/libexec/gvfsd
│ │ └─init.scope
│ │ ├─1137 /usr/lib/systemd/systemd --user
│ │ └─1138 (sd-pam)
│ └─user-1000.slice
│ ├─user@1000.service …
│ │ ├─dbusx2d:1.2x2dorg.xfce.Xfconf.slice
│ │ │ └─dbus-:1.2-org.xfce.Xfconf@0.service
│ │ │ └─370748 /usr/lib64/xfce4/xfconf/xfconfd
│ │ ├─dbusx2d:1.2x2dca.desrt.dconf.slice
│ │ │ └─dbus-:1.2-ca.desrt.dconf@0.service
│ │ │ └─371262 /usr/libexec/dconf-service
│ │ ├─dbus-broker.service
│ │ │ ├─1260 /usr/bin/dbus-broker-launch --scope user
│ │ │ └─1261 dbus-broker --log 4 --controller 11 --machine-id
<刪節>
│ │ └─gvfs-mtp-volume-monitor.service
│ │ └─370987 /usr/libexec/gvfs-mtp-volume-monitor
│ ├─session-3.scope
│ │ ├─1218 sshd: dboth [priv]
│ │ ├─1233 sshd: dboth@pts/1
│ │ └─1235 -bash
│ └─session-7.scope
│ ├─370621 /usr/libexec/lxdm-session
│ ├─370631 xfce4-session
│ ├─370805 /usr/bin/VBoxClient --clipboard
│ ├─370806 /usr/bin/VBoxClient --clipboard
│ ├─370817 /usr/bin/VBoxClient --seamless
│ ├─370818 /usr/bin/VBoxClient --seamless
│ ├─370824 /usr/bin/VBoxClient --draganddrop
│ ├─370825 /usr/bin/VBoxClient --draganddrop
│ ├─370841 /usr/bin/ssh-agent /bin/sh -c exec -l bash -c "/usr/bin/startxfce4"
│ ├─370910 /bin/gpg-agent --sh --daemon --write-env-file /home/dboth/.cache/gpg-agent-info
│ ├─370911 xfwm4 --display :0.0 --sm-client-id 2dead44ab-0b4d-4101-bca4-e6771f4a8ac2
│ ├─370923 xfsettingsd --display :0.0 --sm-client-id 261b4a437-3029-461c-9551-68c2c42f4fef
│ ├─370930 xfce4-panel --display :0.0 --sm-client-id 2ce38b8ef-86fd-4189-ace5-deec1d0e0952
│ ├─370934 Thunar --sm-client-id 2cfc809d8-4e1d-497a-a5c5-6e4fa509c3fb --daemon
│ ├─370939 xfdesktop --display :0.0 --sm-client-id 299be0608-4dca-4055-b4d6-55ec6e73a324
<刪節>
└─system.slice
├─rngd.service
│ └─1650 /sbin/rngd -f
├─irqbalance.service
│ └─1631 /usr/sbin/irqbalance --foreground
├─fprintd.service
│ └─303383 /usr/libexec/fprintd
├─systemd-udevd.service
│ └─956 /usr/lib/systemd/systemd-udevd
<刪節>
├─systemd-journald.service
│ └─588 /usr/lib/systemd/systemd-journald
├─atd.service
│ └─1010 /usr/sbin/atd -f
├─system-dbusx2d:1.10x2dorg.freedesktop.problems.slice
│ └─dbus-:1.10-org.freedesktop.problems@0.service
│ └─371197 /usr/sbin/abrt-dbus -t133
├─sshd.service
│ └─893 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
├─vboxservice.service
│ └─802 /usr/sbin/VBoxService -f
├─crond.service
│ └─1011 /usr/sbin/crond -n
├─NetworkManager.service
│ └─765 /usr/sbin/NetworkManager --no-daemon
├─switcheroo-control.service
│ └─787 /usr/libexec/switcheroo-control
<刪節>
這個樹狀視圖顯示了所有的用戶和系統切片,以及每個控制組內正在運行的服務和程序。注意叫作 scope
(範圍)的單元,它將相關的程序組成一個管理單元,在上面列出的結果中就是 user-1000.slice
。user-1000.slice/session-7.scope
控制組包含了 GUI 桌面程序層次結構,以 LXDM 顯示管理器會話和其所有的子任務開始,包括像 Bash 命令行解釋器和 Thunar GUI 文件管理器之類的程序。
配置文件中不定義範圍單元,而是作為啟動相關程序組的結果程序化生成的。範圍單元不創建或啟動作為控制組的組成部分運行的進程。範圍內的所有進程都是平等的,沒有內部的層次結構。一個範圍的生命周期在第一個進程創建時開始,在最後一個進程銷毀時結束。
在你的桌面打開多個窗口,比如終端模擬器、LibreOffice、或者任何你想打開的,然後切換到一個可用的虛擬控制台,啟動類似 top
或 Midnight Commander 的程序。在主機運行 systemd-cgls
命令,留意整體的層次結構和範圍單元。
systemd-cgls
命令提供的控制組層次結構表示(以及組成控制組單元的細節),比我見過的其他任何指令都要完整。和 ps
命令提供的輸出相比,我喜歡 systemd-cgls
命令更簡潔的樹形表示。
來自朋友們的一點幫助
介紹完這些基礎知識後,我曾計划過深入研究控制組的更多細節,以及如何使用,但是我在 Opensource.com 的姐妹網站 Enable Sysadmin 上發現了一系列四篇優秀文章,由 Red Hat 公司的 Steve Ovens 所作。與其從頭重寫 Steve 的文章,我覺得倒不如通過鏈接到這些文章,利用他的控制組專業知識:
像我一樣享受這些文章並從中汲取知識吧。
其他資源
互聯網上充斥著大量關於 systemd 的信息,但大部分都簡短生硬、愚鈍、甚至令人誤解。除了本文提到的資源,下面的網頁提供了關於 systemd 啟動更詳細可靠的信息。自從我開始這一系列的文章來反映我所做的研究以來,這個的列表已經變長了。
- Fedora 項目有一個優質實用的 systemd 指南,幾乎有你使用 systemd 配置、管理、維護一個 Fedora 計算機需要知道的一切。
- Fedora 項目還有一個好用的 速查表,交叉引用了古老的 SystemV 命令和對應的 systemd 命令。
- systemd.unit(5) 手冊頁 包含了一個不錯的單元文件中各個節的列表,以及這些節的配置選項和簡潔的描述。
- Red Hat 文檔包含了一個 單元文件結構 的有用描述,還有一些其他的重要信息。
- 要獲取 systemd 的詳細技術信息和創立的原因,查看 Freedesktop.org 的 systemd 描 述。這個使我發現過的最棒頁面之一,因為其中包含了許多指向其他重要準確文檔的鏈接。
- Linux.com 上 「systemd 的更多樂趣」 提供了更高級的 systemd 信息和提示。
- 查看 systemd.resource-control(5) 的手冊頁
- 查看 Linux 內核用戶和管理員指南 中的 控制組 v2 條目。
還有一系列針對系統管理員的深度技術文章,由 systemd 的設計者和主要開發者 Lennart Poettering 所作。這些文章寫於 2010 年 4 月到 2011 年 9 月之間,但在當下仍然像當時一樣有 價值。關於 systemd 及其生態的許多其他優秀的作品都是基於這些文章的。
- Rethinking PID 1
- systemd for Administrators, Part I
- systemd for Administrators, Part II
- systemd for Administrators, Part III
- systemd for Administrators, Part IV
- systemd for Administrators, Part V
- systemd for Administrators, Part VI
- systemd for Administrators, Part VII
- systemd for Administrators, Part VIII
- systemd for Administrators, Part IX
- systemd for Administrators, Part X
- systemd for Administrators, Part XI
via: https://opensource.com/article/20/10/cgroups
作者:David Both 選題:lujun9972 譯者:YungeG 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive