1 个不稳定版本
0.1.0 | 2021年11月15日 |
---|
#447 in 构建工具
用于 runkins
2KB
Runkins
支持 cgroup 和 gRPC 接口的过程执行器。执行进程,将 stdout、stderr 存储在内存中,并通过流传输到 CLI。
可能的用例
- 在脚本中用于管理可能比脚本寿命长的长时间运行的进程
- 调试时,完整的容器运行时会妨碍调试,但需要比纯 Linux 更好的接口
- 轻量级 CI:工作流程中的步骤可以由退出代码、stdout 内容、超时等触发。
文件夹结构
- runkins - 包含
runkins
CLI 和runkins-server
gRPC 服务器的二进制包 - lib - 服务器使用的库,
examples/slow
二进制文件用于测试 - proto - 库和
*.proto
定义 - systemd - 示例 .service 文件
用法
要求
- Rust 2021 版本
对于 cgroup 功能(在设置限制时运行进程时需要)
- cgroup v2 已启用
systemd --version
>= 244 以将 cgroup v2 控制器委派给非 root 用户。可以通过以 root 身份运行等方法解决这个问题。
更多信息可以在 cgroup 部分。
安装
cargo install runkins
运行服务器
要在终端中查看错误日志,请使用
export RUST_LOG=runkins_server=debug,runkins_lib=debug,info
要运行服务器,执行
runkins-server
这将在(目前硬编码) localhost:50051
上启动 gRPC 服务器。CLI 使用相同的硬编码地址。
或者,使用 systemd 服务示例。
运行 CLI
要启动进程,运行
runkins start -- ls -la
start
子命令将 RUNKINS_EID 输出到 stdout。
所有其他子命令(status
、stop
、logs
、rm
)期望将其作为第一个参数或作为 RUNKINS_EID
环境变量接收。
示例工作流程
RUNKINS_EID=$(runkins start -- ls -la)
echo "RUNKINS_EID=$RUNKINS_EID" > .env
runkins status
runkins logs
runkins stop
runkins rm
rm .env
要获取命令的帮助,请使用 --help
标志。
构建
cargo build
要创建所有组件的调试构建,请运行
cargo build
或者使用 --release
运行以获取发布版本构建。
测试
手动测试
启动服务器,然后执行专为测试创建的二进制文件 slow
RUNKINS_EID=$(runkins start -- cargo run --example slow 10)
测试系统是否按预期工作。子命令 logs
应将行写入 stdout 和 stderr。程序写入 10 行后,客户端应断开连接,状态应为 Exited with code 0
。
要测试不同的退出代码,请使用 slow 1 3
,这将结束状态 Exited with code 3
。
使用 killall slow
或 stop
RPC 杀死 slow
进程应以状态 Exited with signal
结束。
自动测试
运行
cargo test
要执行依赖于 cgroup v2 和 systemd-run 的测试,请通过 RUST_FLAGS
或 .cargo/config
启用 test_systemd_run
配置。
cgroup 支持
以下环境变量需要设置,否则将不会启用 cgroup 支持。
- PARENT_CGROUP - 当前用户可以写入的 cgroup 目录的完整路径
- CGROUP_BLOCK_DEVICE_ID - 形式为 MAJOR:MINOR,请参阅
lsblk
- CGROUP_MOVE_CURRENT_PID_TO_SUBFOLDER_ENABLED - 为支持 systemd 服务所必需。如果设置(为任何值),在需要时创建 PARENT_CGROUP/service cgroup 并将当前 pid 移动到那里。此设置还将所需的控制器添加到 $PARENT_CGROUP/cgroup.subtree_control。
使用 systemd-run 启动新的用户切片
如果父 cgroup 是使用 systemd-run
创建的,请确保 shell 仍然打开。示例
$ systemd-run --user -p Delegate=yes --slice=my.slice --shell
# depending on the user, path might be:
# export PARENT_CGROUP=/sys/fs/cgroup/user.slice/user-1000.slice/[email protected]/my.slice
验证
TODO:这应该在服务器启动时运行的健康检查。
验证进程是否运行在自己的 cgroup 中
# note the --limits flag - if not set, cgroup will not be created
$ RUNKINS_EID=$(runkins start --limits -- cat /proc/self/cgroup)
$ runkins logs $RUNKINS_EID
0::/user.slice/user-1000.slice/[email protected]/my.slice/15395846019127741322
$ runkins rm $RUNKINS_EID
验证所有所需的控制器 cpu io memory
是否可用
$ RUNKINS_EID=$(runkins start --limits -- \
sh -c 'cat /sys/fs/cgroup/$(cat /proc/self/cgroup | cut -d ':' -f 3)/cgroup.controllers')
$ runkins logs $RUNKINS_EID
cpu io memory pids
$ runkins rm $RUNKINS_EID
通过 CLI 设置 cgroup 限制
可以使用帮助发现限制的开关。
$ runkins start --help
runkins-start 0.1.0
USAGE:
runkins start [FLAGS] [OPTIONS] <path> [args]...
FLAGS:
-h, --help Prints help information
-l, --limits Enable cgroup limits
-V, --version Prints version information
OPTIONS:
--cpu-max-period-micros <cpu-max-period-micros> Set cpu.max, period part, both parts must be set together
--cpu-max-quota-micros <cpu-max-quota-micros> Set cpu.max, quota part, both parts must be set together
--io-max-rbps <io-max-rbps> Set io.max, rbps value
--io-max-riops <io-max-riops> Set io.max, riops value
--io-max-wbps <io-max-wbps> Set io.max, wbps value
--io-max-wiops <io-max-wiops> Set io.max, wiops value
--memory-max <memory-max> Set memory.max in bytes
--memory-swap-max <memory-swap-max> Set memory.swap.max in bytes
ARGS:
<path>
<args>...
请注意,必须设置 --limits
标志,否则 CLI 将会报错。
示例
# this should succeed:
$ RUNKINS_EID=$(runkins start \
--limits --memory-max 1000000 --memory-swap-max 0 -- \
bash --help)
# this should exit with signal:
$ RUNKINS_EID=$(runkins start \
--limits --memory-max 100000 --memory-swap-max 0 -- \
bash --help)
mTLS
目前尚未实现。
依赖关系
~5.5–7.5MB
~130K SLoC