作为这个系列文章的最后一篇,作者将介绍 systemd 以及它如何帮助管理 Cgroup(点击参考原文)。
在开始之前,建议先读完本系列的前三篇文章,便于更好地理解。
使用 systemd 管理 Cgroup
在默认情况下,systemd 会为其监控的每个服务在 system.slice
下创建一个新的 Cgroup。回到 OpenShift 控制平面主机,运行 systemd-cglsshows
命令,可以看到(简洁起见,这里只展示其中一部分输出):
plain
└─system.slice
├─sssd.service
├─lvm2-lvmetad.service
├─rsyslog.service
├─systemd-udevd.service
├─systemd-logind.service
├─systemd-journald.service
├─crond.service
├─origin-node.service
├─docker.service
├─dnsmasq.service
├─tuned.service
├─sshd.service
├─NetworkManager.service
├─dbus.service
├─polkit.service
├─chronyd.service
├─auditd.service
└─getty@tty1.service
我们可以通过编辑 systemd service 文件来进行更改,一共有三种方法:
- 编辑 service 文件本身;
- 使用 drop-in 文件;
- 使用
systemctl set-property
命令。这个过程与手动编辑文件相同,但systemctl
会为我们创建所需要的条目。
下面来详细介绍这三种方法。
编辑 Service 文件本身
我先创建一个非常简单的单元文件,运行脚本:
bash
[Service]
Type=oneshot
ExecStart=/root/generate_load.sh
TimeoutSec=0
StandardOutput=tty
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
它的 bash 脚本只有两行:
bash
#!/bin/bash
/usr/bin/cat /dev/urandom > /dev/null &
检查 systemd-cgls
输出,发现新服务嵌套在 system.slice
下(只展示其中一部分输出):
bash
└─system.slice
├─cat.service
├─tuned.service
├─sshd.service
├─NetworkManager.service
├─sssd.service
├─dbus.service
│ └─getty@tty1.service
└─systemd-logind.service
如果在 systemd service 文件中添加下列语句,会发生什么?
bash
Slice=my-beautiful-slice.slice
systemd-cgls
的输出有些出人意料,而且 cat.service
文件也被深层嵌套着:
bash
Control group /:
├─my.slice
│ └─my-beautiful.slice
│ └─my-beautiful-slice.slice
│ └─cat.service
│ └─4010 /usr/bin/cat /dev/urandom
为什么会这样?
这与 systemd 的 Cgroup 嵌套方式有关。通常来说,子项以 -.slice
的方式声明。如果父项本身不存在,那么 systemd 会自动进行创建。如果刚刚我使用的是下划线 _
,而不是破折号 -
,那么结果就是您所想的那样了:
plaintext
Control group /:
├─my_beautiful_slice.slice
│ └─cat.service
│ └─4123 /usr/bin/cat /dev/urandom
使用 drop-in 文件
在 systemd 中设置 drop-in 文件非常简单。首先,在 /etc/systemd/system
目录下根据服务名称创建一个合适的目录。以 cat
为例,运行以下命令:
bash
# mkdir -p /etc/systemd/system/cat.service.d/
我们可以任意组织这些文件。鉴于它们是按照数字顺序依次执行的,可以将配置文件命名为类似 10-CPUSettings.conf
这样的形式。此目录中的所有文件都使用 .conf
文件扩展名。每次调整这些文件时,都需要运行 systemctl daemon-reload
命令。
我创建了两个 drop-in 文件来展示如何分离配置。第一个文件是 00-slice.conf
。如下所示,它为 cat
服务设置了单独切片的默认选项:
bash
[Service]
Slice=AWESOME.slice
MemoryAccounting=yes
CPUAccounting=yes
另一个文件设置了 CPUShares 的数量,我把它命名为 10-CPUSettings.conf
:
bash
[Service]
CPUShares=256
我在同一个切片中创建了第二个服务。为了更容易区分进程,第二个脚本会略有不同:
bash
#!/bin/bash
/usr/bin/sha256sum /dev/urandom > /dev/null &
然后我简单创建了 cat
文件的副本,替换了脚本,并更改了 CPUShares 的值:
bash
# sed 's/load\.sh/load2\.sh/g' cat.service > sha256sum.service
# cp -r cat.service.d sha256sum.service.d
# sed -i 's/256/2048/g' sha256sum.service.d/10-CPUSettings.conf
最后重新加载 daemon 并启动服务:
bash
# systemctl daemon-reload
# systemctl start cat.service
# systemctl start sha256sum.service
这里我先不展示 top
的输出,而是想介绍一下 systemd-cgtop
。它的工作方式与常规的 top
类似,但它会按切片和切片中的服务提供细分后的信息。这可以帮助我们了解是否在系统上充分利用了 Cgroup。
如下所示,systemd-cgtop
显示了特定切片中所有服务的聚合情况,以及切片中每个服务的资源利用情况:
使用 systemctl set-property
命令
最后一个方法是使用 systemctl set-property
命令配置 Cgroup。下面从一个基本的 service 文件 md5sum.service
开始:
bash
[Service]
Type=oneshot
ExecStart=/root/generate_load3.sh
TimeoutSec=0
StandardOutput=tty
RemainAfterExit=yes
Slice=AWESOME.slice
[Install]
WantedBy=multi-user.target
使用 systemctl set-property
命令,把文件放置在 /etc/systemd/system.control
目录中。这些文件不用手动编辑。因为 set-property
命令不能识别到所有属性,所以 Slice
定义被放在了 service 文件中。
设置好单元文件并重新加载 daemon 后,使用 systemctl
命令:
bash
# systemctl set-property md5sum.service CPUShares=1024
它创建了一个位于 /etc/systemd/system.control/md5sum.service.d/50-CPUShares.conf
的 drop-in 文件,可以随意查看。因为这些文件本不是用来手动编辑的,所以暂且不论。
运行命令,测试更改是否生效:
shell
systemctl start md5sum.service cat.service sha256sum.service
如图所示,更改应该成功了。sha256sum.service
的 CPUShares 为 2048,md5sum.service
为 1024,cat.service
为 256。
总结
到此,我们也只是涉及了 Cgroup 的一点皮毛,实际应用的过程会更加复杂。Cgroup 除了能够保持系统健康运行,还能帮助实施"深度防御"策略。此外,它们也是现代 Kubernetes 工作负载的关键组件之一,有助于正确运行容器化进程,主要负责:
- 限制进程的资源;
- 在存在争用时决定优先级;
- 控制对读/写和 mknod 设备的访问;
- 对系统上运行的进程进行高级别资源统计。
可以说,如果没有 Cgroup,容器化和 Kubernetes 等很多关键业务都不可能实现。
这个系列教程到这里就告一段落了,希望能对大家有所启发。
参考资料
- 0xax.gitbooks.io/linux-insid...
- sysadmincasts.com/episodes/14...
- itnext.io/chroot-cgro...
- www.certdepot.net/rhel7-get-s...
- access.redhat.com/documentati...
- oakbytes.wordpress.com/2012/09/02/...
- www.redhat.com/en/blog/wor...
- www.redhat.com/en/blog/wor...
- youtu.be/z7mgaWqiV90
- youtu.be/el7768BNUPw
- youtu.be/sK5i-N34im8
- youtu.be/_AODvcO5Q_8
- youtu.be/x1npPrzyKfs
- youtu.be/yZpNsDe4Qzg
- access.redhat.com/solutions/4...