systemd-run 运行临时命令

发布时间: 更新时间: 总字数:1150 阅读时间:3m 作者: IP上海 分享 网址

systemd-run创建并启动一个临时的 .scope.service.path.socket.timer 单元,并在其中运行 COMMAND 命令,可以结合 cgroup 限制资源的使用,并支持使用 systemd 管理该进程

介绍

  • 帮助:man systemd-run
    • .service 是一个或一组进程,由 systemd 依据单位配置文件启动,并可以作为一个整体被启动或终止
    • .scope 一组外部创建的进程,前台进程。由强制进程通过 fork() 函数启动和终止、之后被 systemd 在运行时注册的进程,scope 会将其封装。例如:用户会话、容器和虚拟机被认为是 scope
    • slice 一组按层级排列的单位
      • slice 并不包含进程,但会组建一个层级,并将 scopeservice 都放置其中
      • 真正的进程包含在 scopeservice
      • 在这一被划分层级的树中,每一个 slice 单位的名字对应通向层级中一个位置的路径
      • 小横线(-)起分离路径组件的作用
  • 可以像普通的 unit 一样被 systemd 管理,也可被 systemctl list-units 显示出来
  • 本质上:启动一个以 systemd 进程为父进程的,干净的、独立的执行环境。默认在后台执行(也可通过 --no-block--wait 选项定制)
  • 默认情况下,systemd-run 创建 simple 类型的临时服务,可以通过参数 --property=Type=exec 配置
  • 若为 .path.socket.timer 单元,该单元会被立即启动
  • systemd-run --scope 用于创建一个新的 systemd 作用域(systemd scope)来隔离程序的运行环境
    • 在 systemd 中,systemd scope 是一种资源控制单元,用于跟踪进程组的活动,并允许对它们进行管理
NAME
       systemd-run - Run programs in transient scope units, service units, or path-, socket-, or timer-triggered
       service units

SYNOPSIS
       systemd-run [OPTIONS...] COMMAND [ARGS...]

       systemd-run [OPTIONS...] [PATH OPTIONS...] {COMMAND} [ARGS...]

       systemd-run [OPTIONS...] [SOCKET OPTIONS...] {COMMAND} [ARGS...]

       systemd-run [OPTIONS...] [TIMER OPTIONS...] {COMMAND} [ARGS...]

参数说明:

  • --slice=<slice-name> 生成 cgroup 层级的名字
  • --unit=<name> 生成 unit 单元的名字
  • -p 限制资源信息
    • -p MemoryLimit=5M

示例

记录 systemd 传递给服务单元的环境变量

$ systemd-run env
Running as unit: run-rfca9dba864cd40689ed91b8ae192a8c7.service
$ $ journalctl -u run-rfca9dba864cd40689ed91b8ae192a8c7.service
Apr 07 14:46:40 ip-172-31-38-208 systemd[1]: Started /usr/bin/env.
Apr 07 14:46:40 ip-172-31-38-208 env[438183]: LANG=C.UTF-8
Apr 07 14:46:40 ip-172-31-38-208 env[438183]: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/>
Apr 07 14:46:40 ip-172-31-38-208 env[438183]: INVOCATION_ID=e283c29bdf9845c496ace0bb351dff67
Apr 07 14:46:40 ip-172-31-38-208 env[438183]: JOURNAL_STREAM=8:10454352
Apr 07 14:46:40 ip-172-31-38-208 env[438183]: SYSTEMD_EXEC_PID=438183
Apr 07 14:46:40 ip-172-31-38-208 systemd[1]: run-rfca9dba864cd40689ed91b8ae192a8c7.service: Deactivated successfully.

限制一个命令可以使用的资源

运行 updatedb 工具,并将其块设备 I/O 权重限制到 10

systemd-run -p BlockIOWeight=10 updatedb

特定时间运行命令

$ date; systemd-run --on-active=30 --timer-property=AccuracySec=100ms /bin/touch /tmp/foo
Sun Apr  7 02:49:09 PM UTC 2024
Running timer as unit: run-r904f7dd2409c4226a3a4a7cd6d30b64e.timer
Will run service as unit: run-r904f7dd2409c4226a3a4a7cd6d30b64e.service
$ journalctl -b -u run-r904f7dd2409c4226a3a4a7cd6d30b64e.timer
Apr 07 14:49:09 ip-172-31-38-208 systemd[1]: Started /bin/touch /tmp/foo.
$ journalctl -b -u run-r904f7dd2409c4226a3a4a7cd6d30b64e.timer
Apr 07 14:49:09 ip-172-31-38-208 systemd[1]: Started /bin/touch /tmp/foo.
$ journalctl -b -u run-r904f7dd2409c4226a3a4a7cd6d30b64e.service
Apr 07 14:49:39 ip-172-31-38-208 systemd[1]: Started /bin/touch /tmp/foo.
Apr 07 14:49:39 ip-172-31-38-208 systemd[1]: run-r904f7dd2409c4226a3a4a7cd6d30b64e.service: Deactivated successfully.

允许被运行的命令访问终端

以临时服务的方式运行 /bin/bash 命令, 并将其标准输入标准输出标准错误连接到当前的 TTY 设备上

$ systemd-run -t --send-sighup /bin/bash
Running as unit: run-u166.service
Press ^] three times within 1s to disconnect TTY.
root@ip-172-31-38-208:/#

在一个临时的用户单元中运行 screen 工具

  • screen 作为 systemd --user 进程(由 user@.service 的某个实例启动)的子进程运行,并将其封装在一个临时 scope 单元中
    • 使用 systemd.scope 单元而不是 systemd.service 单元,是因为 screen 会在脱离终端后退出,进而导致 service 单元被终结。将 screen 放在用户单元中运行,可以避免它成为会话 scope 单元的一部分
ubuntu@ip-172-31-38-208:~$ systemd-run --scope --user screen
Running scope as unit: run-ra297f1dd124e4e30a8bb7edfb6172fe4.scope
[detached from 438261.pts-0.ip-172-31-38-208]
cmd + A, cmd + D
ubuntu@ip-172-31-38-208:~$ screen -ls
There is a screen on:
	438261.pts-0.ip-172-31-38-208	(04/07/2024 02:55:12 PM)	(Detached)
1 Socket in /run/screen/S-ubuntu.

限制资源

# 指定 scope 作为前台进程存在的
systemd-run -p MemoryLimit=5M --unit=name --scope --slice=slice_name command

# 指定 scope 作为 .service 存在
systemd-run -p MemoryLimit=5M --unit=name --slice=slice_name command

# 命令执行完成后,创建的临时单元文件会自动清理
systemd-run -p MemoryLimit=5M  -p CPUShares=100 --unit=sleep-10  --scope  --slice=test sleep 10

# 将 bash 放入 service,限制其资源使用
# 使用 systemctl cat bash-limit.service 查看详情
# 使用 systemctl disable bash-limit.service --now 停止
systemd-run -p MemoryLimit=5M -p CPUShares=100 --unit=bash-limit   --slice=bash-test -t /bin/bash

参考

  1. https://www.freedesktop.org/software/systemd/man/latest/systemd-run.html
Home Archives Categories Tags Statistics
本文总阅读量 次 本站总访问量 次 本站总访客数