☰
理解 rkt 的 App Container 基础:ACI 镜像、Pod 执行单元与 appc 规范实现验证
2026/9/25 6:06:25 网站建设 项目流程
  • 容器运行时
  • 云原生
  • 网络

【免费下载链接】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 官方文档 Documentation/app-container.md 为骨架,系统讲解 rkt 所依赖的 App Container(appc)开放规范:它定义了应用容器镜像格式(ACI)、运行时环境与发现协议,而 rkt 的原生镜像格式与运行时环境正是该规范的直接实现。读完本文,你将掌握 ACI 的组成结构与构建工具、Pod 这一基本执行单元的设计语义、rkt 作为 Application Container Executor(ACE)的验证方法,并理解 rkt 如何通过源码层面复用appc/spec与docker2aci来落地上层规范。

appc:定义"如何在容器中运行应用"的开放规范

App Container(简称 appc)是一个开放规范,它定义了如何在容器中运行应用程序的若干核心方面:

  • 镜像格式(image format):应用程序如何被打包、分发与校验;
  • 运行时环境(runtime environment):容器如何获得名称、资源约束、网络上下文等执行所需信息;
  • 发现协议(discovery protocol):如何根据镜像名称解析并获取镜像。

rkt 的原生镜像格式和运行时环境直接采用该规范所定义的标准,从而保证"写一次镜像,处处可运行"的互操作性。需要说明的是,截至 2016 年底,appc 除了小幅修补外已不再积极开发,但它功能完整且稳定,rkt 将持续支持;未来版本的 rkt 可能增加对 OCI 格式的原生支持。这是理解 rkt 技术选型背景的重要前提——rkt 本质上是一份 appc 规范的工程实现,而不是凭空发明的新容器格式。

ACI:rkt 使用的应用容器镜像格式

ACI 的结构与内容

appc 定义并由 rkt 使用的镜像格式称为Application Container Image(应用容器镜像),缩写为ACI。一个 ACI 本质上是:

  • 一个简单的tarball 包(归档文件),其中包含:
    • rootfs:应用执行所需的全部文件(即容器内的完整根文件系统);
    • Image Manifest(镜像清单):一份 JSON 文档,定义镜像的默认执行参数(如默认执行的命令exec、运行用户/组)与默认资源约束(如 CPU、内存限制)。
  • 两者以规范定义的目录布局和文件位置打包在一起,使任意符合规范的运行时都能解包并运行该镜像。

从源码层面可以印证这一结构:pkg/aci/aci.go 中的NewImageWriter实现了"基于给定 manifest 生成 ACI 归档"的写入器:Close()方法在归档收尾时通过addManifest将镜像清单以aci.ManifestFile名义写入归档(见 pkg/aci/aci.go),而addFileNow则以 0644 权限写入普通文件条目。同时该包复用了上游github.com/appc/spec/aci与github.com/appc/spec/schema的数据结构来操作 ACI——这正是文档所述"rkt 使用上游 appc/spec 仓库的 schema 和代码来操作 ACI"的代码级证据。

构建与转换 ACI 的工具链

ACI 可以使用多种工具构建:

  • acbuild:以命令式方式逐层构建 ACI;
  • actool:appc/spec 仓库自带的构建工具;
  • goaci:Go 语言项目的 ACI 构建工具。

对于存量 Docker 镜像,可以使用docker2aci将其转换为 ACI。rkt 甚至会自动完成这一转换:当你以docker://前缀引用 Docker 镜像时,rkt 会透明地拉取并转换为 ACI 再运行,无需用户手动介入。该自动转换的实际执行逻辑位于 rkt/image/dockerfetcher.go:dockerFetcher.Hash()调用d2acommon.ParseDockerURL解析docker://[REGISTRY_HOST[:REGISTRY_PORT]/]IMAGE_NAME[:TAG]形式的 URL,fetch()则通过docker2aci.ConvertRemoteRepo将远程 Docker 仓库转换为squashed(压缩合并的)ACI 文件,再交给imagestore.Store.WriteACI存入本地镜像库(见 rkt/image/dockerfetcher.go)。由于 Docker 镜像不支持签名验证,使用docker://拉取时必须以--insecure-options=image关闭镜像签名校验(下文详细说明)。

运行时参数可覆盖性

ACI 镜像清单中定义的大多数参数都可以在运行时由 rkt 覆盖。最典型的例子是rkt run允许用户为镜像提供自定义的 exec 参数:例如rkt run example.com/worker -- --loglevel verbose会把--loglevel verbose追加为应用的执行参数;--exec、--user、--group、--cpu、--memory等标志也可以分别覆盖镜像中的默认可执行文件、运行用户/组与资源隔离器。这一点体现了"镜像定义默认值、运行时决定实际值"的设计哲学,也是 rkt 灵活性的来源之一。

Pods:appc 定义的基本执行单元

Pod 的语义

appc 将Pod(荚)定义为基本执行单元:

  • 一个 Pod 是一个或多个应用镜像(ACI)的分组;
  • 可以对整个 Pod 施加额外的元数据,例如在 Pod 级别应用资源约束,从而为 Pod 内所有应用形成一个"外边界"(outer bound)——任何应用自身的约束都不得超过该边界;
  • Pod 内的所有镜像在共享的上下文中执行,包括共享网络(networking)。

因此 Pod 提供了一个"多进程、共享网络、统一资源边界"的执行环境,与单容器模型形成鲜明对比。

rkt 中的 Pod 与 Kubernetes Pod 的一致性

rkt 中的 Pod 概念与 Kubernetes 中定义的 Pod 在概念上一致:两者都强调"一组共享生命周期与网络命名空间的容器集合"。这也是 rkt 早期被设计为 Kubernetes 运行时(kubelet 的--container-runtime=rkt选项)的底层原因——容器引擎的抽象层级与编排系统保持一致,减少了语义转换成本。

Pod 在 rkt 中的工程实现

从源码结构看,Pod 的工程实现由 pkg/pod/pods.go 承载。该文件中的Pod结构体反映了 Pod 及其生命周期状态,其生命周期状态机(embryo → preparing → prepared → running → exited,以及垃圾回收相关的 exited-garbage / garbage 等状态)通过文件系统目录(pods/embryo、pods/prepare、pods/prepared、pods/run、pods/exited-garbage、pods/garbage)配合文件锁来表达(见 pkg/pod/pods.go)。每个 Pod 通过NewPod分配一个 UUID,并在ToPreparing/ToPrepared/ToRun等方法中完成状态迁移与目录重命名(pkg/pod/pods.go)。

Pod 内的应用清单由Pod Manifest(运行时清单)表达。当用户不提供 pod manifest 时,stage0.Prepare会调用generatePodManifest依据 CLI 参数生成(见 stage0/run.go);当用户通过--pod-manifest提供清单文件时,则走validatePodManifest进行校验并逐应用校验镜像 ID、从本地镜像库读取对应 Image Manifest、检查重复应用名与端口转发合法性(stage0/run.go)。--pod-manifest模式下镜像必须已在本地 store 中,rkt 不会进行发现或拉取。

验证 rkt 作为 appc 实现:ACE 与 Metadata Service

rkt 实现的两大运行时组件

rkt 实现了 appc 规范的两个运行时组件:

  1. Application Container Executor(ACE,应用容器执行器):负责实际拉取、准备并运行 ACI 的核心执行部分;
  2. Metadata Service(元数据服务):为运行中的应用提供一种自省执行环境、查询 pod/镜像清单、查找注解,并基于 HMAC token 提供可加密验证的 Pod 身份的服务。

此外,rkt 使用上游 appc/spec 仓库的 schema 和代码来操作 ACI、处理镜像与 Pod 清单,并执行镜像发现。

使用 ACE 验证镜像执行规范合规性

为验证 rkt 成功实现了 appc 规范的 ACE 部分,官方文档推荐使用 App Container 的验证用 ACI(validation ACIs)。执行方式如下:

# rkt metadata-service & # 确保元数据服务正在运行 # rkt --insecure-options=image run \ --mds-register \ --volume=database,kind=host,source=/tmp \ https://github.com/appc/spec/releases/download/v0.8.11/ace-validator-main.aci \ https://github.com/appc/spec/releases/download/v0.8.11/ace-validator-sidekick.aci

这条命令的关键要素逐项拆解:

  • rkt metadata-service &:先在后台启动元数据服务,供--mds-register注册 Pod 使用。元数据服务的实现位于 rkt/metadata_service.go,它默认监听/run/rkt/metadata-svc.sock这个 Unix socket 接收注册事件,同时监听 TCP 端口 18112 供容器内应用通过AC_METADATA_URL环境变量访问(参见 Documentation/subcommands/metadata-service.md)。
  • --insecure-options=image:因为验证 ACI 通过 HTTPS URL 直接下载,需要允许跳过镜像签名验证;
  • --mds-register:让 rkt 在stage0.Run中通过registerPod将 Pod 及其应用清单注册到元数据服务,并获得一个 16 字节随机数生成的 token 作为身份凭证(见 stage0/registration.go);该注册走的是Unix socket,与容器内应用访问元数据所用的 TCP 端口是两条路径;
  • --volume=database,kind=host,source=/tmp:将宿主机的/tmp目录以 host 类型卷挂载进 Pod,验证 ACI 测试文件卷挂载能力;
  • 两个验证 ACI(main 与 sidekick):ace-validator-main.aci是主验证容器,ace-validator-sidekick.aci是伴随容器,二者共同组成一个完整的验证 Pod。

验证通过后,ace-validator-main会输出各测试阶段的... OK结果。这一流程在仓库测试中也有自动化对应:tests/rkt_ace_validator_test.go中的TestAceValidator会先LaunchMDS()启动元数据服务,再以--insecure-options=image run --mds-register --volume database,kind=empty运行验证 ACI,并用正则ace-validator-(?:main|sidekick)\[\d+\]: ([[:alpha:]]+) OK解析输出、断言prestart、main、sidekick等阶段全部通过(见 tests/rkt_ace_validator_test.go)。

元数据服务的配套使用细节

要让验证 Pod 内的应用能真正访问元数据服务,Pod 必须能到达宿主机上的该服务,因此--mds-register需要配合--net=default(或default-restricted、host)等具备宿主机连通性的网络模式使用;若配合--net=none则会报错(该约束在 rkt/run.go 中有明确校验)。这与验证命令中隐含的默认网络设置是配套的。元数据服务还支持 systemd socket activation 场景,此时 socket 必须命名为/run/rkt/metadata-svc.sock,并建议在.socket文件中使用RemoveOnStop指令清理 socket 文件。

rkt 对 Docker 镜像的透明转换:一个 ACI 生态的实战补充

虽然 Documentation/app-container.md 的核心是 appc/ACI/Pod 概念,但文档明确提到"rkt 会自动将 Docker 镜像转换为 ACI",因此这里给出可直接落地的操作示例,作为 ACI 生态的实战闭环。完整指南见 Documentation/running-docker-images.md。

使用docker://前缀引用 Docker 镜像,rkt 会从默认的 Docker Hub 拉取并自动转换:

# rkt --insecure-options=image run docker://redis rkt: fetching image from docker://redis rkt: warning: image signature verification has been disabled Downloading layer: 511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158 ... sha512-c6d6efd98f506380ff128e473ca239ed

注意事项:

  • Docker 镜像不支持签名验证,因此必须配合--insecure-options=image,否则 rkt 会拒绝拉取(dockerFetcher.fetchImageFrom中显式检查该标志,见 rkt/image/dockerfetcher.go);
  • 默认使用 Docker Hub;指定其他 registry 只需把 registry 写进镜像引用,如rkt --insecure-options=image fetch docker://quay.io/zanui/nginx;
  • 拉取完成后,sha512-...是转换后 ACI 的镜像 ID,之后可直接用该 hash 运行:rkt --insecure-options=image run sha512-c6d6efd98f506380ff128e473ca239ed。

从调用链看,rkt run/rkt fetch首先经过 rkt/image/finder.go 的Finder.FindImage:若参数是合法 hash 则直接从本地 store 解析;否则通过Fetcher依据镜像字符串判定分发类型(Docker 分发、ACI 归档、appc 名称发现或普通 HTTP 地址),再委派给对应的 fetcher 执行拉取(rkt/image/finder.go)。

总结

rkt 的容器模型完全建立在 appc 开放规范之上,具体表现为三个层次:

  1. 镜像层:以 ACI 作为标准镜像格式(rootfs + Image Manifest 的 tarball),可通过 acbuild/actool/goaci 构建、docker2aci 转换,且镜像内的大多数参数都能在运行时被rkt run覆盖;
  2. 执行单元层:以 Pod 作为基本执行单元,支持多镜像共享网络与统一的资源"外边界",该概念与 Kubernetes Pod 保持一致,并经由 pkg/pod/pods.go 以目录 + 锁的机制实现完整生命周期管理;
  3. 验证层:rkt 实现 appc 的 ACE 与 Metadata Service 两个运行时组件,官方通过ace-validator-main.aci+ace-validator-sidekick.aci组成验证 Pod,配合元数据服务与卷挂载完成规范符合性验证,该流程也被tests/rkt_ace_validator_test.go固化为自动化测试。

理解这一"规范驱动实现"的架构,是深入掌握 rkt 的镜像处理、Pod 生命周期、网络与安全模型的前提——无论你是想基于 rkt 构建工具链,还是对照 appc 规范做二次实现,本文所梳理的镜像格式、执行单元与验证路径都能直接作为切入点。

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

【免费下载链接】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
点击查看免费下载

相关推荐

上一篇:探索代码的海洋:cloc——你的代码行数统计专家
下一篇:Cloudreve:自托管的多云文件管理系统

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

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

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

立即咨询