#systemd攻略
##相關文檔
[arch 的 systemd 說明頁面 (簡體中文)](https://wiki.archlinux.org/index.php/Systemd_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87))
[fedora 的 systemd 說明頁面](http://fedoraproject.org/wiki/Packaging:Systemd,中文:https://fedoraproject.org/wiki/Systemd/zh-cn)
[紅帽7官方文檔 SYSTEM ADMINISTRATOR'S GUIDE](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System_Administrators_Guide/)
[systemd 的手冊頁](http://www.freedesktop.org/software/systemd/man)
[systemd.unit 中文手冊 - 金步國](http://www.jinbuguo.com/systemd/systemd.unit.html)
[Systemd 入門教程:命令篇 -阮一峰](http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html)
[Systemd 入門教程:實戰篇 -阮一峰](http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-part-two.html)
[How to debug Systemd problems](http://fedoraproject.org/wiki/How_to_debug_Systemd_problems)
[systemd Optimizations優化](https://freedesktop.org/wiki/Software/systemd/Optimizations/)
[fedora What is D-Bus?](https://freedesktop.org/wiki/Software/dbus/)
[fedora IntroductionToDBus](https://www.freedesktop.org/wiki/IntroductionToDBus/)
[DBus學習筆記](http://kb.cnblogs.com/page/76759/2/)
[systemd/Timers (簡體中文)](https://wiki.archlinux.org/index.php/Systemd/Timers_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87))
[www.kernel.org](https://www.kernel.org/doc/Documentation/)
##帶着疑惑看文檔
###第一關:基礎問題
* systemd背景基礎命令有哪些?
* jounalctl日志管理命令知多少?
* 如何開機啟動httpd.service?
* systemctl list-units 和 systemctl list-unit-files 輸出有什么區別?
* systemctl --failed 輸出的是什么?
* static invalid 是什么意思?
```
#systemctl list-unit-files
UNIT FILE STATE
proc-sys-fs-binfmt_misc.automount static
crond.service enabled
dbus-org.freedesktop.network1.service invalid
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
```
* 6u的cgroup和7u的cgroup有哪些區別?
* 7u的cgroup中的slice,scope,service的概念區別是什么?
* 如何在6u上管理cgroup?libcgroup
* 如何在7u上管理cgroup?systemd-run
* 在7u上從臨時創建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@jiangyi02.sqa.zmf /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}'
```
##如何讀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
2. 然后,你將開始對每一類型的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,首先,
* [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也就失敗了,只有B成功了,A才能成功;
* 建議搭配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](https://wiki.archlinux.org/index.php/D-Bus)
[Dbus page at freedesktop.org](https://www.freedesktop.org/wiki/Software/dbus/)
[IntroductionToDBus at IntroductionToDBus](https://www.freedesktop.org/wiki/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 (簡體中文)](https://wiki.archlinux.org/index.php/Systemd/Timers_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)).
####服務單元
每個 .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@baseos_server01.cloud.dg /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@baseos_server01.cloud.dg /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@baseos_server01.cloud.dg /home/ahao.mah]
#journalctl --file /run/log/journal/613fd1717b844226af5ea83f4849d6dd/system.journal
```
第二種:指定目標目錄
```
[root@jiangyi01.sqa.zmf /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的時候,你可以使用!
####7u的systemd-journald默認幫你存多少日志量?
* 默認日志最大限制為所在文件系統容量的 10%,即:如果 /var/log/journal 儲存在 50GiB 的根分區中,那么日志最多存儲 5GiB 數據。可以修改配置文件指定最大限制。如限制日志最大 50MiB:
```
/etc/systemd/journald.conf
SystemMaxUse=50M
```
####7u上如何手動清理日志?
/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](https://wiki.archlinux.org/index.php/Syslog-ng#Overview)
*
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.
###7u上的cgroup淺談
其實,網上對6u的介紹比較多,但是7u的較少一些,最重要的是理解cgroup的內部邏輯和機制,7u上最好的文檔就是man手冊,熟悉man手冊,對systemd的深入了解至關重要;基本的概念其實沒有必要在本文中再重復重復重復,而是在腦海里對其整個體系結構有一個框架,帶着疑問去看man手冊;
####帶着疑問看man手冊
* 6u上的libconfig(/etc/cgconfig.conf),7u上還有嗎?
####參考鏈接
[Cgroups at wiki.archlinux.org](https://wiki.archlinux.org/index.php/Cgroups)
[紅帽官方7u的cgroup文檔](https://access.redhat.com/documentation/zh-CN/Red_Hat_Enterprise_Linux/7/html-single/Resource_Management_Guide/index.html#br-Systemd_Unit_Types)
[紅帽官方6u的cgroup文檔](https://access.redhat.com/documentation/zh-CN/Red_Hat_Enterprise_Linux/6/html/Resource_Management_Guide/index.html)
[Blog(6u): Linux資源管理之cgroups簡介](http://tech.meituan.com/cgroups.html)
對6u的cgroup講解的很好[Blog(6u): how to use cgroup](http://tiewei.github.io/devops/howto-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@jiangyi01.sqa.zmf /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/alisys/dragoon/bin/DragoonAgent
│ ├─ 1556 /usr/alisys/dragoon/bin/DragoonAgent
│ ├─ 1557 /usr/alisys/dragoon/bin/DragoonAgent
│ ├─ 1558 /usr/alisys/dragoon/bin/DragoonAgent
│ ├─ 1560 /usr/alisys/dragoon/bin/DragoonAgent
│ ├─ 1561 /usr/alisys/dragoon/bin/DragoonAgent
│ ├─119532 /home/staragent/bin/staragentd
│ └─119533 staragent-core
..
..
```
當我新打開一個session,如下,會產生一樹枝:session-86942.scope
```
[root@jiangyi01.sqa.zmf /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/alisys/dragoon/bin/DragoonAgent
│ ├─ 1556 /usr/alisys/dragoon/bin/DragoonAgent
│ ├─ 1557 /usr/alisys/dragoon/bin/DragoonAgent
│ ├─ 1558 /usr/alisys/dragoon/bin/DragoonAgent
│ ├─ 1560 /usr/alisys/dragoon/bin/DragoonAgent
│ ├─ 1561 /usr/alisys/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 7u
* transient cgroup(臨時 cgroup):請使用 systemd-run 指令啟動此服務,如此,可以限制此服務在運行時所用資源。對 systemd 進行 API 調用,應用程序可以動態創建臨時 cgroup。
* persistent cgroup(永久 cgroup),請對其單位配置文件進行編寫。系統重啟后,此項配置會被保留,所以它可以用於管理自動啟動的服務。請注意,scope 單位不能以此方式創建。
####7u上創建臨時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@jiangyi01.sqa.zmf /home/ahao.mah]
#systemd-run --unit=toptest --slice=test top -b
Running as unit toptest.service.
現在,toptest.service 名稱可以與 systemctl 指令結合,以監控或修改 cgroup。
```
slice輸出
```
[root@jiangyi01.sqa.zmf /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@jiangyi01.sqa.zmf /home/ahao.mah]
#systemctl -t service | grep test
toptest.service loaded active running /usr/bin/top -b
```
配合systemctl
```
[root@jiangyi01.sqa.zmf /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 jiangyi01.sqa.zmf top[94889]: 120293 root 20 0 0 0 0 S 0.0 0.0 0:00.17 kworker/1+
Aug 15 13:23:08 jiangyi01.sqa.zmf top[94889]: 120935 root 20 0 0 0 0 S 0.0 0.0 0:22.16 kworker/6+
Aug 15 13:23:08 jiangyi01.sqa.zmf top[94889]: 122864 root 20 0 0 0 0 S 0.0 0.0 0:04.90 kworker/9+
Aug 15 13:23:08 jiangyi01.sqa.zmf top[94889]: 124341 root 0 -20 0 0 0 S 0.0 0.0 8:56.26 kworker/9+
Aug 15 13:23:08 jiangyi01.sqa.zmf top[94889]: 125657 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kworker/1+
Aug 15 13:23:08 jiangyi01.sqa.zmf top[94889]: 126324 root 20 0 0 0 0 S 0.0 0.0 0:02.37 kworker/1+
Aug 15 13:23:08 jiangyi01.sqa.zmf top[94889]: 127006 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kworker/1+
Aug 15 13:23:08 jiangyi01.sqa.zmf top[94889]: 128144 root 0 -20 0 0 0 S 0.0 0.0 8:55.18 kworker/1+
Aug 15 13:23:08 jiangyi01.sqa.zmf top[94889]: 129070 root 0 -20 0 0 0 S 0.0 0.0 0:00.30 kworker/2+
Aug 15 13:23:08 jiangyi01.sqa.zmf top[94889]: 130319 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kworker/1+
```
####7u上創建永久 cgroup
上面,我們已經創建了一個臨時cgroup,如果想讓它永久,下次開機還存在,我們只需要使用: systemctl enable 指令,動運行此指令會在 /usr/lib/systemd/system/ 目錄中創建單位文件。如要對 cgroup 做出永久改變,請添加或修改其單位文件中的配置參數
####7u上刪除cgroup
兩種方式:
* 終止一個unit:
```systemctl stop name.service```
* 終止多個unit,pid用逗號分隔:
```systemctl kill name.service --kill-who=PID,... --signal=signal ```
永久刪除一個cgroup:```systemctl disable name.service ```
####7u上修改crgroup:
兩種方式
* 命令行:臨時修改cgroup:systemctl set-property
```
~]# systemctl set-property httpd.service CPUShares=600 MemoryLimit=500M
```
* 修改文件:所有被 systemd 監管的永久單位都在 /usr/lib/systemd/system/ 目錄中有一個單位配置文件。如要修改 service 單位的參數,請修改此配置文件。
####6u上使用cgroup
蝦面這個系列文章簡單的實例寫的不錯
[linux cgroups 概述](http://xiezhenye.com/2013/10/linux-cgroups-%E6%A6%82%E8%BF%B0.html)
[用 cgroups 管理 cpu 資源](http://xiezhenye.com/2013/10/%E7%94%A8-cgroups-%E7%AE%A1%E7%90%86-cpu-%E8%B5%84%E6%BA%90.html)
[用 cgroups 管理進程磁盤 io](http://xiezhenye.com/2013/10/%E7%94%A8-cgroups-%E7%AE%A1%E7%90%86%E8%BF%9B%E7%A8%8B%E7%A3%81%E7%9B%98-io.html)
[用 cgruops 管理進程內存占用](http://xiezhenye.com/2013/10/%E7%94%A8-cgruops-%E7%AE%A1%E7%90%86%E8%BF%9B%E7%A8%8B%E5%86%85%E5%AD%98%E5%8D%A0%E7%94%A8.html)
####cgroup中幾個問題解答
* 6u的cgroup和7u的cgroup有哪些區別?
* 7u的cgroup中的slice,scope,service的概念區別是什么?
* 如何在6u上管理cgroup?libcgroup
* 如何在7u上管理cgroup?systemd-run
* 在7u上從臨時創建cgroup到永久創建cgroup需要做什么?
* cgroup中cpu管理中的CPUShares,cpu.cfs_period_us 和 cpu.cfs_quota_us 你需要清楚
```
在 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 即可。
```
* cgroup中cpuacct管理中cpuacct.stat統計使用量,你需要知道
```
cpuacct 子系統專門用來做 cpu 資源統計。cpuacct.stat 統計了該控制組中進程用戶態和內核態的 cpu 使用量,單位是 USER_HZ,也就是 jiffies、cpu 滴答數。每秒的滴答數可以用 getconf CLK_TCK 來獲取,通常是 100。將看到的值除以這個值就可以換算成秒。
cpuacct.usage 和 cpuacct.usage_percpu 是該控制組中進程消耗的 cpu 時間,單位是納秒。后者是分 cpu 統計的。
```
* cpu,mem,等等的管理,你需要對```/sys/fs/cgroup/memory/```有大致的了解