☰
rkt status 命令详解:查询 Pod 状态、应用退出码与等待时机控制
2026/9/25 5:08:02 网站建设 项目流程
  • 容器运行时
  • 云原生
  • 网络

【免费下载链接】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 status是 rkt(pod-native 容器引擎)中用于查询单个 Pod 运行时状态的核心命令。给定一个 Pod UUID,它可以一次返回该 Pod 的当前生命周期状态(state)、创建与启动时间、stage1 主进程 PID 以及 Pod 内每个应用(app)的退出码;它还提供--wait与--wait-ready两种等待模式,可让命令阻塞直至 Pod 结束或就绪,非常适合在自动化脚本中精确捕获终态。读完本文,你将掌握rkt status的完整用法、每条输出字段的含义、底层状态文件与锁机制,以及如何在脚本里安全地等待 Pod 并读取退出结果。

本文内容以仓库文档 Documentation/subcommands/status.md 为骨架,并辅以 rkt/status.go、pkg/pod/pods.go、pkg/pod/wait.go 等源码实现展开说明。

基本用法:按 UUID 查询 Pod 状态

rkt status需要一个 Pod UUID 作为参数。UUID 支持前缀匹配,也就是说你只需要提供足以唯一区分该 Pod 的前缀即可,例如完整的 32 位十六进制 UUID 可以只写前几位。下面这条命令会返回一个已退出 Pod 的完整状态信息:

$ rkt status 66ceb509 state=exited created=2016-01-26 14:23:34.631 +0100 CET started=2016-01-26 14:23:34.744 +0100 CET pid=16964 exited=true app-redis=0 app-etcd=0

注意应用退出码在输出中会以app-前缀标识:app-redis=0表示名为redis的应用以退出码 0 结束,app-etcd=0同理。

输出字段逐个解读

结合 rkt/status.go 中printStatus的实现,各字段含义如下:

字段含义说明
statePod 当前生命周期状态可取embryo、preparing、aborted prepare、prepared、running、deleting、exited deleting、exited、exited garbage、garbage等,详见 pkg/pod/pods.go 的状态常量定义
createdPod 创建时间对应 Pod 进入 prepare 阶段的时间,读取自pod-created文件;为了兼容 rkt v1.20 之前的版本,该文件缺失时会回退到读取pod文件的修改时间,见 pkg/pod/pods.go
startedPod 启动时间读取自pid或ppid文件的修改时间;若该 Pod 尚未启动(如仍处于prepared),则此字段不会输出,见 pkg/pod/pods.go
pidstage1 主进程 PID即启动该 Pod 的 stage1 进程 PID,读取自pid文件,缺失时回退到ppid文件,见 pkg/pod/pods.go
exited是否处于退出态为true时表示 Pod 已退出(包括exited与exited garbage两种状态)
app-<name>各应用的退出码只有 Pod 不在running状态时才会输出,按 Pod manifest 中声明的每个 app 逐个读取退出码文件

时间戳的默认输出格式由常量defaultTimeLayout = "2006-01-02 15:04:05.999 -0700 MST"定义(见 rkt/image_list.go,同样被 rkt/status.go 使用),因此输出中会同时携带时区信息(如+0100 CET)。

输出的三类字段与状态的关系

从源码可以看到,输出字段并非在所有状态下都齐全,而是分层输出的:

  1. state、created、started是基础字段;
  2. 当状态为running或exited时,额外输出networks=(Pod 使用的网络列表,来自netinfo);
  3. 当状态处于running/deleting/exited deleting/exited/exited garbage时,尝试输出pid=;
  4. 只有当状态不是running时,才逐个输出app-<name>=<exitcode>。

也就是说,对还在运行的 Pod,rkt status只会给出state/created/started/networks/pid/exited=false,并不会给出各应用的退出码;应用退出码只有在 Pod 进入终态之后才能查到。

pid 字段的可用性窗口

文档特别强调:即使state=running,在rkt run或rkt run-prepared之后不久,pid字段也可能暂时不可用。其根源在 pkg/pod/pods.go 的注释中讲得很清楚:

the pid file might not be written yet when the state changes to 'Running'; it may also never be written if systemd never executes (e.g.: a bad command).

也就是说,Pod 目录被重命名为run/(状态变为running)与 stage1 内 systemd 真正写出pid文件之间存在一个时间窗口;如果 stage1 启动失败,pid文件甚至永远不会出现。因此脚本在running状态下依赖pid字段时应当做好重试或等待。源码中还提供了ContainerPid1()(pkg/pod/pods.go)来循环重试获取容器内 PID 1,供内部使用。

等待 Pod 结束:--wait 参数

如果 Pod 仍在运行,你可以直接执行rkt status --wait UUID,命令会阻塞等待 Pod 结束后再输出其最终状态。典型场景是:启动一个 Pod,然后脚本等待它自然退出,从而拿到所有应用的退出码。

$ rkt status --wait 66ceb509

如果要限定等待时长,可以传入一个 Go duration 字符串。例如下面这条命令最多等待 10 秒,若 Pod 在 10 秒内结束,则立即输出终态;若超时仍未结束,命令报错退出:

$ rkt status --wait=10s UUID

--wait的实际语义通过parseDuration函数(rkt/status.go)解析,规则如下:

传入值解析结果行为
--wait(无值)或--wait=true负时长无限期等待
--wait=false零时长不等待,立即查询
--wait=10s、--wait=5m等合法 duration对应时长等待到超时为止

源码中的NoOptDefVal = "true"(rkt/status.go)保证了裸写--wait时等价于--wait=true。等待超时通过newContext(rkt/status.go)构造带超时的context,超时后WaitFinished返回context deadline exceeded,命令随即以状态码 254 退出并打印error waiting for pod to finish。

WaitFinished 的底层机制

真正执行等待的是Pod.WaitFinished(pkg/pod/wait.go),它通过每 100 毫秒轮询加锁来判定 Pod 是否结束:

  • 尝试获取 Pod 目录的共享锁;若TrySharedLock返回lock.ErrLocked,说明该 Pod 的独占锁仍被持有,即仍处于运行阶段(prepare、run、exitedGarbage、garbage 等),继续轮询;
  • 若成功加锁,说明 Pod 已经越过运行阶段,立即解锁并调用refreshState()刷新状态;
  • 若刷新后发现 Pod 处于prepared(对应 split 场景下 prepare 与 run-prepared 分开使用的间隙),则额外睡 1 秒后继续轮询;
  • 最终IsFinished()判定 Pod 是否进入终态(exited、aborted prepare、garbage或已消失)。

命令文档也提醒:--wait返回后,应以输出内容本身为准来确定 Pod 的实际终态,而不是假定"等待成功=运行成功",因为等待成功只代表 Pod 进入某个终态,最终是成功退出还是异常中止要读exited与各app-*退出码来判断。

等待 Pod 就绪:--wait-ready 参数

另一类场景是等待 Pod 真正"就绪":执行rkt status --wait-ready UUID,命令会阻塞直到 Pod 的 supervisor(典型为 systemd pid1)进入 ready 状态。

与--wait一样,--wait-ready也支持裸开关、布尔值与 duration 三种写法,解析规则完全相同。例如等待最多 10 秒:

$ rkt status --wait-ready=10s UUID

从 rkt/status.go 可以看出,--wait-ready的等待发生在--wait之前:若dReady != 0先执行WaitReady,随后再判断是否执行WaitFinished。

WaitReady 的判定依据

Pod.WaitReady(pkg/pod/wait.go)同样以 100 毫秒为间隔轮询,核心判定委托给IsSupervisorReady(pkg/pod/pods.go):它读取 stage1 rootfs 下的rkt/supervisor-status符号链接,若链接目标为ready字符串则视为就绪;任何读取错误都按"未就绪"处理。supervisor-status由 stage1 中的 systemd 服务在就绪时写入,因此该机制与 stage1 实现(kvm、fly、nspawn 等)紧密相关,具体约定可参见 Documentation/devel/stage1-implementors-guide.md。

从文件读取 UUID:--uuid-file 参数

当 Pod UUID 由其他命令或工具写入到某个文件时,可以使用--uuid-file让rkt status从文件中读取,从而避免手动传参。命令格式为:

$ rkt status --uuid-file=FILE

注意--uuid-file与位置参数是互斥的:runStatus中的 switch(rkt/status.go)规定,要么不传位置参数而用--uuid-file,要么传一个位置参数而不带--uuid-file,否则打印 usage 并以状态码 254 退出。文件读取与校验由pkgPod.ReadUUIDFromFile(pkg/pod/uuid.go)完成。

这一参数特别适合由rkt run --uuid-file-save=FILE之类的命令先落盘 UUID、再由状态查询脚本接力读取的编排方式。仓库的功能测试 tests/rkt_status_test.go 正是这样验证的:先用rkt prepare拿到 Pod UUID 写入临时文件,再执行rkt status --uuid-file=<file>,并断言输出中包含state=prepared。

输出格式:--format 参数

除默认的key=value键值对输出外,rkt status还支持 JSON 输出,便于被程序化消费(如接入监控系统或 CI 脚本):

$ rkt status --format=json UUID $ rkt status --format=json-pretty UUID

--format的可选值在 rkt/image_list.go 中定义,包括json(紧凑 JSON)与json-pretty(带缩进的 JSON)。当指定了 JSON 格式时,printStatus会调用lib.NewPodFromInternalPod(lib/pod.go)将内部 Pod 结构转换为 api/v1 的Pod模型,再序列化输出;该模型包含 UUID、State、Networks、CreatedAt、StartedAt、AppNames、每个 app 的详细状态、UserAnnotations 与 UserLabels 等字段。默认(--format为空)则输出本文开头展示的键值对格式。

全局选项

rkt status还接受 rkt 的全部全局选项,例如--dir(rkt 数据目录,默认/var/lib/rkt)、--insecure-options(禁用部分安全特性)、--local-config(本地配置目录,默认/etc/rkt)、--system-config(系统配置目录,默认/usr/lib/rkt)等,完整表格见 Documentation/commands.md 的 global options 一节。当 Pod 数据目录被移动到非默认位置时,务必配合rkt --dir=<dataDir> status UUID使用。

命令综合示例:脚本中捕获 Pod 退出码

将上述能力组合起来,可以在 shell 脚本中完整捕获一个 Pod 的退出结果:

# 启动 Pod(后台运行),保存 UUID 到文件 rkt run --uuid-file-save=/tmp/myapp.uuid myapp.aci & # 等待 Pod 结束(最多 60 秒),然后打印终态 rkt status --wait=60s --uuid-file=/tmp/myapp.uuid # 等待结束后单独查询 JSON 格式的完整状态 rkt status --format=json-pretty --uuid-file=/tmp/myapp.uuid

如果 Pod 超过 60 秒仍未结束,--wait=60s会因 context 超时而以状态码 254 失败,脚本据此可决定是继续等待还是强制处理(例如后续配合rkt stop、rkt rm,见 Documentation/subcommands/stop.md 与 Documentation/subcommands/rm.md)。

使用注意事项小结

  • UUID 支持前缀匹配,但必须唯一,否则报ambiguous uuid, N matches;匹配逻辑见 pkg/pod/uuid.go。
  • pid在running状态初期可能缺失,脚本不应假设它立即可用。
  • --wait与--wait-ready均支持true/false/duration 三种取值,裸写开关等价于true。
  • --wait-ready的等待先于--wait执行,两者可组合使用(先等就绪、再等结束)。
  • 应用退出码只有在 Pod 非running状态时才输出,且以app-前缀区分。
  • 想要以程序化方式消费状态信息,优先使用--format=json/--format=json-pretty。

如需进一步了解 Pod 的完整生命周期与状态机(embryo→preparing→prepared→running→exited/garbage等状态及锁迁移规则),可阅读 Documentation/devel/pod-lifecycle.md 以及其对应的状态常量定义 pkg/pod/pods.go。

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

【免费下载链接】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
点击查看免费下载
上一篇:CDCS金融算法挑战赛终极指南:甜橙金融与融360实战案例深度解析
下一篇:Yearning轻量级部署指南:5步实现资源受限环境下的SQL防御

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

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

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

立即咨询