Linux systemd-run unit封装CGroup资源进行任务运行

Posted 青冬

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux systemd-run unit封装CGroup资源进行任务运行相关的知识,希望对你有一定的参考价值。

Linux systemd-run 封装资源使用

之前我们讲了关于 systemctl 对各种服务或者说是 unit 进行了讲解,也讲了怎么创建一个 unit,进行相关配置或者依赖设置等等。在使用 systemctl status xxx 时,我们可以发现对应的资源使用情况,如:

systemctl status chronyd

但如果创建一个 unit 每次都要通过配置文件,然后巴拉巴拉,其实还是很麻烦的,我们只需要使用 systemd-run 就可以轻而易举的创建一个 CGroup,封装资源,运行命令,包装成一个 unit

systemd-run

快速认识

systemd-run 可以创建临时命令封装到 CGroup 中。CGroup 可以封装资源,运行任务。这样一个任务会变成我们熟悉的 unit 进行运行,然后可以通过 systemctl 进行管理。如:

# 后面会有完整实例
systemd-run -p  MemoryLimit=5M  -p CPUShares=100 --unit=mysleep --slice=test sleep 60
systemctl status mysleep

可以看到,我们直接创建了一个 service,运行在 CGroup 中,并设置了一些资源限制。甚至我们可以查看下她的 service 配置文件:

systemctl cat mysleep
# 自动构建在了 /run/systemd/system/mysleep.service 中

格式与我们之前创建配置一致,所以可以认为 systemd-run 创建了一次性的 unit 运行。

如果在该任务运行完毕后,再次使用 systemctl 去查看:

systemctl status mysleep
systemctl cat mysleep

会发现该任务已经运行完毕,查看不到了。

描述

systemd-run 可以创建一个临时的 service 或者 scopeunit,然后在里面运行简单的 COMMAND 命令。会创建对应的 service 文件,关联 pathsockettimer 等等,帮助在特定条件下启动临时的 service

通过 systemd-run 运行的命令,会在干净、独立的 CGroup 中;和其他的 unit 一样,可以使用 systemctl list-units 进行筛选查看;运行时,会使用 systemd 进程为父进程,以异步的方式在后台创建临时 service 运行,并且在命令执行之后返回结果(除明确 前台 执行外)。

使用

systemd-run 可以直接跟 bash 命令,全局默认运行程序:

systemd-run sleep 100
systemctl status run-5561

当然可以选择部分参数设置:

全量请参考,这里仅仅举例重要部分 https://www.linux.org/docs/man1/systemd-run.html

man systemd-run

–no-ask-password

需要切换用户执行时,不要进行密码验证

–scope

指定一个 unit 类型来创建任务,默认是 service

–unit=[name]

unit 指定名字,如果不指定,默认为 run-ID.service 格式。

–property / -p

unit 设置一个属性,这个属性列表是用空格分割的属性与值的键值对,比如:

systemd-run -p MemoryLimit=5M -p CPUShares=100 sleep 100

这里面大多数都是属性控制,需要参照的是 systemd.resource-control,主要包含 CPU、Memory、IO 相关属性配置。

以下列举了常用的配置,大全请读者自行百度:https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html

或者参考该链接

选项取值含义
CPUAccountingyes/no如果为 yes,会开启CPU占用统计。
CPUWeight1-10000默认100;CPU分配权重,控制Cgroup的 cpu.weight 属性,是系统正常运行时占比
StartupCPUWeight1-10000默认100;CPU分配权重,控制Cgroup的 cpu.weight 属性,是系统启动过程时占比
CPUQuotaN%设置CPU时间上限,是一个百分数,占用单颗CPU的总时间多少
MemoryAccountingyes/no如果为 yes,会开启MEM占用统计。
MemoryMinN[KMGT] or N%进程保留的最低内存用量,可以使用512K进行表示,或者 10%相对系统的总物理内存;对应CGroup的memory.min
MemoryLowN[KMGT] or N%进程保障内存用量(除非其他的最低用量不够,才会少于这部分用量),可以使用512K进行表示,或者 10%相对系统的总物理内存;对应CGroup的memory.low
MemoryHighN[KMGT] or N%进程柔性内存用量限制(如果超过会降低权重,并且尽量回收内存),可以使用512K进行表示,或者 10%相对系统的总物理内存;对应CGroup的memory.high
MemoryMaxN[KMGT] or N%进程刚性内存用量限制(如果超过会被强制杀死),可以使用512K进行表示,或者 10%相对系统的总物理内存;对应CGroup的memory.max
MemorySwapMaxN[KMGT] or N%进程刚性交换空间用量限制(如果超过会被强制杀死),可以使用512K进行表示,或者 infinity 不做限制;对应CGroup的memory.swap.max
TasksAccountingyes/no如果为yes,会进行任务数量统计
TasksMaxN or N%总任务数量的限制配置,可以为整数或者最大任务数量的百分比,或者 infinity 不做限制;对应CGroup的pids.max
IOAccountingyes/no如果为yes,会进行块设备IO统计
IOWeight1-10000默认100;IO分配权重,控制Cgroup的 cpu.weight 属性,是系统正常运行时占比
StartupIOWeight1-10000默认100;IO分配权重,控制Cgroup的 cpu.weight 属性,是系统启动过程时占比
Slicestring将unit放入那个slice中,主要是可以做层次、分组的资源分配或者依赖管理等。

–description=[string]

可以直接给 unit 添加一个描述性的字符串,如果不存在则是 COMMAND 本身。

–slice=[sliceName]

将该 unit 放入对应的 slice 中,默认为 system.slice。与上面表格的 Slice 相同。

–remain-after-exit / -r

unit 执行完毕后,是否继续保持服务的存在,直到 stop 为止。如果不设置,在执行完 unit 后,该 unit 的信息会被全部删除。

–uid=[N]

以指定的 UID 身份进行 unit 的执行。

–gid=[N]

以指定的 GID 身份进行 unit 的执行。

–nice=[N]

执行 nice 谦让优先级。

–working-directory=[path]

指定工作目录进行 unit 运行。

–setenv=“[K=V]”

unit 传递一个环境变量,是一个列表使用空格隔开,内容为 KV 键值对,如:

systemd-run -r --setenv="name=huangyichun age=26" env

–cocllect / -G

unit 执行失败的时候,不会从内存中卸载,会一直保留在内存中,直到用户明确使用其他命令重启、或关闭。如果开启,资源回收会更加激进,在任务执行后被卸载,无论成功与否。

–on-active=[time]

在特定时间进行 unit 的运行,如:

systemd-run -r --on-active=60 env  # 60秒后运行
systemctl status run-11249.service
systemctl status run-11249.service
systemctl status run-11249.service

返回值

0 为提交成功,1 为提交失败。

哪些地方可以使用

可以看到 systemd-run 可以封装一个小型的 shell 资源,并且可以指定到不同的用户运行,所以一般可以作为调度平台的使用。

shell

在调度中,会涉及大量 shell 脚本的使用,但是 shell 脚本的返回结果,资源封装等等做的并不够好,此时我们完全可以通过 unit 进行 shell 任务的调度。

spark-sql

举例一个大数据环境中,需要提交一个 spark-sql 任务,其实用 shell 也可以,但是如果我们还想保留完整的提交日志,尽量少的资源占用等等,都可以使用 systemd-run 来实现。

以上是关于Linux systemd-run unit封装CGroup资源进行任务运行的主要内容,如果未能解决你的问题,请参考以下文章

systemd-run 中文手册

如何通过 python 和 dbus (systemd-run like) 创建 systemd 瞬态计时器和服务?

关于Linux下通过ping/mtr 长期监控网络输出日志报告的一些笔记

关于Linux下通过ping/mtr 长期监控网络输出日志报告的一些笔记

Linux-unit12

Linux unit 12