天天看點

10分鐘教你如何劃重點——Systemd最全攻略

本文,更像是一個學習指南,裡面沒有詳細的一條一條指令的解釋,畢竟熟悉指令網上搜很多,本文更像是一個文檔指南,或者說是本人自己的的QA,把自己當初一下沒有想到的問題,重點記錄下來,帶你了解systemd的犄角旮旯,尤其是如何從man手冊入手,畢竟man手冊才是權威的,強大的man手冊背後其實正隐藏了systemd各個邏輯之間的關聯。

相關文檔

  • arch 的 systemd 說明頁面 (簡體中文)
  • fedora 的 systemd 說明頁面
  • 紅帽7官方文檔 SYSTEM ADMINISTRATOR’S GUIDE
  • systemd 的手冊頁
  • systemd.unit 中文手冊 - 金步國
  • Systemd 入門教程:指令篇 -阮一峰
  • Systemd 入門教程:實戰篇 -阮一峰
  • How to debug Systemd problems
  • systemd Optimizations優化
  • fedora What is D-Bus?
  • fedora IntroductionToDBus
  • systemd/Timers (簡體中文)
  • www.kernel.org

1帶着疑惑看文檔

     在平時看文檔的時候,最好帶着疑問去看,效果好,了解快,下面我羅列了一系列的問題,都是曾經想過的問題,這些問題,也在整個文檔中是可以找到答案的。

第一關:基礎問題

  • systemd背景基礎指令有哪些?
  • jounalctl日志管理指令知多少?
  • 如何開機啟動httpd.service?
  • systemctl list-units 和 systemctl list-unit-files 輸出有什麼差別?
  • systemctl –failed 輸出的是什麼?
  • static invxxxd 是什麼意思?
#systemctl list-unit-files
UNIT FILE                              STATE
proc-sys-fs-binfmt_misc.automount      static
crond.service                          enabled
dbus-org.freedesktop.network1.service  invxxxd
cpupower.service                       disabled      

第二關:中級問題

  • systemd中的unit是什麼概念?
  • unit檔案類型有哪些?
  • 如何編寫一個unit檔案?
  • unit檔案中哪些參數是常見的,重要的?

第三關:進階問題

  • DBUS是什麼?
  • Target是什麼?Target 與 傳統 RunLevel 的對應關系?
#systemctl list-units
slices.target
dbus.socket
test.slice
sshd.service
sys-devices-platform-serial8250-tty-ttyS3.device
brandbot.path
logstore.mount
systemd-journald.socket
systemd-tmpfiles-clean.timer
proc-sys-fs-binfmt_misc.automount      
  • el6的cgroup和el7的cgroup有哪些差別?
  • el7的cgroup中的slice,scope,service的概念差別是什麼?
  • 如何在el6上管理cgroup?libcgroup
  • 如何在el7上管理cgroup?systemd-run
  • 在el7上從臨時建立cgroup到永久建立cgroup需要做什麼?
  • cgroup中cpu管理中的CPUShares,cpu.cfs_period_us 和 cpu.cfs_quota_us 你需要清楚
  • cgroup中mem管理中的memory.max_usage_in_bytes 參數你需要清楚
  • cgroup中cpuacct管理中cpuacct.stat統計使用量,你需要知道
  • cpu,mem,等等的管理,你需要對

    /sys/fs/cgroup/memory/

    有大緻的了解
[root@localhost /usr/lib/systemd/system]
#cat /proc/1049/cgroup
10:memory:/
9:cpuset:/
8:hugetlb:/
7:perf_event:/
6:cpuacct,cpu:/
5:blkio:/
4:freezer:/
3:devices:/
2:net_cls:/
1:name=systemd:/system.slice/syslog-ng.service      
  • 一些指令
#systemd-cgls
#mount|awk '$5=="cgroup" {print $0}'      
  • 背後邏輯圖
10分鐘教你如何劃重點——Systemd最全攻略
10分鐘教你如何劃重點——Systemd最全攻略

2如何讀Man手冊

在linux上,其實很多知識在man手冊裡的都可以獲得的,但是,對于新鮮的systemd,也許作為小白,可能一開始還真不太知道該man什麼?強大的man手冊本身背後的邏輯和關聯性很好的反映了systemd背後知識體系的關系

  1. 首先,應該先#man 1 systemd 這裡入手 ,你将對systemd有一個全面的了解,并且知道systemd有12種類型的unit:
  2. 看完#man 1 systemd,你肯定會對12種類型的unit有很多的疑問,究竟這些unit的細節;
man systemd.service
 man systemd.socket
 man systemd.target
 man systemd.device
 man systemd.mount
 man systemd.automount
 man systemd.snapshot
 man systemd.timer
 man systemd.swap
 man systemd.path
 man systemd.slice
 man systemd.scope      

最為特殊的是systemd.special,從這裡你将獲知很多的系統特殊的東西:

man systemd.special
    basic.target, bluetooth.target, ctrl-alt-del.target, cryptsetup.target, cryptsetup-pre.target, dbus.service, dbus.socket, default.target,
   display-manager.service, emergency.target, exit.target, final.target, getty.target, graphical.target, halt.target, hibernate.target,
   hybrid-sleep.target, initrd-fs.target, kbrequest.target, kexec.target, local-fs.target, local-fs-pre.target, multi-user.target, network.target,
   network-online.target, network-pre.target, nss-lookup.target, nss-user-lookup.target, paths.target, poweroff.target, printer.target, reboot.target,
   remote-fs.target, remote-fs-pre.target, rescue.target, initrd-root-fs.target, rpcbind.target, runlevel2.target, runlevel3.target, runlevel4.target,
   runlevel5.target, shutdown.target, sigpwr.target, sleep.target, smartcard.target, sockets.target, sound.target, suspend.target, swap.target,
   sysinit.target, syslog.socket, system-update.target, time-sync.target, timers.target, umount.target, -.slice, system.slice, user.slice,
   machine.slice      
  1. 然後,你将開始對每一類型的unit檔案的文法和參數使用有疑問,此時,你應該#man 5 systemd.unit

systemd全面了解:about unit types

#man 1 systemd      

systemd provides a dependency system between various entities called “units” of 12 different types.

majority of units are configured in unit configuration files, whose syntax and basic set of options is described in systemd.unit(5)

The following unit types are available:
    1. Service units, which start and control daemons and the processes they consist of. For details see systemd.service(5).
    2. Socket units, which encapsulate local IPC or network sockets in the system, useful for socket-based activation. For details about socket units
       see systemd.socket(5), for details on socket-based activation and other forms of activation, see daemon(7).
    3. Target units are useful to group units, or provide well-known synchronization points during boot-up, see systemd.target(5).
    4. Device units expose kernel devices in systemd and may be used to implement device-based activation. For details see systemd.device(5).
    5. Mount units control mount points in the file system, for details see systemd.mount(5).
    6. Automount units provide automount capabilities, for on-demand mounting of file systems as well as parallelized boot-up. See
       systemd.automount(5).
    7. Snapshot units can be used to temporarily save the state of the set of systemd units, which later may be restored by activating the saved
       snapshot unit. For more information see systemd.snapshot(5).
    8. Timer units are useful for triggering activation of other units based on timers. You may find details in systemd.timer(5).
    9. Swap units are very similar to mount units and encapsulate memory swap partitions or files of the operating system. They are described in
       systemd.swap(5).
   10. Path units may be used to activate other services when file system objects change or are modified. See systemd.path(5).
   11. Slice units may be used to group units which manage system processes (such as service and scope units) in a hierarchical tree for resource
       management purposes. See systemd.slice(5).
   12. Scope units are similar to service units, but manage foreign processes instead of starting them as well. See systemd.scope(5).      

帶你劃重點

如何自己寫一個unit?

其實,我們經常寫的最多的是service unit,還有xx.socket ,xx.scope,xx.timer 一般一個unit檔案中,都會有Unit區塊,寫的是一些介紹類,如果是xx.service ,那麼就會有一個[Service]區塊,如果是xx.timer,就會有一個[Timer]區塊,那service unit舉例子:

  • [Unit]是每個unit檔案都需要有的
  • [Service] 區塊:定義如何啟動目前服務,
  • [Install區塊],定義如何安裝這個配置檔案,即怎樣做到開機啟動。
#systemctl cat httpd.service
# /usr/lib/systemd/system/httpd.service
[Unit]
Description=The Apache HTTP Server   //
After=network.target remote-fs.target nss-lookup.target
Documentation=man:httpd(8)
Documentation=man:apachectl(8)
[Service]
Type=notify
CPUShares=1500
MemoryLimit=1G
EnvironmentFile=/etc/sysconfig/httpd
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
ExecStop=/bin/kill -WINCH ${MAINPID}
# We want systemd to give httpd some time to finish gracefully, but still want
# it to kill httpd after TimeoutStopSec if something went wrong during the
# graceful stop. Normally, Systemd sends SIGTERM signal right after the
# ExecStop, which would kill httpd. We are sending useless SIGCONT here to give
# httpd time to finish.
KillSignal=SIGCONT
PrivateTmp=true
[Install]
WantedBy=multi-user.target      

依賴關系和前後順序

  • 依賴關系:Requires和Wants
  • 前後順序:After,Before

依賴關系,前後順序是比較容易混淆的,當使用Requires和Wants的時候,

  • 如果不搭配After,Before使用,比如:

unit A Requires unit B, 那麼A和B會一起啟動,如果B失敗了,A也就失敗了,隻有B成功了,A才能成功;

unit A Wants unit B, 那麼A和B會一起啟動,如果B失敗了,A未必失敗,A不強依賴B

  • 建議搭配After,Before使用,比如:

unit A Requires unit B, 那麼同時最好unit A中寫上:After=B

unit處理依賴關系:Requires和Wants的差別?

使用systemd時,可通過正确編寫單元配置檔案來解決其依賴關系。典型的情況是,單元A要求單元B在A啟動之前運作。在此情況下,向單元A配置檔案中的 [Unit] 段添加 Requires=B 和 After=B 即可。若此依賴關系是可選的,可添加 Wants=B 和 After=B。請注意 Wants= 和Requires= 并不意味着 After=,即如果 After= 選項沒有制定,這兩個單元将被并行啟動。 依賴關系通常被用在服務(service)而不是目标(target)上。例如, network.target 一般會被某個配置網絡接口的服務引入,是以,将自定義的單元排在該服務之後即可,因為 network.target 已經啟動。

unit檔案中,服務類型: Type= 參數

編寫自定義的 service 檔案時,可以選擇幾種不同的服務啟動方式。啟動方式可通過配置檔案 [Service] 段中的 Type= 參數進行設定。

  • Type=simple(預設值):systemd認為該服務将立即啟動。服務程序不會fork。如果該服務要啟動其他服務,不要使用此類型啟動,除非該服務是socket激活型。
  • Type=forking:systemd認為當該服務程序fork,且父程序退出後服務啟動成功。對于正常的守護程序(daemon),除非你确定此啟動方式無法滿足需求,使用此類型啟動即可。使用此啟動類型應同時指定 PIDFile=,以便systemd能夠跟蹤服務的主程序。
  • Type=oneshot:這一選項适用于隻執行一項任務、随後立即退出的服務。可能需要同時設定 RemainAfterExit=yes 使得 systemd 在服務程序退出之後仍然認為服務處于激活狀态。
  • Type=notify:與 Type=simple 相同,但約定服務會在就緒後向 systemd 發送一個信号。這一通知的實作由 libsystemd-daemon.so 提供。
  • Type=dbus:若以此方式啟動,當指定的 BusName 出現在DBus系統總線上時,systemd認為服務就緒。
  • Type=idle: systemd會等待所有任務處理完成後,才開始執行idle類型的單元。其他行為和Type=simple 類似。

type的更多解釋可以參考 systemd.service(5)。

什麼是DBus?

參考連結

  • Dbus page at archlinux
  • Dbus page at freedesktop.org
  • IntroductionToDBus at IntroductionToDBus

Install

D-Bus is enabled automatically when using systemd because dbus is a dependency of systemd.

DBus是一種IPC機制

DBus是一種IPC機制,由freedesktop.org項目提供,使用GPL許可證發行,用于程序間通信或程序與核心的通信。

注:Linux中的IPC通信機制還包括,管道(fifo),共享記憶體,信号量,消息隊列,Socket等。

DBus程序間通信主要有三層架構:

  1. 底層接口層:主要是通過libdbus這個函數庫,給予系統使用DBus的能力。
  2. 總線層:主要Message bus daemon這個總線守護程序提供的,在Linux系統啟動時運作,負責程序間的消息路由和傳遞,其中包括Linux核心和Linux桌面環境的消息傳遞。總線守護程序可同時與多個應用程式相連,并能把來自一個應用程式的消息路由到0或者多個其他程式。
  3. 應用封裝層:通過一系列基于特定應用程式架構将DBus的底層接口封裝成友好的Wrapper庫,供不同開發人員使用(DBus官方首頁 http://www.freedesktop.org/wiki/Software/dbus ,提供了大部分程式設計語言的DBus庫版本)。比如libdbus-glib, libdbus-python.

Target和傳統的啟動級别之間的關系

啟動級别(runlevel)是一個舊的概念。現在,systemd 引入了一個和啟動級别功能相似又不同的概念——目标(target)。不像數字表示的啟動級别,每個目标都有名字和獨特的功能,并且能同時啟用多個。一些目标繼承其他目标的服務,并啟動新服務。systemd 提供了一些模仿 sysvinit 啟動級别的目标,仍可以使用舊的 telinit 啟動級别 指令切換。

擷取目前目标

不要使用 runlevel 指令了:

$ systemctl list-units --type=target

修改預設啟動級别/目标

開機啟動進的目标是 default.target,預設連結到 graphical.target (大緻相當于原來的啟動級别5)。可以通過核心參數更改預設啟動級别:

  • systemd.unit=multi-user.target (大緻相當于級别3)
  • systemd.unit=rescue.target (大緻相當于級别1)

另一個方法是修改 default.target。可以通過 systemctl 修改它:

# systemctl set-default multi-user.target

 要覆寫已經設定的default.target,請使用 force: 

# systemctl set-default -f multi-user.target

 可以在 systemctl 的輸出中看到指令執行的效果:連結 /etc/systemd/system/default.target 被建立,指向新的預設啟動級别。

定時器timer是什麼鬼?

定時器是以 .timer 為字尾的配置檔案,記錄由system的裡面由時間觸發的動作, 定時器可以替代 cron 的大部分功能。詳情參閱 systemd/Timers (簡體中文).

服務單元

每個 .timer 檔案所在目錄都得有一個對應的 .service 檔案(如 foo.timer 和 foo.service)。.timer 用于激活并控制 .service 檔案。 .service 檔案中不需要包含 [Install] 部分,因為這由 timer 單元接管。必要時通過在定時器的 [Timer] 部分指定 Unit= 選項來控制一個與定時器不同名的服務單元。

管理

使用 timer 單元時像其他單元一樣 enable 或 start 即可(别忘了添加 .timer 字尾)。要檢視所有已啟用的定時器,運作: $ systemctl list-timers NEXT LEFT LAST PASSED UNIT ACTIVATES Thu 2014-07-10 19:37:03 CEST 11h left Wed 2014-07-09 19:37:03 CEST 12h ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service Fri 2014-07-11 00:00:00 CEST 15h left Thu 2014-07-10 00:00:13 CEST 8h ago logrotate.timer logrotate.service

systemd-journald和syslog之間的秘密

[root@localhost /home/ahao.mah]
#df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2        50G  4.4G   43G  10% /
devtmpfs         32G     0   32G   0% /dev
tmpfs            32G  364K   32G   1% /dev/shm
tmpfs            32G   57M   32G   1% /run   日志存在這裡就是存在記憶體裡,明顯不合理,有的docker機器這裡日志量,占用記憶體量很大,需要解決;
tmpfs            32G     0   32G   0% /sys/fs/cgroup
/dev/sda1       243M   71M  157M  31% /boot
tmpfs           6.3G     0  6.3G   0% /run/user/0
tmpfs           6.3G     0  6.3G   0% /run/user/122575      

如何檢視journal二進制日志檔案?

[root@localhost /home/ahao.mah]
#ll /run/log/journal/613fd1717b844226af5ea83f4849d6dd/system.journal
-rw-r-x---+ 1 root systemd-journal 58720256 Aug 15 10:51 /run/log/journal/613fd1717b844226af5ea83f4849d6dd/system.journal      

使用檢視xxx.journal的方法有兩種:

第一種:指定目标檔案

[root@localhost /home/ahao.mah]
#journalctl --file /run/log/journal/613fd1717b844226af5ea83f4849d6dd/system.journal      

第二種:指定目标目錄

[root@localhost /home/ahao.mah]
#journalctl -D /var/log/journal/      

問題:systemd-journald請不用占用我的記憶體

這裡有個問題,是很多docker的機器,記憶體本來就不多,systemd-journald 産生的日志導入/run/log/journal/裡,占用了大量的記憶體空間,不合理;

通過檢視man手冊,可以知道

#man 5 journald.conf

 你會發現,Storage=的值可以是”volatile”, “persistent”, “auto” and “none”,但是,預設的是auto,

  • volatile代表日志隻存在記憶體中,即/run/log/journal/
  • persistent代表日志隻存在磁盤中,即/var/log/journal/
  • auto代表日志存在磁盤中,或者記憶體中,這個取決于你是否建立/var/log/journal/目錄!!這個也算是一個坑吧,看來大家都需要手動

    mkdir -p /var/log/journal/;systemctl restart systemd-journald

     來解放自己的記憶體了!!!
  • none,表示,日志不保留,全部drop,隻有當你決定不使用systemd-journald的時候,你可以使用!

el7的systemd-journald預設幫你存多少日志量?

  • 預設日志最大限制為所在檔案系統容量的 10%,即:如果 /var/log/journal 儲存在 50GiB 的根分區中,那麼日志最多存儲 5GiB 資料。可以修改配置檔案指定最大限制。如限制日志最大 50MiB:
/etc/systemd/journald.conf
SystemMaxUse=50M      

el7上如何手動清理日志?

/var/log/journal 存放着日志, rm 應該能工作. 或者使用journalctl, 例如:

  • 清理日志使總大小小于 100M: 

    # journalctl --vacuum-size=100M

  • 清理最早兩周前的日志: 

    # journalctl --vacuum-time=2weeks

有了systemd-journald,我們是否還需要syslog-ng,rsyslog?

在man手冊裡

#man journald.conf

,有一段關于systemd-journald和第三方syslog的關系的描述,如果,我們想步子邁大一些,不使用第三方syslog 當然是可以的,如果我們想小步走,可以繼續使用第三方syslog。man手冊介紹了兩種方式讀日志;

  • /run/systemd/journal/syslog + ForwardToSyslog= yes 的方式,傳給syslog-ng,此時,syslog-ng的source必須是
source s_sys {
# Source additional configuration files (.conf extension only)
    system();
    internal();
};      

至于問什麼?請參考:wiki.archlinux.org中介紹的Syslog-ng

* in a second method, a syslog daemon behaves like a normal journal client, and reads messages from the journal files, similarly to journalctl(1). In this method, messages do not have to be read immediately, which allows a logging daemon which is only started late in boot to access all messages since the start of the system. In addition, full structured meta-data is available to it. This method of course is available only if the messages are stored in a journal file at all. So it will not work if Storage=none is set. It should be noted that usually the second method is used by syslog daemons, so the Storage= option, and not the ForwardToSyslog= option, is relevant for them.

3el7上的Cgroup淺淡

其實,網上對el6的介紹比較多,但是el7的較少一些,最重要的是了解cgroup的内部邏輯和機制,el7上最好的文檔就是man手冊,熟悉man手冊,對systemd的深入了解至關重要;基本的概念其實沒有必要在本文中再重複重複,而是在腦海裡對其整個體系結構有一個架構,帶着疑問去看man手冊;

帶着疑問看man手冊

  • el6上的libconfig(/etc/cgconfig.conf),el7上還有嗎?

  • Cgroups at wiki.archlinux.org
  • 紅帽官方el7的cgroup文檔
  • 紅帽官方el6的cgroup文檔
  • Blog(el6): Linux資源管理之cgroups簡介
  • 對el6的cgroup講解的很好Blog(el6): how to use cgroup

與 cgroup 相關的 systemd man文檔

以下的 manual page 包含 systemd 中統一的 cgroup 層級基本資訊:

  • systemd.resource-control(5) —— 描述系統機關共享的資源控制配置選項。
  • systemd.unit(5) —— 描述所有機關配置檔案的共同選項。
  • systemd.slice(5) —— 提供 .slice 機關的基本資訊。
  • systemd.scope(5) —— 提供 .scope 機關的基本資訊。
  • systemd.service(5) —— 提供 .service 機關的基本資訊。

與 cgroup 相關的 Systemd 工具幫助頁面

  • systemd-run(1) —— 此 manual page 列出了 systemd-run 實用工具的全部指令列選項。
  • systemctl(1) —— systemctl 實用工具的 manual page 列出了可用選項及指令。
  • systemd-cgls(1) —— 此 manual page 列出了 systemd-cgls 實用工具的全部指令列選項。
  • systemd-cgtop(1) —— 此 manual page 包含了 systemd-cgtop 實用工具的全部指令列選項。
  • machinectl(1) —— 此 manual page 列出了 machinectl 實用工具的全部指令列選項。
  • systemd.kill(5) —— 此 manual page 為系統機關提供了終止配置選項的概述。

初感受:user.slice使用者會話

[root@localhost /home/ahao.mah]
#systemd-cgls
..
..
├─user.slice
│ ├─user-122575.slice
│ │ └─session-86733.scope
│ │   ├─15404 sshd: ahao.mah [priv
│ │   ├─15406 sshd: ahao.mah@pts/0
│ │   ├─15407 -bash
│ │   ├─15443 sudo su -c bash
│ │   ├─15450 su -c bash
│ │   ├─15451 bash
│ │   ├─91380 systemd-cgls
│ │   └─91381 less
│ └─user-0.slice
│   └─session-1.scope
│     ├─  1554 /usr/xxxsys/dragoon/bin/DragoonAgent
│     ├─  1556 /usr/xxxsys/dragoon/bin/DragoonAgent
│     ├─  1557 /usr/xxxsys/dragoon/bin/DragoonAgent
│     ├─  1558 /usr/xxxsys/dragoon/bin/DragoonAgent
│     ├─  1560 /usr/xxxsys/dragoon/bin/DragoonAgent
│     ├─  1561 /usr/xxxsys/dragoon/bin/DragoonAgent
│     ├─119532 /home/staragent/bin/staragentd
│     └─119533 staragent-core
..
..      

當我新打開一個session,如下,會産生一樹枝:session-86942.scope

[root@localhost /home/ahao.mah]
#systemd-cgls
..
..
├─user.slice
│ ├─user-122575.slice
│ │ ├─session-86942.scope
│ │ │ ├─91454 sshd: ahao.mah [priv
│ │ │ ├─91476 sshd: ahao.mah@pts/1
│ │ │ └─91477 -bash
│ │ └─session-86733.scope
│ │   ├─15404 sshd: ahao.mah [priv
│ │   ├─15406 sshd: ahao.mah@pts/0
│ │   ├─15407 -bash
│ │   ├─15443 sudo su -c bash
│ │   ├─15450 su -c bash
│ │   ├─15451 bash
│ │   ├─91513 systemd-cgls
│ │   └─91514 less
│ └─user-0.slice
│   └─session-1.scope
│     ├─  1554 /usr/xxxsys/dragoon/bin/DragoonAgent
│     ├─  1556 /usr/xxxsys/dragoon/bin/DragoonAgent
│     ├─  1557 /usr/xxxsys/dragoon/bin/DragoonAgent
│     ├─  1558 /usr/xxxsys/dragoon/bin/DragoonAgent
│     ├─  1560 /usr/xxxsys/dragoon/bin/DragoonAgent
│     ├─  1561 /usr/xxxsys/dragoon/bin/DragoonAgent
│     ├─119532 /home/staragent/bin/staragentd
│     └─119533 staragent-core
..
..      

看了上面,你應該對user-0.slice産生疑惑才對,為什麼在user.slice下,會存在user-0.slice這個slice呢??也許猜猜可能知道,這個是集團DragoonAgent 産生的。但是它是怎麼産生的呢?留下這個疑問。

How to use cgroup at el7

  • transient cgroup(臨時 cgroup):請使用 systemd-run 指令啟動此服務,如此,可以限制此服務在運作時所用資源。對 systemd 進行 API 調用,應用程式可以動态建立臨時 cgroup。
  • persistent cgroup(永久 cgroup),請對其機關配置檔案進行編寫。系統重新開機後,此項配置會被保留,是以它可以用于管理自動啟動的服務。請注意,scope 機關不能以此方式建立。

el7上建立臨時cgroup

檢視man手冊,獲得systemd-run用法:

systemd-run(1) manual page

 如下:

用法:
systemd-run --unit=name --scope --slice=slice_name command
解釋:
--unit=toptest  代表您想要此機關被識别的名稱。如果 --unit 沒有被指定,機關名稱會自動生成。建議選擇一個描述性的名字,因為它将代表 systemctl 輸出中的機關。在機關運作時期間,此名字需為獨一無二的。
使用可選的 --scope 參數建立臨時 scope 機關來替代預設建立的 service 機關。
--slice 選項,讓您新近建立的 service 或 scope 機關可以成為指定 slice 的一部分。用現存 slice(如 systemctl -t slice 輸出所示)的名字替代 slice_name,或者通過傳送一個獨有名字來建立新 slice。預設情況下,service 和 scope 做為 system.slice 的一部分被建立。
用您希望在 service 機關中運作的指令替代 command。将此指令放置于 systemd-run 句法的最末端。這樣,此指令的參數就不會與 systemd-run 參數混淆。
除上述選項外,systemd-run 也有一些其它可用參數。例如,--description 可以建立對機關的描述;service 程序結束後,--remain-after-exit 可以收集運作時資訊;--machine 選項可以在密閉容器中執行指令。更多資訊,請參閱 systemd-run(1) manual page。
栗子:
[root@localhost /home/ahao.mah]
#systemd-run --unit=toptest --slice=test top -b
Running as unit toptest.service.
現在,toptest.service 名稱可以與 systemctl 指令結合,以監控或修改 cgroup。      

slice輸出

[root@localhost /home/ahao.mah]
#systemctl -t slice
UNIT                         LOAD   ACTIVE SUB    DESCRIPTION
-.slice                      loaded active active Root Slice
machine.slice                loaded active active Virtual Machine and Container Slice
system-getty.slice           loaded active active system-getty.slice
system-systemd\x2dfsck.slice loaded active active system-systemd\x2dfsck.slice
system.slice                 loaded active active System Slice
test.slice                   loaded active active test.slice
user-0.slice                 loaded active active user-0.slice
user-122575.slice            loaded active active user-122575.slice
user.slice                   loaded active active User and Session Slice      

service輸出

[root@localhost /home/ahao.mah]
#systemctl -t service | grep test
  toptest.service                                       loaded active running /usr/bin/top -b      

配合systemctl

[root@localhost /home/ahao.mah]
#systemctl status toptest.service
● toptest.service - /usr/bin/top -b
   Loaded: loaded (/run/systemd/system/toptest.service; static; vendor preset: disabled)
  Drop-In: /run/systemd/system/toptest.service.d
           └─50-Description.conf, 50-ExecStart.conf, 50-Slice.conf
   Active: active (running) since Mon 2016-08-15 13:17:30 CST; 5min ago
 Main PID: 94889 (top)
   CGroup: /test.slice/toptest.service
           └─94889 /usr/bin/top -b
Aug 15 13:23:08 localhost top[94889]: 120293 root      20   0       0      0      0 S   0.0  0.0   0:00.17 kworker/1+
Aug 15 13:23:08 localhost top[94889]: 120935 root      20   0       0      0      0 S   0.0  0.0   0:22.16 kworker/6+
Aug 15 13:23:08 localhost top[94889]: 122864 root      20   0       0      0      0 S   0.0  0.0   0:04.90 kworker/9+
Aug 15 13:23:08 localhost top[94889]: 124341 root       0 -20       0      0      0 S   0.0  0.0   8:56.26 kworker/9+
Aug 15 13:23:08 localhost top[94889]: 125657 root      20   0       0      0      0 S   0.0  0.0   0:00.00 kworker/1+
Aug 15 13:23:08 localhost top[94889]: 126324 root      20   0       0      0      0 S   0.0  0.0   0:02.37 kworker/1+
Aug 15 13:23:08 localhost top[94889]: 127006 root      20   0       0      0      0 S   0.0  0.0   0:00.00 kworker/1+
Aug 15 13:23:08 localhost top[94889]: 128144 root       0 -20       0      0      0 S   0.0  0.0   8:55.18 kworker/1+
Aug 15 13:23:08 localhost top[94889]: 129070 root       0 -20       0      0      0 S   0.0  0.0   0:00.30 kworker/2+
Aug 15 13:23:08 localhost top[94889]: 130319 root      20   0       0      0      0 S   0.0  0.0   0:00.00 kworker/1+      

el7上建立永久 cgroup

上面,我們已經建立了一個臨時cgroup,如果想讓它永久,下次開機還存在,我們隻需要使用: systemctl enable 指令,動運作此指令會在 /usr/lib/systemd/system/ 目錄中建立機關檔案。如要對 cgroup 做出永久改變,請添加或修改其機關檔案中的配置參數

el7上删除cgroup

兩種方式:

  • 終止一個unit: 

    systemctl stop name.service

  • 終止多個unit,pid用逗号分隔:

    systemctl kill name.service --kill-who=PID,... --signal=signal

永久删除一個cgroup:

systemctl disable name.service

el7上修改crgroup:

兩種方式

  • 指令行:臨時修改cgroup:systemctl set-property
~]# systemctl set-property httpd.service CPUShares=600 MemoryLimit=500M      
  • 修改檔案:所有被 systemd 監管的永久機關都在 /usr/lib/systemd/system/ 目錄中有一個機關配置檔案。如要修改 service 機關的參數,請修改此配置檔案。

el6上使用cgroup

蝦面這個系列文章簡單的執行個體寫的不錯

  • linux cgroups 概述
  • 用 cgroups 管理 cpu 資源
  • 用 cgroups 管理程序磁盤 io
  • 用 cgruops 管理程序記憶體占用

cgroup中幾個問題解答

在 cpu 子系統中,cpu.stat 就是用前面那種方法做的資源限制的統計了。nr_periods、nr_throttled 就是總共經過的周期,和其中受限制的周期。throttled_time 就是總共被控制組掐掉的 cpu 使用時間。
還有個 cpu.shares, 它也是用來限制 cpu 使用的。但是與 cpu.cfs_quota_us、cpu.cfs_period_us 有挺大差別。cpu.shares 不是限制程序能使用的絕對的 cpu 時間,而是控制各個組之間的配額。比如
/cpu/cpu.shares : 1024
/cpu/foo/cpu.shares : 2048      
  • cgroup中mem管理中的limit_in_bytes參數你需要清楚
# echo 10485760 >/sys/fs/cgroup/memory/foo/memory.limit_in_bytes
即可限制該組中的程序使用的實體記憶體總量不超過 10MB。對 memory.memsw.limit_in_bytes 來說,則是限制虛拟記憶體使用。memory.memsw.limit_in_bytes 必須大于或等于 memory.limit_in_byte。這些值還可以用更友善的 100M,20G 這樣的形式來設定。要解除限制,就把這個值設為 -1 即可。      
cpuacct 子系統專門用來做 cpu 資源統計。cpuacct.stat 統計了該控制組中程序使用者态和核心态的 cpu 使用量,機關是 USER_HZ,也就是 jiffies、cpu 滴答數。每秒的滴答數可以用 getconf CLK_TCK 來擷取,通常是 100。将看到的值除以這個值就可以換算成秒。
cpuacct.usage 和 cpuacct.usage_percpu 是該控制組中程序消耗的 cpu 時間,機關是納秒。後者是分 cpu 統計的。      
  • /sys/fs/cgroup/memory/

    有大緻的了解。
10分鐘教你如何劃重點——Systemd最全攻略
10分鐘教你如何劃重點——Systemd最全攻略

繼續閱讀