#cgroup #process #manage #grpc #script #execution #runkins

构建 runkins_proto

Runkins 使管理命令执行变得容易

1 个不稳定版本

0.1.0 2021年11月15日

#447 in 构建工具


用于 runkins

MIT 许可证

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。

所有其他子命令(statusstoplogsrm)期望将其作为第一个参数或作为 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 slowstop 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