可启动容器 (bootc) 的部署

https://bugs.launchpad.net/ironic/+bug/2085801

虽然可启动容器是一个相对较新的概念,但从更高层次的概念来看,容器的整体概念限定于一个文件系统,源自于容器镜像。容器镜像本身只是“tgz”文件中分层复合的文件,最终创建一个镜像。

虽然“容器”可以采用多种不同的形式,包括一种通用的镜像传输机制,但本规范的主要驱动力是启用从容器注册表中获取的有效部署,即我们使用 bootc 来促进可启动容器的部署的形式。

问题描述

如今,Ironic 的“镜像”部署选项有限,主要限于表示文件系统的磁盘镜像,或者具有多个分区的整个块设备布局。在社区术语中,这些分别被称为分区镜像和全盘镜像。

这些方法通常被称为“经过尝试和验证的方法”,因为它们代表着相对准确的复合体,需要标准化的流程来协调内容。但这些方法也有缺点,因为它们需要复杂且因此脆弱的流程(引导加载程序设置)、引导加载程序指针注入,以及/或将空白和文件系统结构方面(如块设备大小)编码到镜像中,这增加了额外的复杂性。

这种复杂性可能会强制维护多种不同类型的镜像,但最终,我们的用户应该被授权做出许多不同的权衡。

虽然现有的 Qcow2 格式的镜像格式处理在一定程度上可以处理空白,但这并不是解决所有此类问题的方案。例如,我们的引导加载程序安装建模是基于 Grub/Grub2 的,这与未来 UniKernel 镜像 (UKI) 工作负载不一致,后者不使用引导加载程序。同样,全盘镜像无法在飞行中从 512 字节块大小结构安全地转换为 4kB 块结构,并且需要重新制作镜像,因为结构和分区明显不同,例如逻辑卷。

这使得回到文件的概念成为可能。获取文件,将其放在磁盘上,并让镜像通过标准结构和路径来完成必要的操作,例如,对于 x86_64 主机上的 Linux 工作负载,默认的启动工件是 /boot/efi/EFI/BOOT/BOOTX64.EFI。一种更现代的解决方案是将其中一些负担和挑战转移到外部工具,即支持通过 bootc 项目使用可启动容器。

提议的变更

为了促进可启动容器的部署,我们需要考虑整体的使用模型。在大多数情况下,你不会在磁盘上有一个代表整个容器的文件,而是用户可能拥有一个容器注册表,他们将其用作远程镜像存储来存储他们的镜像。

这意味着,如果有人查看可启动容器的使用方式,只谈论远程容器注册表才有意义,因此我们将只提供一种机制来下载通过 instance_info\image_source 参数提供的容器,然后执行 bootc-install-to-disk,并使用足够的磁盘利用率大小来允许注入配置驱动器。

为了实现这一点,我们将创建一个新的 deploy_interface,称为 bootc,它将基于 CustomAgentDeploy,目的是启动代理,然后通过添加到代理中的额外支持,利用 bootc 工具来触发安装过程。

安装过程将采用一种模型,即容器直接从容器注册表下载,绕过 image_download_source 建模所涉及的内容,该建模存在于 agent 部署接口的逻辑中。

在具有代理的主机内存中,容器可以启动,然后调用 bootc-install-to-disk 命令,允许我们尝试部署的镜像负责自身的安装。这是模型的要求,同时也将部署逻辑的整体维护者从本部署接口的使用情况下的 Ironic 转移到镜像本身。因此,这需要在请求的容器镜像中存在 bootc。为了最好地保护这一点,并为操作员提供禁用此功能的方式,此选项被公开为自己的简化部署接口,而不是向现有的部署逻辑和工作流程添加进一步的复杂性。

注意

该模型的总体优势在于容器知道如何安装自身,最终可以将许多逻辑从 Ironic 卸载,从而能够部署更多异构镜像,其中容器只是知道“该怎么做”。此外,直接从容器部署的支持允许操作员删除整体工作流程步骤或强制执行尴尬的手动流程到整体部署序列中,而如今必须“准备磁盘镜像”。

警告

该模型的总体缺点是它可能比预先制作的磁盘镜像慢。在这种模型中,我们将大量工作转移到“正在部署的节点”,作为整体权衡的一部分。

总的来说,该模型旨在专注于 UEFI 的使用,并仍然支持 Ironic 使用配置驱动器的模型,同时还启用一些特定的部署时选项,例如 root 用户 authorized_keys 注入和 LUKS 加密。

备选方案

我们可以“抽象”或隐藏许多逻辑来促进这在代理内部,这是最初为本规范提出的,但是经过反思和审查,与另一个规范,变更 933612 一致,似乎拥有一个明确的接口和结构模型更合乎逻辑,如果我们尝试使用不太具体的模型来支持每种建模用例,我们也会打开大门,最终需要支持更复杂的交互,从而增加由此工作产生的错误的风险。

数据模型影响

状态机影响

REST API 影响

客户端 (CLI) 影响

“openstack baremetal” CLI

“openstacksdk”

RPC API 影响

驱动程序 API 影响

Nova 驱动程序影响

Ramdisk 影响

预计此更改将在 ironic-python-agent 源代码中现有的代理源代码和流程中进行。

安全影响

目前没有已知的其他安全影响。

其他最终用户影响

可扩展性影响

性能影响

其他部署者影响

该模型需要将容器加载到内存中,这对于较大的容器镜像可能存在问题。

开发人员影响

此更改可能无法使用上游 CI 中的容器镜像进行测试。社区可能需要确定一个中间立场来以现实的方式促进此测试。

实现

负责人

主要负责人

Julia “TheJulia” Kreger

工作项

  • 将可选依赖项 podman 添加到 ironic-python-agent ramdisk,以促进容器的下载和 bootc 工具的执行。

注意

podman 的使用在很大程度上被认为是隐藏的实现细节,并且可能由于本规范所依赖的镜像 URL 工作而已经存在于 ramdisk 镜像中。

  • 创建一个新的接口方法来下载、执行和将容器安装到磁盘。

  • 添加示例部署文档。

依赖项

  • Podman

  • 如变更 933612 中提出的 OCI 容器 URL 支持,尽管不太可能进行导体端 URL 处理,因为将所有架构镜像到单独的容器注册表中也是一项效率低下的操作,因为额外的镜像格式会导致需要传输更多数据。在稍后的某个时间点,这种想法可能会成为一个不同的功能。

测试

我们预计这将需要一个单独的 CI 作业来使用,或者可能可以通过 tempest 在一个组合的 CI 作业中有效地驱动。在进入实施阶段之前,这可能没有明确的答案。

升级和向后兼容性

不适用

文档影响

预计不会产生负面影响。

参考资料