幕后:使用 Seekable OCI 和 亚马逊云科技 Fargate 延迟加载容器镜像
2023 年 11 月:亚马逊云科技 Fargate 现在支持在同一个亚马逊 ECS 任务中同时使用启用 SOCI 和未启用 SOCI 的容器,因此 “亚马逊 ECS 任务中的所有容器镜像都需要 SOCI 索引清单” 的限制不再适用。要了解更多信息,请参阅
在这篇文章中,我们将深入探讨 SOCI 以及它如何在不修改内容或无需更改现有工具或工作流程的情况下索引容器镜像。我们将讨论 SOCI 快照工具,这是一种利用 SOCI 索
Seekable OCI 是如何工作的?
在 SOCI 快照程序可以延迟加载容器图像之前,它需要拥有有关图像内容的元数据。容器映像由多个容器映像层组成,这些层作为压缩压缩压缩包存储在与 OCI 兼容的注册表中。为了让 SOCI snapshotter 能够延迟加载容器镜像,它需要知道每个层中有哪些文件,它们存储在压缩压缩包中的哪个位置,以及如何仅解压缩应用程序需要的文件。在 SOCI 中,所有这些元数据都存储在 SOCI 索引中。
在
soci 创建
命令如何索引容器镜像并创建 SOCI 索引清单。 soci push
命令将 SOCI 索引清单推送到兼容 OCI 的注册表,随时可供 SOCI 快照程序使用。让我们更详细地了解这两个步骤。
创建 SOCI 索引清单
运行 soci create 时 ,会在幕后为每个容器映像层创建
一个 ztoC(一段 SOCI 元数据)。这个 ztoC 分为两个部分:
- 目录 (TOC) — 此表包含该图层中所有文件的列表以及该文件在 tarball 中可以找到的位置的偏移量。
- zInfo — 在 SOCI 中,压缩后的压缩包被拆分为多个跨度,即逻辑区块。跨度列表存储在一个名为 zInfo 的表中。每个跨度可以通过向注册表发出范围的 GET 请求独立检索,然后使用存储在 ZInfo 中的数据进行解压缩。使用 span,在后台进程检索完整压缩包之前,SOCI 快照程序只能从注册表中下载所需的文件。
对于每个已编入索引的容器镜像, soci c li
将创建一个 SOCI 索引清单,其中包括容器镜像的所有 ztoC,以及与之相关的容器镜像的引用。可以使用 soci 索引 信息 命令在本地查看 SOCI 索引
清单。
SOCI 指数清单的两个值得注意的部分是:
-
层
— 在 SOCI 索引中,这些图层不是容器映像图层的列表,而是相应容器映像的所有 ztOC 的列表。注释还显示 ztoC 对应于哪个容器镜像层。 -
主题
— 通过指定容器映像清单的摘要、媒体类型和大小来识别此 SOCI 索引引用的容器镜像。由客户端(在本例中为 SOCI 快照工具)来读取主题字段并知道 SOCI 索引指的是哪张图片。
下图显示了 SOCI 索引清单和容器映像清单之间的关系。
推送 SOCI 指数清单
soci push 将 SOCI 索引清单和所有 ztoC(每个容器映像层一个)推送
到兼容 OCI 的注册表。除了 SOCI 索引清单外,第二个清单,即
ha-
soci c li
将停止向支持反向链接 API 的注册表推送第二个构件。
使用 SOCI 索引运行容器
在带有索引容器镜像的容器启动之前,SOCI 快照程序会将 SOCI 索引清单和所有 ztoC 下载到容器主机。它还将为每个容器映像层创建一个
- SOCI 快照程序首先进行查找以找到包含该文件的图层。
- 快照程序从 TOC 检索文件在图层压缩包中的位置。
- 快照程序使用偏移量和 zInfo 表来查找包含该文件数据的一组跨度(即压缩压缩包的逻辑区块)。
- 最后,它仅下载和解压缩必要的跨度,并返回文件的数据。下载跨度后,SOCI 会使用本地缓存来确保仅下载和解压缩每个跨度一次。
自动生成 SOCI 索引图像
SOCI 项目的主要目标之一是实现延迟加载,而客户无需更改现有的工作流程和工具。使用 SOCI 为容器映像编制索引不会修改容器映像数据,从而保留现有签名和摘要验证流程中存在的信任链。我们还知道客户希望自动生成 SOCI 索引。因此,除了使用 SOCI 在 亚马逊云科技 Fargate 上启动延迟加载容器镜像的同时,我们还发布了 SOC
SOCI 索引生成器提供了一个蓝图,用于在将容器映像推送到 Amazon ECR 时自动创建 SOCI 索引。该项目的源代码是开源的,可在
要开始使用该项目并将其部署到您的账户中,请参阅
其他工具
除了 SOCI 索引生成器,我们还
-
容器化索引生成器 — 使用 Docker 引擎作为开发工作流程一部分的客户,例如运行 Docker Desktop 的客户,会发现 soci cli 找不到他们的容器镜像。
这是因为默认情况下,Docker 引擎将容器镜像存储在 Docker Engine 镜像存储区中,而不是容器镜像存储库中。Moby 项目 正在努力将 Docker Engine 镜像存储迁移 到容器,但在撰写本文时,容器镜像存储还不是默认值。为了帮助客户在利用 Docker 引擎时创建 SOCI 索引,可以使用此容器化映像生成器创建 SOCI 索引。该工具的工作原理是在容器内运行容器(如 Docker 中的 Docker),从远程注册表中下拉容器镜像,为容器映像编制索引,然后将索引推回 OCI 兼容注册表。 -
亚马逊云科技 Code Pipeline 演示 — 客户通常将生产容器映像作为持续集成持续交付管道的一部分来构建。工具箱存储库中有一张亚马逊云科技 CodePipeline 的蓝图,用于展示 如何在 CI/CD 管道 中构建容器映像并对其进行索引。此示例希望为如何将 SOCI 集成到现有的 CI/CD 管道提供灵感。
在 亚马逊云科技 Fargate 上延迟加载容器镜像
事实证明,在 亚马逊云科技 Fargate 上延迟加载容器映像可以缩短启动新 Amazon ECS 任务所需的时间;但是,并非所有工作负载和容器映像都能从中受益。在内部测试中,我们已经看到,大型(> 250 MB)容器镜像从 SOCI 中获得的最大好处。但是,如果工作负载经常访问文件系统元数据,或者如果工作负载需要在应用程序启动后快速访问所有图像数据,则 SOCI 的好处就会降低。我们将继续迭代以提高性能,增加可以利用 SOCI 的工作负载数量。
在本节中,我们将深入探讨在 亚马逊云科技 Fargate 上实现延迟加载容器镜像的一些细节。
亚马逊 ECS 任务中的所有容器镜像都需要 SOCI 索引清单
为了重申这一点,在撰写本文时,如果任务中只有一个容器,请为这个容器镜像生成 SOCI 索引。如果任务中有一个工作负载容器和一个日志 Sidecar 容器,则为工作负载容器映像和日志记录的 sidecar 容器镜像生成 SOCI 索引。
识别容器镜像是否已延迟加载
在 Amazon ECS 任务中,有一个
$ curl -s $ECS_CONTAINER_METADATA_URI_V4 | jq -r '.Snapshotter'
soci
$ curl -s $ECS_CONTAINER_METADATA_URI_V4/task | jq -r '.Containers | .[0].Snapshotter'
soci
为了防止客户必须修改应用程序才能使用此端点,可以在 亚马逊云科技 F
容器图像大小
随着容器镜像大小的增加,完全下载镜像所花费的时间也会增加(因此,较大的容器镜像会成比例地影响 亚马逊云科技 Fargate 的启动时间)。在我们的内部测试中,与大型(>250 MB)容器镜像一起使用时,SOCI 对缩短 Task 启动时间的影响最大。
对于小型容器映像,SOCI 的影响较小,甚至可能减慢启动 亚马逊云科技 Fargate 任务所需的时间。这是因为下载 SOCI 工件和设置 FUSE 文件系统会产生开销。在我们的测试中,我们发现,当容器镜像压缩后大于 250MB 时,SOCI 会开始产生明显的影响。对于小于 250 MB 的容器镜像,初始延迟加载开销可能大于使用传统方法提取完整容器镜像所花费的时间。
容器图像图层大小
使用 soci create 创建 SOCI 索
引时 ,有一个参数可以控制客户端为其生成 ztoC 的容器镜像层的最小大小。默认情况下,这是一个 10MB 的图层,使用 --min-
layer-size 标志进行调整。当客户端检测到一个小层时创建 SOCI 索引时,它会跳过为该层生成 ztoC,并且该层不会在运行时延迟加载。内部测试表明,在启动时简单地下载整个小层,而不是延迟加载它,性能更高。在小型容器映像中,如果容器映像中的所有图层都小于 10MB,则不会创建 SOCI 索引。
在为侧车集装箱创建 SOCI 索引时,值得记住这一点。日志或监控容器映像中的所有容器映像层都可能低于 10MB。因此,要为他们创建 SOCI 索引,可能需要调整此参数。
结论
在这篇文章中,我们深入探讨了 Seekable OCI 和 SOCI 快照。我们已经深入研究了 SOCI 索引、它如何清点容器镜像的内容,并研究了在 亚马逊云科技 和现有 CI/CD 管道中实现自动化的方法。最后,我们探讨了今天在 亚马逊云科技 Fargate 上使用 SOCI 时的一些注意事项。