zaki work log

作業ログやら生活ログやらなんやら

[Ansible Builder v3] execution environment definitionのversion 3 formatでAlmaLinuxをベースにビルドお試し

Ansible Builderのバージョンが3になり、execution-environment.ymlのフォーマットもver3が使えるようになったのでお試し。
RHEL系の任意のイメージをベースに使えるようになったので、試しにAlmaLinux 9のminimal版をベースにすることで、イメージサイズの軽量化もできた。

Ansible Builder ver3のインストール

従来通りpipでインストールする。

pip install ansible-builder

ただしAnsible Builder 3.0のインストールはPython 3.9以上が必要。
Pythonが古いとインストールできないので注意。
例えばPython 3.8.10の環境だと、pip install ansible-builderでインストールされるのは1.2.0になる。

イメージのビルド

execution environment definition file (version 3 format)

version 3フォーマットになって記載方法が拡張されている。
詳細は公式ドキュメント参照。

ansible.readthedocs.io

わかりやすい変更点(個人の感想)としては以下がある。

  1. Ansible Core / Ansible Runnerのインストールから記述可能
  2. パッケージ類の記述をインラインで記述可能
  3. prepend_baseでビルド時のパッケージインストール前の処理を記述可能

Ansible Coreのインストールの定義によって、ベースイメージに指定できるイメージはAnsible Runner用のイメージである必要がなくなった(ざっと試した限りRHEL互換であれば大丈夫)。よって、Rocky LinuxやAlmaLinuxのようなイメージを元にビルドすることもできるようになった。
また、以前はadditional_build_steps.prependにインストールしたいパッケージ類とは別に個別の処理を記載できたが、処理順的に「パッケージリポジトリの追加」を書いてもbindepの処理の後になってしまう制限があったが、新しく追加されたadditional_build_steps.prepend_baseではbindep前に処理されるため、より柔軟なビルド定義ができるようになった。

ということで例としてAlmaLinux 9(minimal)をベースにKubernetes系の処理をするためのEEをビルドする定義ファイル。
minimalをベースにして最小のパッケージ類のみでビルドすると、イメージのサイズは400MB弱まで小さくなった。

---
version: 3

dependencies:
  ansible_core:
    package_pip: ansible-core==2.15.2
  ansible_runner:
    package_pip: ansible-runner
  galaxy:
    collections:
      - name: kubernetes.core
        version: 2.4.0
      - community.general
  python:
    - six
    - psutil
    - kubernetes>=12.0.0
    - jsonpath
  system:
    - git
    - kubectl

images:
  base_image:
    name: docker.io/library/almalinux:9-minimal

options:
  package_manager_path: /usr/bin/microdnf

additional_build_files:
  - src: ansible.cfg
    dest: configs

additional_build_steps:
  prepend_galaxy:
    - ADD _build/configs/ansible.cfg ~/.ansible.cfg

  prepend_base: |
    RUN microdnf install python3 -y   # for alma/rocky minimal
    RUN echo -e "[kubernetes]\n\
    name=Kubernetes\n\
    baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch\n\
    enabled=1\n\
    gpgcheck=1\n\
    gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg" > /etc/yum.repos.d/kubernetes.repo

カスタマイズポイント

minimal系ベースイメージの場合のポイント

almalinux:minimalrockylinux:9-minimalをベースにする際のポイントは以下

dnfが入っていない

かわりに軽量版のmicrodnfを使用してパッケージ管理をする構成になっているので、パッケージマネージャでそれを指定する。

options:
  package_manager_path: /usr/bin/microdnf

pythonが入っていない

minimal系イメージはPythonが入っておらずそのままではpip installもできないため追加でインストールを行う。その場合dependencies.systemでは処理が遅すぎるため、additional_build_steps.prepend_baseの方にRUNで記述する。

  prepend_base: |
    RUN microdnf install python3 -y

Ansible Core + 必要最小限のコレクションでなくAnsibleを丸ごと入れる

上の例でdependencies.ansible_core.package_pipに指定しているansible-core==2.15.2の部分にansible==8.2.0のように記述すればOK

dependencies:
  ansible_core:
    package_pip: ansible==8.2.0

この場合ビルドできたイメージサイズは700MB強程度になった。(それでもformat1のときは1GB超えだったけど)

パッケージ類を以前と同様に外部ファイル定義

運用でexecution-environment.ymlは固定で、EEを使いたい人なり組織が自分たち用のパッケージ定義だけをしてビルドする、みたいな使い方なら外部ファイルが都合が良いかも。
その場合は旧バージョンと同様に記載内容でOK

dependencies:
  python: requirements.txt
  system: bindep.txt
  galaxy: requirements.yml

環境

Builderの関連エントリは以下

zaki-hmkc.hatenablog.com

zaki-hmkc.hatenablog.com


ヒアドキュメントはやっぱり使えないかぁ。これで合ってるよね?

  prepend_base: |
   COPY <<EOF /etc/yum.repos.d/kubernetes.repo
     [kubernetes]
     name=Kubernetes
     baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch
     enabled=1
     gpgcheck=1
     gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
   EOF