自动化执行环境剖析
自动化执行环境剖析
Red Hat Ansible Automation Platform 2 引入了重大架构变更,例如自动化网格和自动化执行环境,这有助于以灵活的方式扩展整个组织的 Ansible 自动化,为所有组织和混合云自动化需求提供单一解决方案。
自动化执行环境是充当自动化控制器作业的 Ansible 运行时的容器镜像。Ansible Automation Platform 还包含一个名为 ansible-builder(执行环境构建器)的命令行工具,允许您通过指定 Ansible 内容集合和 Python 依赖项来创建自动化执行环境。
通常,自动化执行环境包括
- 一个 Python 版本。
- 一个 ansible-core 版本。
- Python 模块/依赖项。
- Ansible 内容集合(可选)。
在本博文中,我将带您了解 ansible-builder 的内部机制以及 **如何** 将所有上述需求打包到自动化执行环境中,并作为 Ansible Automation Platform 的一部分交付。
两个 ansible-builder 包的故事
与 Red Hat 中的所有项目一样,ansible-builder 遵循开放式开发模型和上游优先方法。 ansible-builder 的上游项目作为 Python 包发布,然后打包到 Ansible Automation Platform 下游的 RPM 中。 这也意味着有不同的方法可以安装上游包和下游 ansible-builder。
注意:要获取下游包,您必须订阅来自 Red Hat 的 Ansible Automation Platform 存储库。
上游
pip3 install ansible-builder
下游:
dnf install ansible-builder
这有时会导致用户之间产生混淆,因为 Ansible Automation Platform 的客户也可以免费安装 Python 包。 上游和下游包之间存在细微差异,您应该在深入研究构建自动化执行环境之前了解这些差异。
如前所述,自动化执行环境是充当 Ansible 运行时的容器镜像,ansible-builder 与 Podman 和 Docker 等通用容器引擎非常相似。 因此,与任何其他容器引擎一样,构建镜像的概念从基础镜像开始; 这就是上游和下游 ansible-builder 包不同的原因。 上游 ansible-builder(Python 包)中用作预定义常量的基础镜像如下
EE_BASE_IMAGE='quay.io/ansible/ansible-runner:latest' EE_BUILDER_IMAGE='quay.io/ansible/ansible-builder:latest'
下游包中的基础镜像如下
EE_BASE_IMAGE='registry.redhat.io/ansible-automation-platform-22/ee-minimal-rhel8:latest' EE_BUILDER_IMAGE='registry.redhat.io/ansible-automation-platform-22/ansible-builder-rhel8:latest'
上游基础镜像可通过 Red Hat Quay.io 获取,而下游镜像来自 Red Hat 生态系统目录(registry.redhat.io),这需要使用 Red Hat 帐户进行身份验证。 这些镜像的另一个区别是,上游镜像使用 CentOS 镜像作为基础镜像,而下游镜像使用 Red Hat 通用基础镜像 (UBI)。 与 CentOS 镜像相比,UBI 为 Red Hat 官方容器镜像提供更高的可靠性、安全性和性能。
上游和下游包的一个共同点是,它们都允许通过名为 execution-environment.yml 的自动化执行环境规范文件进行镜像配置。
无论您是 Ansible Automation Platform 客户还是 ansible-builder 的社区用户,您都可以根据包使用 UBI 镜像或 CentOS 镜像作为自动化执行环境的基础镜像,或者通过将不同的基础镜像集传递给自动化执行环境规范文件。
为什么 ansible-builder 包有两个基础镜像?
承接上一节介绍的 ansible-builder 的上游和下游基础镜像,有两个参数指定要使用的镜像
EE_BASE_IMAGE
构建参数指定自动化执行环境的父镜像。EE_BUILDER_IMAGE
构建参数指定用于编译类型任务的镜像。
对于大多数容器镜像,通常只需要一个基础镜像,然后在该镜像之上添加不同的指令,也称为构建步骤,以创建最终的容器镜像。
但是,基础自动化执行环境 (ee-minimal) 是使用容器的多阶段构建概念构建的。 EE_BUILDER_IMAGE
构建参数充当中间步骤,用于安装集合和构建依赖项,以尽可能降低基础镜像的大小。
举个例子:假设您的 Ansible 内容集合依赖于需要使用 python-dev 包(例如 NumPy)进行编译的 Python 包。 由于 python-dev 是编译时依赖项,因此您不一定需要将其包含在最终包中(您只需要 NumPy 包)。 您不希望将 python-dev 包含在最终镜像中,以尽可能降低镜像大小。 为此,EE_BUILDER_IMAGE
用于构建依赖项,然后仅将最终自动化执行环境所需的软件包轮子复制过来。
如果我想构建自定义自动化执行环境,这有关系吗?
在大多数情况下,这无关紧要。 当您使用 ansible-builder 构建自动化执行环境时,您只需要 EE_BASE_IMAGE
,而不需要 EE_BUILDER_IMAGE
。 但是,您应该了解如何在名为 bindep.txt 的自动化执行环境规范文件中应用编译时二进制依赖项。 对于上面的示例,如果您需要将 NumPy Python 包作为集合在 UBI8 上的依赖项安装,则指定 bindep.txt 和 requirements.txt 如下
# bindep.txt python38-devel [compile platform:rhel-8] #compile time dependency
# requirements.txt
NumPy
在某些情况下,自动化执行环境规范中的配置不会反映出来,或者在您构建自动化执行环境时会发生错误。 在这些情况下,了解 EE_BUILDER_IMAGE 的作用很重要。 下一节将更详细地解释这一点。
自动化执行环境设计
上图概述了自动化执行环境的设计方式。 我已在相同的框中提到了上游镜像名称和下游镜像名称。
作为参考,CentOS 8 和 UBI8(对于下游)作为 python-base 容器镜像的基础镜像,该镜像充当运行基于 Python 的项目的镜像,因此它捆绑了 ansible-core 包(参考 python 3.8)支持的 Python 版本。
这个 python-base 镜像是 python-builder 镜像和 ansible-runner(ee-minimal 下游)镜像的基础镜像。 为了总结 python-builder 和 ansible-builder 镜像的目的,它们构建 Python 项目,例如 ansible-core 和任何依赖于 Python 的集合。 例如,如果您的集合依赖于需要在机器本身上构建轮子的 Python 依赖项,则它们将在 python-builder 镜像上构建。
最后,ansible-runner(ee-minimal 下游)镜像包含一个 ansible-core 包版本。 ansible-builder 镜像与该镜像协同工作以构建 Python 轮子,以便通过仅保留运行所需自动化所需的元素来使最终的自动化执行环境大小最小化。 图中的 custom-ee1 和 custom-ee2 代表可以使用 ansible-runner(ee-minimal 下游)和 ansible-builder 镜像创建的任何自定义自动化执行环境。
验证您的基础镜像
要开始构建自定义自动化执行环境,您应该首先验证 ansible-builder 默认情况下使用哪些 EE_BASE_IMAGE
和 EE_BUILDER_IMAGE
。 要验证,首先创建一个空的自动化执行环境定义文件,名为 execution-environment.yml
touch execution-environment.yml
然后,通过在创建空定义文件的同一个目录中运行以下命令,从空定义文件创建构建上下文
ansible-builder create
这将在您的工作目录中创建一个上下文目录,其中包含一个 Containerfile。 打开 Containerfile 会显示哪些镜像设置为 BASE 和 BUILDER 镜像,并告诉您正在使用哪个 ansible-builder,是上游还是下游。 例如,如果您打开通过上述过程和 ansible-builder 的 pip install 创建的 Containerfile,您会看到以下内容
ARG EE_BASE_IMAGE=quay.io/ansible/ansible-runner:latest ARG EE_BUILDER_IMAGE=quay.io/ansible/ansible-builder:latest FROM $EE_BASE_IMAGE as galaxy ARG ANSIBLE_GALAXY_CLI_COLLECTION_OPTS= USER root FROM $EE_BUILDER_IMAGE as builder FROM $EE_BASE_IMAGE USER root COPY --from=builder /output/ /output/ RUN /output/install-from-bindep && rm -rf /output/wheels
在前两行中,您可以观察到镜像指向上游镜像。 如果您对 ansible-builder 的下游安装执行相同的过程,您会在类似的 Containerfile 中找到下游镜像。
使用 ansible-builder 上下文
上下文构建是 ansible-builder 的重要方面。 您可以使用上下文更改 Containerfile 并根据您的需求自定义自动化执行环境。 您可以使用此上下文和使用 BUILDER 和 BASE 镜像进行多阶段构建的知识,在断开连接的环境中构建自动化执行环境。 以下显示了从私有自动化中心实例拉取 BUILDER 和 BASE 镜像的执行环境定义
# cat execution-environment.yml
---
version: 1
build_arg_defaults:
EE_BASE_IMAGE: 'automation-hub.demolab.local/ansible-automation-platform-22/ee-minimal-rhel8:latest'
EE_BUILDER_IMAGE: 'automation-hub.demolab.local/ansible-automation-platform-22/ansible-builder-rhel8:latest'
dependencies:
python: requirements.txt
requirements.txt 文件的内容如下
# cat requirements.txt dnspython==1.15.0
让我们为上面的定义文件 execution-environment.yml 创建一个上下文
# ansible-builder create Complete! The build context can be found at: /root/disconnected_ee/context
在断开连接的环境中构建自动化执行环境时,可能会出现以下问题(本示例考虑了下游镜像的构建)
- 无法访问外部 yum 存储库。
- 无法从外部 PyPI 服务器拉取 Python 依赖项,因此在构建自动化执行环境时使用内部 PyPI 代理。
- (可选)从内部 PyPI 镜像拉取时出现 SSL 证书问题。
首先,创建一个指向本地镜像的 pip.conf
# cat context/pip.conf [global] index-url = https://nexus-nexus.apps.celeron.demolab.local/repository/pypi-proxy/simple/
您将上面的 pip.conf 文件和证书添加到目标自动化执行环境创建的上下文文件夹中,以便将这些文件添加到自定义执行环境中。
使用多阶段构建知识和上下文编辑,编辑 Containerfile。 注意以粗体文本标记的部分以及一些注释。 这些是用于以断开连接的方式构建自动化执行环境的更改。
# cat Containerfile ARG EE_BASE_IMAGE=automation-hub.demolab.local/ansible-automation-platform-21/ee-supported-rhel8:latest ARG EE_BUILDER_IMAGE=automation-hub.demolab.local/ansible-automation-platform-21/ansible-builder-rhel8:latest FROM $EE_BASE_IMAGE as galaxy ARG ANSIBLE_GALAXY_CLI_COLLECTION_OPTS= USER root ADD _build /build WORKDIR /build FROM $EE_BUILDER_IMAGE as builder ADD _build/requirements.txt requirements.txt RUN ansible-builder introspect --sanitize --user-pip=requirements.txt --write-bindep=/tmp/src/bindep.txt --write-pip=/tmp/src/requirements.txt ####### Changes to create EE in a disconnected environment # Remove ubi repo which tries to reach external links RUN rm -f /etc/yum.repos.d/ubi.repo # Add pip.conf for internal pypi proxy ADD pip.conf /etc/pip.conf # Add CA certificate and update trust ADD demolab-ca.crt /etc/pki/ca-trust/source/anchors/demolab-ca.crt RUN update-ca-trust ####### This marks the end of edits for the builder stage RUN assemble FROM $EE_BASE_IMAGE USER root COPY --from=builder /output/ /output/ ####### Changes to create EE in a disconnected environment # Remove ubi repo which tries to reach external links RUN rm -f /etc/yum.repos.d/ubi.repo # Add pip.conf for internal pypi proxy ADD pip.conf /etc/pip.conf # Add CA certificate and update trust ADD demolab-ca.crt /etc/pki/ca-trust/source/anchors/demolab-ca.crt RUN update-ca-trust ####### This marks the end of edits for the main image RUN /output/install-from-bindep && rm -rf /output/wheels
如果您仔细观察上面的 Containerfile,您会注意到添加的内容修复了之前在 BUILDER 和 BASE 镜像阶段提到的所有问题,因为这两个镜像都使用此信息来拉取和构建 Python 依赖项。
了解每个阶段发生的事情有助于您了解在哪里以及在哪个阶段编辑 Containerfile,从而允许您对自定义自动化执行环境进行无限制的自定义。
最后,让我们使用以下命令构建上面的执行环境
podman build -f context/Containerfile -t disconnected_ee:1.0
构建成功后,您应该会看到类似以下的消息
--> 2316db485a1 Successfully tagged localhost/disconnected_ee:1.0 2316db485a1c4e7be4a687c682d0fc90335372d7e5564774f1ff6451840ac35f
展望未来
我们的最终目标是为客户提供尽可能无缝的开发人员体验。Ansible 工程团队正在致力于增强自动化执行环境构建体验,并且已经计划了多项改进。在这些增强功能可用之前,本博文将帮助您应对构建自动化执行环境过程中遇到的任何挑战。遵循上游优先模型意味着您也可以参与社区讨论,并通过 IRC 提供您的想法和反馈。请点击这里加入我们。自动化执行环境体验的主要增强功能之一正在此GitHub 拉取请求中讨论,因此您也可以参与 GitHub 讨论。