☰
rkt 性能基准测试与剖析指南:用 rkt-monitor 量化 v1.4.0 容器资源开销
2026/9/25 2:55:16 网站建设 项目流程
  • 容器运行时
  • 云原生
  • 网络

【免费下载链接】rkt

[Project ended] rkt is a pod-native container engine for Linux. It is composable, secure, and built on standards.

项目地址:https://gitcode.com/gh_mirrors/rk/rkt
点击查看免费下载

rkt 是一个面向 Linux 的 pod 原生容器引擎,其官方仓库在Documentation/performance/目录下提供了性能基准测试工具rkt-monitor的使用方法,以及 rkt v1.4.0 在四种典型负载下的实测数据。本文以 Documentation/performance/rkt-1-4-0-benchmarks.md 为核心,结合 Documentation/performance/README.md 与 tests/rkt-monitor 的源码实现,完整讲解如何构建负载、运行基准、读懂输出,并借助 rkt 内置的--cpuprofile/--memprofile隐藏全局参数对 rkt 自身进行 Go 性能剖析。读完本文,你将能够在自己的机器上复现 rkt 资源开销测量,并对 rkt 进程进行 pprof 级性能分析。

rkt-monitor:rkt 的资源监控基准工具

rkt-monitor 是 rkt 仓库自带的基准测试工具,作用是运行一个 rkt 容器负载,并跟踪 rkt 及其全部子进程的内存与 CPU 占用。其核心思路来自 tests/rkt-monitor/README.md:

  • 通过exec方式启动 rkt(附带一个 ACI 或 pod manifest 作为工作负载);
  • 每秒读取一次/proc,记录 rkt 及所有子孙进程的 CPU、RSS 等指标;
  • 到达指定时长后调用rkt stop终止容器、rkt gc回收资源,并把统计结果打印出来。

从 tests/rkt-monitor/main.go 的源码可以看出,rkt-monitor 对每次实验执行的操作序列为:构造rkt run --debug [--stage1-path=…] <workload> --insecure-options=image --net=default-restricted命令 → 启动后等待输出中的APP-STARTED!标记确认容器就绪 → 循环采样直到超时 →rkt stop <containerId>→rkt gc --grace-period=0→ 汇总并打印平均值与峰值。

运行基准测试的前置条件

依据 Documentation/performance/README.md,运行基准需要同时具备三样东西:

  1. 一个构建好的 rkt-monitor 可执行文件;
  2. 一个测试工作负载(单个 ACI,或由多个 ACI + pod manifest 组成的 pod);
  3. rkt 位于当前PATH中(rkt-monitor 会直接调用名为rkt的二进制,除非通过-p显式指定目录)。

另外还有两个隐含前提:

  • 需要 root 权限。tests/rkt-monitor/main.go 在启动时检查os.Getuid() != 0,非 root 会直接退出并提示need to be root to run rkt images;
  • 由于 rkt-monitor 通过--insecure-options=image运行 ACI(tests/rkt-monitor/main.go),请确保你了解该参数关闭了镜像签名校验的安全含义。

构建 rkt-monitor

按文档说明,进入tests/rkt-monitor目录执行其中的build脚本即可生成rkt-monitor二进制;该目录同时提供多个build-*脚本(例如 tests/rkt-monitor/README.md 中展示的./tests/rkt-monitor/build-stresser.sh all),用于把各类压力负载打包成 ACI。

构建负载 ACI 与 pod manifest

所有构建脚本都依赖acbuild工具(需位于当前PATH)。构建完成后会产生两种结果之一:

  • 单个 ACI:如log-stresser.aci、mem-stresser.aci、cpu-stresser.aci,可直接作为 rkt-monitor 的入参;
  • 一个目录 + pod manifest:目录内含多个 ACI 和一个 pod manifest(如文档中使用的too-many-apps.podmanifest)。这种场景必须先导入:把目录中的 ACI 逐一导入 rkt 的内容寻址存储(CAS),命令如下:
rkt fetch --insecure-options=image <newDirectory>/*

导入完成后,即可将 pod manifest 交给 rkt-monitor 使用。

启动一次基准

sudo ./rkt-monitor <workload>

<workload>可以是 ACI 文件路径,也可以是 pod manifest 文件路径。rkt-monitor 会通过 JSON 解码自动识别 pod manifest 并切换运行模式(tests/rkt-monitor/main.go)。

rkt-monitor 命令行选项详解

rkt-monitor 官方帮助 与 tests/rkt-monitor/main.go 中的 flags 定义完全对应,汇总如下:

选项简写默认值说明
--duration-d10s基准运行时长,使用 Go 的time.ParseDuration格式(如30s、1m);-d 30s即运行 30 秒
--repetitions-r1基准实验重复次数,每次独立执行一轮"启动→采样→停止→GC"
--verbose-vfalse每秒打印各进程当前的瞬时资源占用
--show-output-ofalse透传显示 rkt 的 stdout / stderr,便于观察容器内部输出
--to-file-ffalse把采样结果写入文件(默认落在/tmp),生成 CSV
--output-dir-w/tmp指定结果写入目录,配合-f使用
--rkt-dir-p""指定包含rkt二进制的目录;为空时使用PATH中的 rkt
--stage1-path-s""指定要使用的 stage1 镜像路径;为空时默认使用 coreos stage1(即stage1-coreos.aci)

注意 Documentation/performance/README.md 中提到的-f行为是"保存到带rkt_benchmark前缀的临时目录文件",而从 tests/rkt-monitor/main.go 的实现看,实际会生成两个 CSV:<日期>_<stage1类型>_<负载名>_rkt_benchmark_interval.csv(逐秒采样明细,表头Time, PID name, PID number, RSS, CPU)与<日期>_<stage1类型>_<负载名>_rkt_benchmark_summary.csv(汇总,表头Load1, Load5, Load15, StartTime, StopTime)。-p和-s两个选项对复现"同一台机器、不同 stage1"的对比实验尤其有用。

测量原理:源码级解读

理解 rkt-monitor 的输出之前,有必要弄清楚它的采样机制(来自 tests/rkt-monitor/main.go):

  • 进程树遍历:getUsage(pid)(tests/rkt-monitor/main.go)从 rkt 主进程 PID 出发,通过proc.Children()递归收集全部子孙进程,并利用pidMap缓存已创建的process.Process对象;
  • 指标采集:getProcStatus(tests/rkt-monitor/main.go)对每个进程调用p.Percent(0)(CPU 百分比)和p.MemoryInfo()(其中 RSS 作为内存指标);
  • 采样节奏:主循环每秒time.Sleep(time.Second)采样一次(tests/rkt-monitor/main.go);
  • 平均值与峰值:结束后对每个进程的采样历史求 CPU / RSS 平均,并取 RSS 最大值作为peak Mem(tests/rkt-monitor/main.go);
  • 单位格式化:formatSize(tests/rkt-monitor/main.go)按 1024 进制输出gB / mB / kB / B;
  • 启动/停止计时:以exec发出到 stdout 出现APP-STARTED!之间的时间作为container start time;以发出rkt stop到收到停止确认之间的时间作为container stop time。

因此每条名称(PID): seconds alive: N avg CPU: X% avg Mem: Y peak Mem: Z的含义是:该进程存活期间的平均 CPU 占用、平均 RSS 与峰值 RSS。seconds alive等于被采样到的秒数,略小于总时长(首秒用于确认容器启动)。

测试负载与它们的行为特征

仓库在 tests/rkt-monitor 下提供了四种压力负载的源码,分别模拟不同的资源消耗模式:

  • log-stresser:无限循环打印时间戳字符串,持续制造日志输出,主要考验日志链路(rkt 日志转发与 stage1 中 systemd-journald)的吞吐与 CPU 开销;
  • mem-stresser:无限循环向一个[]uint64切片追加数据,持续增长内存占用,考验内存分配与内核回收压力;
  • cpu-stresser:无限循环累加10 亿次整数求和,制造接近满核的纯 CPU 计算压力;
  • sleeper:空转/休眠,用于测量"几乎无事可做"时 rkt 与 stage1 的基线开销;
  • too-many-apps.podmanifest:包含大量 worker 应用的 pod manifest,用于考察多应用 pod场景下 rkt 与 systemd 的管理开销(worker-binary进程两两重复,仅 PID 不同)。

v1.4.0 基准测试结果

以下数据来自 Documentation/performance/rkt-1-4-0-benchmarks.md,是在一台运行 NixOS 的个人笔记本上测得。

测试环境

derek@proton ~> cat /proc/cpuinfo | grep "model name" model name : Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz model name : Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz model name : Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz model name : Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz derek@proton ~> uname -a Linux proton 4.4.6 #1-NixOS SMP Wed Mar 16 15:43:17 UTC 2016 x86_64 GNU/Linux

即双核四线程的 Intel i7-6500U、内核 4.4.6、x86_64。这些数字与硬件、内核版本、stage1 实现强相关,只能作为量级参考,必须在自己的环境中复测。

log-stresser.aci(日志压力)

derek@proton ~/go/src/github.com/rkt/rkt/tests/rkt-monitor> sudo ./rkt-monitor log-stresser.aci rkt(18493): seconds alive: 10 avg CPU: 28.314541% avg Mem: 2 mB peak Mem: 2 mB systemd(18515): seconds alive: 9 avg CPU: 0.000000% avg Mem: 4 mB peak Mem: 4 mB systemd-journal(18517): seconds alive: 9 avg CPU: 88.397098% avg Mem: 7 mB peak Mem: 7 mB worker(18521): seconds alive: 9 avg CPU: 7.330367% avg Mem: 5 mB peak Mem: 6 mB load average: Load1: 0.390000 Load5: 0.120000 Load15: 0.080000 container start time: 250721ns container stop time: 17332926ns

mem-stresser.aci(内存压力)

derek@proton ~/go/src/github.com/rkt/rkt/tests/rkt-monitor> sudo ./rkt-monitor mem-stresser.aci worker(18634): seconds alive: 9 avg CPU: 98.550401% avg Mem: 318 mB peak Mem: 555 mB rkt(18599): seconds alive: 10 avg CPU: 3.583814% avg Mem: 2 mB peak Mem: 2 mB systemd(18628): seconds alive: 9 avg CPU: 0.000000% avg Mem: 4 mB peak Mem: 4 mB systemd-journal(18630): seconds alive: 9 avg CPU: 0.000000% avg Mem: 6 mB peak Mem: 6 mB load average: Load1: 0.310000 Load5: 0.150000 Load15: 0.090000 container start time: 259746ns container stop time: 17593446ns

cpu-stresser.aci(CPU 压力)

derek@proton ~/go/src/github.com/rkt/rkt/tests/rkt-monitor> sudo ./rkt-monitor cpu-stresser.aci rkt(18706): seconds alive: 10 avg CPU: 3.587050% avg Mem: 2 mB peak Mem: 2 mB systemd(18736): seconds alive: 9 avg CPU: 0.000000% avg Mem: 4 mB peak Mem: 4 mB systemd-journal(18740): seconds alive: 9 avg CPU: 0.000000% avg Mem: 6 mB peak Mem: 6 mB worker(18744): seconds alive: 9 avg CPU: 88.937493% avg Mem: 808 kB peak Mem: 808 kB load average: Load1: 0.310000 Load5: 0.130000 Load15: 0.080000 container start time: 296570ns container stop time: 16124700ns

too-many-apps.podmanifest(多应用 pod,-d 30s)

derek@proton ~/go/src/github.com/rkt/rkt/tests/rkt-monitor> sudo ./rkt-monitor too-many-apps.podmanifest -d 30s # Identical (aside from PID) worker-binary lines removed rkt(17227): seconds alive: 20 avg CPU: 9.595387% avg Mem: 3 mB peak Mem: 20 mB systemd(17253): seconds alive: 17 avg CPU: 0.329028% avg Mem: 16 mB peak Mem: 16 mB systemd-journal(17255): seconds alive: 17 avg CPU: 0.000000% avg Mem: 6 mB peak Mem: 6 mB worker-binary(17883): seconds alive: 17 avg CPU: 0.000000% avg Mem: 840 kB peak Mem: 840 kB load average: Load1: 0.480000 Load5: 0.350000 Load15: 0.300000 container start time: 528476ns container stop time: 4522346ns

结果解读

结合源码与各场景特征,可以从这些数据中提炼出几条可验证的结论:

  • rkt 宿主进程自身开销极低:在 mem / cpu 压力下,rkt 进程平均 CPU 仅约3.5%、平均内存2 mB、峰值2 mB;日志场景 rkt 平均 CPU 升至28%,可以推断这是 rkt 作为日志转发/管道环节承担高频日志 I/O 所致;
  • 日志链路的主要开销在 systemd-journald:log-stresser 场景下systemd-journal平均 CPU 高达88.4%,而 mem / cpu 场景下其 CPU 为0%,说明 journald 是日志热路径的瓶颈所在;
  • worker 进程按预期吃满资源:mem-stresser 的 worker 平均 CPU98.5%、平均内存318 mB、峰值555 mB;cpu-stresser 的 worker 平均 CPU88.9%、内存仅808 kB——符合"累加整数"程序内存占用极小的特征;
  • 多应用 pod 会放大 stage1 管理开销:too-many-apps 场景中 rkt 平均 CPU9.6%、峰值内存20 mB(远超单应用场景的2 mB),systemd 平均内存也升至16 mB,可见应用数量直接影响 rkt 与 stage1 systemd 的资源占用;
  • 容器生命周期耗时量级:三个单应用场景的container start time均在250–300 µs级别(rkt run到应用确认启动),container stop time在16–18 ms级别;多应用 pod 的启动时间约为528 µs,停止时间反而更短(约4.5 ms),体现了批量化进程管理的差异。

需要再次强调:以上数值是特定硬件、特定内核(4.4.6)、特定 stage1(coreos)下的快照,不能泛化为 rkt 的普适性能指标;复现时请使用-r做多次重复、-v观察瞬时波动,并用-f落盘 CSV 便于进一步分析。

性能剖析:rkt 内置的 --cpuprofile 与 --memprofile

除了宏观的资源基准,rkt 还内置了两个隐藏的全局参数用于对 rkt 进程本身做 Go 性能剖析:

  • --cpuprofile=$FILE:把 CPU profile 写入指定文件;
  • --memprofile=$FILE:把内存(堆)profile 写入指定文件。

这两个参数在 rkt/rkt.go 中注册为cmdRkt.PersistentFlags(),并通过MarkHidden隐藏,因此不会出现在rkt help的常规输出中,但功能完整可用。其底层实现位于 rkt/rkt.go:

  • startProfile()在命令执行前被调用:若指定了 CPU profile,则创建文件并调用pprof.StartCPUProfile(cpufile);若指定了内存 profile,仅创建文件、暂不写入;
  • stopProfile()在命令结束时被调用:调用pprof.StopCPUProfile()结束 CPU 采样,并通过pprof.WriteHeapProfile(memfile)把堆 profile 写入内存文件。

需要特别留意的是:内存 profile 只在 rkt 退出前才会被写入,因此在 rkt 运行期间查看该文件会是空的——这是 Documentation/performance/README.md 明确指出的限制。

剖析示例:对 gc 命令做性能剖析

Documentation/performance/README.md 给出的完整示例(使用一个快速结束的子命令gc):

$ sudo /usr/bin/rkt --cpuprofile=/tmp/cpu.profile --memprofile=/tmp/mem.profile gc --grace-period=0 $ go tool pprof /usr/bin/rkt /tmp/cpu.profile $ go tool pprof /usr/bin/rkt /tmp/mem.profile

go tool pprof会进入交互式界面,可用top、web、list <函数名>等指令查看热点函数与调用栈。对于 CPU profile,pprof.StartCPUProfile自命令启动即开始采样,能覆盖整个命令生命周期内的 CPU 热点;对于内存 profile,由于 heap profile 在退出前才落盘,得到的是命令结束时堆的分配快照,适合分析峰值内存分配路径。

由于 rkt 的每个子命令(run、gc、stop、fetch等)都会经过 rkt/rkt.go 的runWrapper,其中统一调用startProfile()与stopProfile(),因此任意子命令都可以带上这两个 flag 进行剖析——例如用rkt --cpuprofile=/tmp/run.profile run <image>剖析一次完整容器启动的 CPU 热点。更系统的 Go 程序性能剖析方法(采样原理、pprof 交互命令、火焰图生成等)可参考 Go 官方博客的《Profiling Go Programs》一文。

总结

  • rkt-monitor是 rkt 官方的资源基准工具,通过逐秒采样 rkt 及其子孙进程的 CPU / RSS,量化容器运行时与 stage1 的实际开销,支持-d、-r、-v、-f、-p、-s、-o等参数,入口源码在 tests/rkt-monitor/main.go;
  • v1.4.0 实测数据显示:单应用场景下 rkt 宿主进程开销极小(内存约 2 mB),日志场景瓶颈集中在 systemd-journald,多应用 pod 会显著抬高 rkt 与 systemd 的管理开销;启动耗时约数百微秒、停止约十几毫秒,但均受硬件与 stage1 影响,需自行复测;
  • 性能剖析:rkt 内置隐藏全局参数--cpuprofile/--memprofile(rkt/rkt.go),配合go tool pprof即可定位 rkt 自身各子命令的热点函数,注意内存 profile 仅在退出前落盘。

如果希望在自己的机器上复现本文数据,建议按顺序:构建 rkt 与 rkt-monitor → 用 acbuild 生成负载 ACI(pod 场景先rkt fetch导入)→sudo ./rkt-monitor <workload> -r 3 -d 30s -v→ 对感兴趣的阶段追加--cpuprofile/--memprofile深入剖析。

  • 容器运行时
  • 云原生
  • 网络

【免费下载链接】rkt

[Project ended] rkt is a pod-native container engine for Linux. It is composable, secure, and built on standards.

项目地址:https://gitcode.com/gh_mirrors/rk/rkt
点击查看免费下载

相关推荐

上一篇:Burn:用 Rust 统一训练与推理的下一代张量库与深度学习框架
下一篇:终极tmux配置指南:Urlscan和PathPicker高效集成应用

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询