1个不稳定版本
0.1.0 | 2021年11月15日 |
---|
#16 in #cgroup
43KB
930 代码行,不包括注释
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)
测试系统按预期工作。日志子命令应该向stdout和stderr写入行。在程序写入10行后,客户端应该断开连接,状态应该是退出代码为0
。
要测试不同的退出代码,使用slow 1 3
,这将结束状态为退出代码为3
。
使用killall slow
或stop
RPC杀死slow
进程应结束状态为退出信号
。
自动化测试
运行
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启动新的用户切片
如果使用systemd-run
创建父cgroup,请确保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
目前尚未实现。
依赖关系
~10–23MB
~282K SLoC