Linux中國

在 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,並將控制組作為一個整體管理系統資源。這意味著資源能夠基於應用管理,而不是由組成應用的各個進程來管理。

控制組的控制單元稱作 切片單元 slice unit 。切片是允許 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 &apos;systemctl list-unit-files&apos;.
[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.sliceuser-1000.slice/session-7.scope 控制組包含了 GUI 桌面程序層次結構,以 LXDM 顯示管理器會話和其所有的子任務開始,包括像 Bash 命令行解釋器和 Thunar GUI 文件管理器之類的程序。

配置文件中不定義範圍單元,而是作為啟動相關程序組的結果程序化生成的。範圍單元不創建或啟動作為控制組的組成部分運行的進程。範圍內的所有進程都是平等的,沒有內部的層次結構。一個範圍的生命周期在第一個進程創建時開始,在最後一個進程銷毀時結束。

在你的桌面打開多個窗口,比如終端模擬器、LibreOffice、或者任何你想打開的,然後切換到一個可用的虛擬控制台,啟動類似 topMidnight Commander 的程序。在主機運行 systemd-cgls 命令,留意整體的層次結構和範圍單元。

systemd-cgls 命令提供的控制組層次結構表示(以及組成控制組單元的細節),比我見過的其他任何指令都要完整。和 ps 命令提供的輸出相比,我喜歡 systemd-cgls 命令更簡潔的樹形表示。

來自朋友們的一點幫助

介紹完這些基礎知識後,我曾計划過深入研究控制組的更多細節,以及如何使用,但是我在 Opensource.com 的姐妹網站 Enable Sysadmin 上發現了一系列四篇優秀文章,由 Red Hat 公司的 Steve Ovens 所作。與其從頭重寫 Steve 的文章,我覺得倒不如通過鏈接到這些文章,利用他的控制組專業知識:

  1. 一個 Linux 系統管理員對控制組的介紹
  2. 如何用 CPUShares 管理控制組
  3. 用更難的方式,手動管理控制組
  4. 用 systemd 管理控制組

像我一樣享受這些文章並從中汲取知識吧。

其他資源

互聯網上充斥著大量關於 systemd 的信息,但大部分都簡短生硬、愚鈍、甚至令人誤解。除了本文提到的資源,下面的網頁提供了關於 systemd 啟動更詳細可靠的信息。自從我開始這一系列的文章來反映我所做的研究以來,這個的列表已經變長了。

還有一系列針對系統管理員的深度技術文章,由 systemd 的設計者和主要開發者 Lennart Poettering 所作。這些文章寫於 2010 年 4 月到 2011 年 9 月之間,但在當下仍然像當時一樣有 價值。關於 systemd 及其生態的許多其他優秀的作品都是基於這些文章的。

via: https://opensource.com/article/20/10/cgroups

作者:David Both 選題:lujun9972 譯者:YungeG 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的電子郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國