1 个不稳定版本
0.1.0 | 2021年11月15日 |
---|
#517 在 Unix APIs
用于 runkins
57KB
1.5K SLoC
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并将其移动到那里。此设置还会将所需的控制器添加到$PARENT_CGROUP/cgroup.subtree_control .
使用systemd-run启动新用户slice
如果使用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
验证
待办事项:这应该在服务器启动时运行健康检查。
验证进程是否在自己的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
目前尚未实现。
依赖关系
~4–17MB
~165K SLoC