- 容器运行时
- 云原生
- 网络
【免费下载链接】rkt
[Project ended] rkt is a pod-native container engine for Linux. It is composable, secure, and built on standards.
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的实现,各字段含义如下:
| 字段 | 含义 | 说明 |
|---|---|---|
state | Pod 当前生命周期状态 | 可取embryo、preparing、aborted prepare、prepared、running、deleting、exited deleting、exited、exited garbage、garbage等,详见 pkg/pod/pods.go 的状态常量定义 |
created | Pod 创建时间 | 对应 Pod 进入 prepare 阶段的时间,读取自pod-created文件;为了兼容 rkt v1.20 之前的版本,该文件缺失时会回退到读取pod文件的修改时间,见 pkg/pod/pods.go |
started | Pod 启动时间 | 读取自pid或ppid文件的修改时间;若该 Pod 尚未启动(如仍处于prepared),则此字段不会输出,见 pkg/pod/pods.go |
pid | stage1 主进程 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)。
输出的三类字段与状态的关系
从源码可以看到,输出字段并非在所有状态下都齐全,而是分层输出的:
state、created、started是基础字段;- 当状态为
running或exited时,额外输出networks=(Pod 使用的网络列表,来自netinfo); - 当状态处于
running/deleting/exited deleting/exited/exited garbage时,尝试输出pid=; - 只有当状态不是
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.
相关推荐
EOSIO 节点对等连接状态查询:cleos net status 命令详解
EOSIO 节点对等连接状态查询:cleos net status 命令详解 cleos net status 是 EOSIO 智能合约平台中用于查询本节点与指
区块链RTK 的 /worktree-status 命令解析:Git Worktree 后台 cargo check 状态查询机制
RTK 的 /worktree status 命令解析:Git Worktree 后台 cargo check 状态查询机制 /worktree status
CLI开发工具AI 应用使用 AWS CLI 的 `cloud9 describe-environment-status` 查询开发环境状态:命令详解与源码解析
使用 AWS CLI 的 cloud9 describe environment status 查询开发环境状态:命令详解与源码解析 导读 aws cloud9
开发工具云原生运维
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考