Ansible 执行环境镜像构建

Ansible 执行环境镜像构建

Ansible 的执行环境构建其实就是容器镜像构建,只不过 Ansible 提供了一个命令 ansible-builder 来实现镜像的标准化构建。

ansible-builder 默认会使用当前目录下的 execution-environment.yamlexecution-environment.yml 来当作执行环境定义文件(就是 Containerfile/Dockerfile)。

执行环境定义文件配置

Ansible Builder 3.x 中 Execution Environment Definition File(执行环境定义文件)支持的 7 个顶级配置段(Top-level sections)

顶级字段名 说明
additional_build_files 指定构建过程中需要添加到 _build/ 上下文目录中的额外文件
additional_build_steps 指定在不同构建阶段(base, builder, final)插入自定义命令,例如 RUN, COPY
build_arg_defaults 设置传递给容器引擎构建命令(如 docker build)的默认参数,等效于 --build-arg
dependencies 指定所需依赖项,如 Python、系统包、Ansible 集合等
images 定义基础镜像(base image)和构建镜像(builder image)
options 设置构建行为的额外选项,如是否保留缓存、中间构建目录等
version 定义文件格式版本,当前为 3

additional_build_files 作用

该字段用于将自定义文件或目录添加到构建上下文目录中,供后续构建步骤(如 RUN, COPY)引用或复制。

additional_build_files:
  - src: <源路径>
    dest: <目标子路径>

src源路径

  • 支持:
    • 相对路径(相对于 execution-environment.yml 文件)
    • 绝对路径(不支持通配符)
    • 通配符 glob(仅用于相对路径)
    • 目录(整个目录会被复制)
  • 示例:files/ansible.cfg/home/user/.ansible.cfg

dest目标子路径(相对于构建上下文的 _build/

  • 不可为绝对路径
  • 不可包含 ..
  • 若目录不存在会自动创建
  • 示例:files/configscustom/ansible

常配合 additional_build_steps 使用。

additional_build_steps 作用

  • 在构建执行环境镜像的各阶段 插入定制命令
  • 允许灵活控制构建过程,例如安装额外依赖、复制文件、设置环境变量等
关键词 插入位置 典型用途
prepend_base 基础镜像构建开始前 安装依赖、添加源配置
append_base 基础镜像构建完成后 清理缓存、安装自定义软件包
prepend_galaxy 安装集合前 拷贝 requirements.yml
append_galaxy 安装集合后 重新设置权限、清理缓存
prepend_builder builder 阶段开始前 安装内部工具包
append_builder builder 阶段结束后 自定义 Python 路径、虚拟环境
prepend_final final 阶段开始前 拷贝额外文件、环境变量
append_final final 阶段结束后 设置 ENTRYPOINT、LABEL、清理缓存等
additional_build_steps:
  prepend_base:
    - RUN echo "Installing base deps"
    - RUN dnf install -y epel-release
  append_base:
    - RUN dnf clean all
  prepend_final: |
    COPY _build/scripts/welcome.sh /usr/local/bin/
    RUN chmod +x /usr/local/bin/welcome.sh
  append_final:
    - RUN echo "Build complete"

这个只是示例,像缓存清理 ansible-builder 默认就会去做。

构建镜像时禁止使用 USER 指令,若需设置默认用户,应使用 options.user

build_arg_defaults 作用

用于指定构建镜像时的默认 --build-arg 变量。这些参数会被硬编码写入 ContainerfileDockerfile 中,适用于如安装 pre-release 集合、控制依赖行为、保留包管理缓存等用途。

构建参数名 类型 默认值 描述
ANSIBLE_GALAXY_CLI_COLLECTION_OPTS str null 传递给 ansible-galaxy collection install 的参数(如 --pre
ANSIBLE_GALAXY_CLI_ROLE_OPTS str null 传递给 ansible-galaxy role install 的参数(如 --no-deps
PKGMGR_PRESERVE_CACHE str null 控制包管理器缓存是否保留。可选值:always(不清理),其他值表示在系统依赖安装后清理;
设置其他任意值会在最终阶段清理缓存
如果是空值的话会频繁清理缓存

dependencies 作用

dependencies 是 Ansible Builder 执行环境定义文件中的核心字段,用于定义要安装进最终镜像的所有依赖,包括:

  • ansible-coreansible-runner
  • Python 包
  • 系统包(如用 bindep 格式)
  • Ansible Collections
  • 可选的依赖排除规则(exclude
字段名 类型 说明
ansible_core dict 使用 package_pip 指定 ansible-core 的安装方式,可为版本号、URL 等 pip 支持的格式
ansible_runner dict 使用 package_pip 指定 ansible-runner 的安装方式,同样支持 pip 格式
galaxy dict / str / list 指定要安装的 Ansible Collections,支持文件路径或嵌套字典结构
python str / list Python 依赖包,支持文件路径或直接列出
python_interpreter dict 设置系统包管理器安装的 Python 版本(对应字段 package_system)和 Python 执行路径(对应字段 python_path
system str / list 系统包依赖,使用 bindep 格式,支持文件路径或直接列出
exclude dict 指定要从 Collections 的依赖中排除的 Python 或系统依赖项(支持名称或正则)需要 Ansible Builder ≥ 3.1(格式看下边示例吧)

ansible_coreansible_runner 支持的格式(以 ansible_core 为例):

ansible_core:
    package_pip: ansible-core
ansible_core:
    package_pip: ansible-core==2.14.3
ansible_core:
    package_pip: https://github.com/example_user/ansible/archive/refs/heads/ansible.tar.gz

官网的示例:

# 引用依赖文件
dependencies:
  python: requirements.txt
  system: bindep.txt
  galaxy: requirements.yml
  ansible_core:
    package_pip: ansible-core==2.14.2
  ansible_runner:
    package_pip: ansible-runner==2.3.1
  python_interpreter:
    package_system: "python310"
    python_path: "/usr/bin/python3.10"

# 直接内联定义依赖
dependencies:
  python:
    - pywinrm
  system:
    - iputils [platform:rpm]
  galaxy:
    collections:
      - name: community.windows
      - name: ansible.utils
        version: 2.10.1
  ansible_core:
    package_pip: ansible-core==2.14.2
  ansible_runner:
    package_pip: ansible-runner==2.3.1
  python_interpreter:
    package_system: "python310"
    python_path: "/usr/bin/python3.10"

# 排除指定依赖(需要 v3.1+)
dependencies:
  exclude:
    python:
      - docker
    system:
      - python3-Cython
    all_from_collections:
      - ~community\..+  # 使用正则排除所有 community.* 相关集合的依赖

images 作用

用于指定构建执行环境的基础镜像(base image)。这个基础镜像决定了最终执行环境的操作系统以及预装的一些基础包。

字段名 类型 说明
base_image dict 定义基础镜像信息,必须包含 name

子字段:

子字段名 类型 说明
name str 镜像名称,建议使用 registry/namespace/image:tag 格式,例如:quay.io/ansible/ansible-runner:latest
signature_original_name str(可选) 当使用镜像签名校验并采用镜像仓库镜像(镜像复制)时,指定原始签名名称
images:
  base_image:
    name: myregistry.local/ansible-runner:latest
    signature_original_name: quay.io/ansible/ansible-runner:latest

镜像签名验证(Image Signature Verification)

如果使用的是 Podman 容器运行时,可以配置签名验证策略来确保镜像安全。

可选策略

策略值 说明
ignore_all 生成一个 policy.json 文件,不执行签名验证(默认跳过验证)
system 使用系统默认的签名策略文件(位于 /etc/containers/policy.json 等)进行验证
signature_required 强制签名验证,必须在 base_image 中配置镜像签名来源,否则构建失败

通过 CLI 参数 --container-policy 传递,例如:ansible-builder build --container-policy signature_required

options 作用

options 是一个高级可选项集合,用于控制构建期间和容器最终行为的细节配置,如容器初始化方式、用户设置、包管理路径等。适合有自定义镜像构建需求的用户。

字段名 类型 默认值 说明
container_init dict 详见子字段 容器 ENTRYPOINT、CMD 和辅助工具(如 dumb-init)的配置
package_manager_path str /usr/bin/dnf 指定包管理器路径,如 dnfmicrodnf,设置了这个就会用这个包管理器去安装 Python 解释器
skip_ansible_check bool false 是否跳过 ansible/runner 安装校验
skip_pip_install bool false 是否跳过 pip 安装(由用户手动处理)
relax_passwd_permissions bool true 是否允许 root 对 /etc/passwd 写权限(支持动态用户)(就是授予镜像执行用户 GID 0root 组,以允许修改 /etc/passwd 添加用户,构建的镜像自带一个添加用户的脚本)
workdir str /runner 容器中进程的默认工作目录(有时会作为 entrypoint 创建的动态用户的家目录),若目录不存在将自动创建并递归赋予 root 组的 rwx 权限
user str/int 1000 容器中默认用户(用户名或 UID)
tags list(str) ["ansible-execution-env:latest"] 构建成功后镜像使用的标签

container_init 子字段:

子字段名 类型 默认值 说明
cmd list(str) ["bash"] 指定容器中执行的默认命令(CMD 指令)
entrypoint list(str) ["/opt/builder/bin/entrypoint", "dumb-init"] 容器的 ENTRYPOINT,含信号转发和用户环境初始化;
这个 ENTRYPOINT 会保证容器启动时的用户拥有合适的环境和家目录(没有这个用户会尝试创建),否则会发出告警
package_pip str dumb-init==1.2.5 安装于最终镜像,用于支持 ENTRYPOINT 的 pip 包
options:
  container_init:
    package_pip: dumb-init>=1.2.5
    entrypoint: ["dumb-init"]
    cmd: ["csh"]
  package_manager_path: /usr/bin/microdnf
  skip_ansible_check: true
  skip_pip_install: false
  relax_passwd_permissions: false
  workdir: /myworkdir
  user: bob
  tags:
    - ee_custom:latest

version 作用

用于标识 execution-environment.yml 文件所使用的配置格式版本,确保 ansible-builder 工具正确解析该文件。

字段名 类型 默认值 说明
version int 1 schema 版本号;使用 ansible-builder 3.x 时,必须设置为 3

执行环境构建流程

  1. 准备好相关执行环境定义文件依赖文件,通过 ansible-builderansible-navigator builder 启动构建,比方说在构建目录执行 ansible-builder build -vvv

  2. ansible-builder 根据已有的配置文件,在构建镜像的工作目录生成 context 目录,目录里包含 Containerfile(或 Dockerfile)、依赖文件和一些构建镜像用的脚本()

    [root@ansible-controller build]# tree context/
    context/
    ├── _build
    │   ├── bindep.txt
    │   ├── configs
    │   │   └── ansible.cfg
    │   ├── requirements.txt
    │   ├── requirements.yml
    │   └── scripts
    │       ├── assemble
    │       ├── check_ansible
    │       ├── check_galaxy
    │       ├── entrypoint
    │       ├── install-from-bindep
    │       ├── introspect.py
    │       └── pip_install
    └── Containerfile
    
    3 directories, 12 files
  3. 整个镜像构建分三个阶段:

    • 第一个阶段:构建一个 BASE 镜像,基础镜像里会把脚本和 entrypoint 拷贝进去并安装 Python 和 pip
    • 第二个阶段:以 BASE 镜像为基础,安装 Ansible Roles 和 Ansible Collections
    • 第三个阶段:以 BASE 镜像为基础,生成最终要安装的 Python 包和系统包的清单
    • 第四个阶段:以 BASE 镜像为基础,将之前安装的 Ansible Roles 和 Ansible Collections 复制进来,安装系统包和 Python 包(包括默认安装和手动设置的),创建需要的目录,并将必要的文件和目录设置好权限,设置容器标签、启动用户和启动命令。
  4. 镜像构建完成后,根据命令参数(--tag)或配置文件的设置(tags:)为镜像打 tag

这个是默认的构建流程,除了默认的流程,还可以通过 additional_build_steps 添加自定义的构建指令。

构建一个执行环境镜像

[root@ansible-controller build]# tree .
.
├── ansible.cfg
├── bindep.txt
├── execution-environment.yml
├── requirements.txt
└── requirements.yml

0 directories, 5 files

[root@ansible-controller build]# cat execution-environment.yml
version: 3

build_arg_defaults:
  ANSIBLE_GALAXY_CLI_COLLECTION_OPTS: "--pre"

images:
  base_image:
    name: registry.access.redhat.com/ubi8/ubi-minimal:8.10-1255

dependencies:
  python_interpreter:
    package_system: python3.12
    python_path: /usr/bin/python3.12
  ansible_core:
    package_pip: ansible-core==2.16.14
  ansible_runner:
    package_pip: ansible-runner
  python: requirements.txt
  system: bindep.txt
  galaxy: requirements.yml

additional_build_files:
- src: ./ansible.cfg
  dest: configs

additional_build_steps:
  append_final:
  - COPY _build/configs/ansible.cfg /etc/ansible/ansible.cfg
  - RUN echo "ADD ansible.cfg to /etc/ansible/!"

options:
  container_init:
    cmd: '["bash"]'
    entrypoint: '["/opt/builder/bin/entrypoint", "dumb-init"]'
    package_pip: dumb-init==1.2.5
  package_manager_path: /usr/bin/microdnf
  relax_passwd_permissions: true
  workdir: /runner
  user: '1000'
  tags:
  - ubi8-ee-py3.12-ansible-core2.16.14:v1

[root@ansible-controller build]# cat bindep.txt
sshpass [platform:rpm]
iputils [platform:rpm]
[root@ansible-controller build]# cat requirements.txt
ansible-lint
requests
six
psutil
[root@ansible-controller build]# cat requirements.yml
collections:
- name: ansible.posix
  version: '<=1.6.2'
- name: ansible.utils
  version: '<=5.1.0'
- name: community.crypto
- name: community.dns
- name: community.docker
- name: community.general
- name: containers.podman
- name: cloud.common

roles:
- name: geerlingguy.repo-epel
  version: '3.1.1'

[root@ansible-controller build]# ansible-builder build -vvv \
    --tag ubi8-ee-py3.12-ansible-core2.16.14:v2

这里有两个地方设置了 tag,一个是 execution-environment.yml 里的 options 设置的,另一个是命令的 --tag 选项设置的,命令优先级最高,上边的构建完成后只会有 ubi8-ee-py3.12-ansible-core2.16.14:v2 这一个,没有 ubi8-ee-py3.12-ansible-core2.16.14:v1

Ansible 执行环境镜像构建
https://www.linuxstudynotes.com/2025/06/16/ansible/ansible-%e6%89%a7%e8%a1%8c%e7%8e%af%e5%a2%83%e9%95%9c%e5%83%8f%e6%9e%84%e5%bb%ba/
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇