- 容器运行时
- 云原生
- 网络
【免费下载链接】rkt
[Project ended] rkt is a pod-native container engine for Linux. It is composable, secure, and built on standards.
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,运行基准需要同时具备三样东西:
- 一个构建好的 rkt-monitor 可执行文件;
- 一个测试工作负载(单个 ACI,或由多个 ACI + pod manifest 组成的 pod);
- 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 | -d | 10s | 基准运行时长,使用 Go 的time.ParseDuration格式(如30s、1m);-d 30s即运行 30 秒 |
--repetitions | -r | 1 | 基准实验重复次数,每次独立执行一轮"启动→采样→停止→GC" |
--verbose | -v | false | 每秒打印各进程当前的瞬时资源占用 |
--show-output | -o | false | 透传显示 rkt 的 stdout / stderr,便于观察容器内部输出 |
--to-file | -f | false | 把采样结果写入文件(默认落在/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: 17332926nsmem-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: 17593446nscpu-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: 16124700nstoo-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 平均 CPU
98.5%、平均内存318 mB、峰值555 mB;cpu-stresser 的 worker 平均 CPU88.9%、内存仅808 kB——符合"累加整数"程序内存占用极小的特征; - 多应用 pod 会放大 stage1 管理开销:too-many-apps 场景中 rkt 平均 CPU
9.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.profilego 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.
相关推荐
用 rkt-monitor 实测 Pod 级资源开销:rkt 性能基准工具的原理与实操
用 rkt monitor 实测 Pod 级资源开销:rkt 性能基准工具的原理与实操 rkt monitor 是 rkt 仓库内置的一个小型 Go 基准测试工
容器运行时云原生网络如何精准掌握招聘发布时间:Boss Show Time插件的7个实用技巧
如何精准掌握招聘发布时间:Boss Show Time插件的7个实用技巧 还在为错过最佳投递时机而烦恼吗?Boss Show Time是一款专为求职者设计的智能
前端服务器安全审计:如何用searchall快速发现隐藏的敏感信息?
服务器安全审计:如何用searchall快速发现隐藏的敏感信息? 在数字安全日益重要的今天,每个服务器管理员都面临着一个共同的挑战:如何确保系统中没有泄露的敏感
网络安全应用安全渗透测试
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考