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
格式与我们之前创建配置一致,所以可以认为 systemd-run 创建了一次性的 unit 运行。
如果在该任务运行完毕后,再次使用 systemctl 去查看:
systemctl status mysleep
systemctl cat mysleep
会发现该任务已经运行完毕,查看不到了。
描述
systemd-run 可以创建一个临时的 service 或者 scope 的 unit ,然后在里面运行简单的 COMMAND 命令。会创建对应的 service 文件,关联 path 、socket 、timer 等等,帮助在特定条件下启动临时的 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
或者参考该链接
选项 | 取值 | 含义 |
---|
CPUAccounting | yes/no | 如果为 yes,会开启CPU占用统计。 | CPUWeight | 1-10000 | 默认100;CPU分配权重,控制Cgroup的 cpu.weight 属性,是系统正常运行时占比 | StartupCPUWeight | 1-10000 | 默认100;CPU分配权重,控制Cgroup的 cpu.weight 属性,是系统启动过程时占比 | CPUQuota | N% | 设置CPU时间上限,是一个百分数,占用单颗CPU的总时间多少 | MemoryAccounting | yes/no | 如果为 yes,会开启MEM占用统计。 | MemoryMin | N[KMGT] or N% | 进程保留的最低内存用量,可以使用512K进行表示,或者 10%相对系统的总物理内存;对应CGroup的memory.min | MemoryLow | N[KMGT] or N% | 进程保障内存用量(除非其他的最低用量不够,才会少于这部分用量),可以使用512K进行表示,或者 10%相对系统的总物理内存;对应CGroup的memory.low | MemoryHigh | N[KMGT] or N% | 进程柔性内存用量限制(如果超过会降低权重,并且尽量回收内存),可以使用512K进行表示,或者 10%相对系统的总物理内存;对应CGroup的memory.high | MemoryMax | N[KMGT] or N% | 进程刚性内存用量限制(如果超过会被强制杀死),可以使用512K进行表示,或者 10%相对系统的总物理内存;对应CGroup的memory.max | MemorySwapMax | N[KMGT] or N% | 进程刚性交换空间用量限制(如果超过会被强制杀死),可以使用512K进行表示,或者 infinity 不做限制;对应CGroup的memory.swap.max | TasksAccounting | yes/no | 如果为yes,会进行任务数量统计 | TasksMax | N or N% | 总任务数量的限制配置,可以为整数或者最大任务数量的百分比,或者 infinity 不做限制;对应CGroup的pids.max | IOAccounting | yes/no | 如果为yes,会进行块设备IO统计 | IOWeight | 1-10000 | 默认100;IO分配权重,控制Cgroup的 cpu.weight 属性,是系统正常运行时占比 | StartupIOWeight | 1-10000 | 默认100;IO分配权重,控制Cgroup的 cpu.weight 属性,是系统启动过程时占比 | Slice | string | 将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
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 来实现。
|