上周末,我在 Texas Linux Fest 2016 上介绍了 Fedora 项目 如何致力于为 Docker 镜像交付可重现的构建系统。我阐述了较新的 Linux 容器技术给团队带来的新挑战,以及我们在 Fedora 社区中如何努力通过为用户和贡献者提供解决方案来应对这些挑战。
随着 DevOps 从业人员的队伍不断壮大,Linux 容器用户群也在随之增长,因为这两者通常是密切相关的。在 Linux 容器实现领域,截至本文撰写之时,Docker 无疑是服务器端应用程序部署中最流行的工具。Docker 是一个强大的工具,它提供标准的构建工作流程、镜像格式、分发机制和运行时。这些特性使其对开发团队和运维团队都极具吸引力,因为它有助于降低这些群体之间的壁垒并建立共同的基础。
与所有新技术一样,新的优势也带来了新的挑战,而 Docker 普及带来的副作用之一就是构建清理。这主要是因为 Docker 的构建过程在灵活性方面实际上等同于 shell 脚本,这意味着它非常灵活,几乎没有限制。虽然这也被许多人视为优势,但它确实给技术社区中被称为 发布工程 的人员带来了挑战。发布工程的工作是确保“软件制造”行为以可重现、可审计、可定义和可交付的方式完成。这意味着,给定相同的输入集,我们可以以标准化的方式交付相同的输出集,这种方式是明确定义的,并且可以在必要时进行审计,以便可预测地交付它。
在 Docker 构建领域,这些并不是构建管道中常见的属性。在 Docker Hub 上列出的任何给定 Docker 镜像都很难追溯其来源,因为通常有人在他们的笔记本电脑或我们无法了解的某些服务器上构建了它,然后将其推送到全世界。构建本身是一个黑匣子,可能没有日志持久性或任何安全措施。也许该构建实际上从 Internet 上拉取了一些二进制工件到文件系统中,而该文件此后已从其原始位置删除。此类担忧的例子不胜枚举。
话虽如此,我们并不希望仅仅因为存在新的挑战就放弃 Linux 容器和 Docker 的强大功能。相反,我们的目标是通过解决方案来应对这些挑战,以便我们能够以可管理的方式为未来交付软件。
需要注意的是,在 Docker 世界中,“基础镜像”和“分层镜像”之间存在差异。基础镜像由预先组成的根文件系统生成,这通常是您选择的上游 Linux 发行版(例如 Fedora、Debian、Arch、OpenSUSE、Ubuntu 或 Alpine)提供的。基础镜像传统上已经以符合发布工程理念的方式创建,因为在许多情况下,它们源于相同的构建或组合过程,以生成发行版本身。
然而,分层镜像是在这些基础镜像之上构建的任何镜像,并且通常是 Docker 构建增强的灵活性可能变得具有挑战性的地方。分层镜像实际上是一种镜像堆叠机制,它可以继承 堆栈较低层 中的其他镜像。通常,较低层提供较高层所需的功能。
这使我们想到了 Fedora 的 分层 Docker 镜像构建服务,它是 Fedora 对名为 OpenShift Build Service (OSBS) 的上游项目的实现,并与 Fedora 的 koji 构建系统 的插件配对,从而为 Fedora 贡献者提供统一的工作流程,以使用他们一直使用的同一组工具维护 RPM 和 Docker 分层镜像,但只是生成新的输出工件。该系统本身利用了 OpenShift 构建 原语,它是 OpenShift 容器平台 的内置功能。
OSBS 的作用是在 OpenShift 中创建所谓的“自定义策略”构建定义,然后将这个新定义的组件以命令行实用程序以及 Python API 的形式呈现给用户和开发人员。然后,OSBS 客户端需要从 git 存储库 提供来自启动构建的任何人或任何事物(人员、自动化任务、CI、CD 等)的信息,以便以可审计的方式向系统提供输入。然后,构建过程本身发生在称为“构建根目录”的受限环境中,这是一个具有清理输入的非特权容器,这意味着系统以编程方式禁止来自未知或未经审查来源的软件,并且内部的所有活动都将被集中记录。
此活动使用名为 atomic-reactor 的实用程序执行,该实用程序来自其上游 Project Atomic。在构建根目录中使用 atomic-reactor 提供了一些便利,例如在成功构建后将镜像推送到注册表、在 Dockerfile 中注入任意 yum/dnf 存储库(更改软件包来源以进行输入清理/门控)、更改 Dockerfile 中的基础镜像 (FROM) 以匹配隔离构建根目录中可用的注册表、在构建镜像后运行简单测试等等。
一旦发生构建,就可以立即从您选择的注册表中拉取镜像。在这里,我们将执行自动化测试,然后最终将镜像“提升”到“生产”或“稳定”注册表,以便控制 Docker 分层镜像中新构建软件的发布。
现在我们完成了,我们能够通过这个系统重现、审计、定义和交付我们的软件。
评论已关闭。