systemd攻略

#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/```有大致的了解

 

posted @ 2016-08-16 00:10  苏小北1024  阅读(3320)  评论(0编辑  收藏  举报