前回に引き続き、今回もAnsibleをコンテナを使って実行する「Ansible Navigator」について取り上げます。
今回は「Ansible Builder」を使ってコンテナイメージをカスタマイズして、「Ansible Navigator」でそのイメージを使ってAnsibleを実行してみたり、作成したイメージの中を覗いてみたりしようと思います。
今回も、次のブログ記事をベースにしています(ちょっとだけ味付けを変えています)。
Ansible Builderのインストール
RHELはdnf、RHEL以外やFedoraではpipを使ってインストールしますが、pipでインストールする場合はansible-navigator
をインストールした時点で依存パッケージとしてインストールされているようです。もしインストールされていない場合は次のように実行します。
$ sudo dnf install python3-pip $ pip3 install --user ansible-builder
参考記事はDockerを使っているようですが、本記事ではコンテナランタイムは今回もPodmanを使います。インストールされていない場合はインストールします。
$ sudo dnf install podman
また、最後にAnsible Navigatorも実行しますので、インストールされていない場合は前回記事のようにインストールしてください。
イメージ作成に必要なファイルを作成
参考記事に従ってイメージ作成のための各ファイルを作っていきますが、custom_ee.yml
のベースイメージのバージョン部分を書き換えました。これは以前の記事で利用していたバージョンと一緒のものを指定しています。
$ cat custom_ee.yml version: 1 build_arg_defaults: ANSIBLE_GALAXY_CLI_COLLECTION_OPTS: '-v' EE_BASE_IMAGE: 'quay.io/ansible/ansible-runner:stable-2.12-devel' //書き換えた部分 ansible_config: 'ansible.cfg' dependencies: galaxy: requirements.yml python: requirements.txt system: bindep.txt additional_build_steps: prepend: | RUN whoami RUN cat /etc/os-release append: - RUN echo This is a post-install command! - RUN ls -la /etc
その他のファイルは参考記事と一緒です。
$ tree . ├── ansible.cfg ├── bindep.txt ├── custom_ee.yml ├── requirements.txt └── requirements.yml
イメージのビルド
次のようなコマンドでイメージを作成します。
$ ansible-builder build -f custom_ee.yml -t custom_ee:2.12 Running command: podman build -f context/Containerfile -t custom_ee:2.12 context Complete! The build context can be found at: /home/fedora/ansiblebuild/context
イメージ作成には結構時間がかかるので、状況はps aux|grep ansible-builder
を実行してPIDを確認し、strace -p PID
などを実行して現在、何を実行しているかを把握してください。
イメージができているのを確認します。
$ podman image ls REPOSITORY TAG IMAGE ID CREATED SIZE localhost/custom_ee 2.12 69b32027df57 23 seconds ago 1.03 GB <none> <none> afb36bc0a5e4 4 minutes ago 1.03 GB <none> <none> 3ec155571a57 6 minutes ago 834 MB quay.io/ansible/ansible-runner stable-2.12-devel 70252e151bfc 4 months ago 816 MB quay.io/ansible/ansible-builder latest b0348faa7f41 6 months ago 779 MB
作成したファイルを元にcontext/Containerfileが作成されています。
$ tree . ├── ansible.cfg ├── bindep.txt ├── context │ ├── _build │ │ ├── ansible.cfg │ │ ├── bindep.txt │ │ ├── requirements.txt │ │ └── requirements.yml │ └── Containerfile ├── custom_ee.yml ├── requirements.txt └── requirements.yml 2 directories, 10 files
Containerfileの中身は色々なコンテキストファイルを元として、希望したイメージを作成するための設定が書かれたファイルが生成されます。これを使ってイメージが作成されます。
今回はEE_BASE_IMAGE
で指定したイメージをカスタマイズする例です。
ちなみにここで指定されているイメージquay.io/ansible/ansible-runner:stable-2.12-devel
の中身は、CentOS Stream 8が使われていました。
$ cat context/Containerfile ARG EE_BASE_IMAGE=quay.io/ansible/ansible-runner:stable-2.12-devel ARG EE_BUILDER_IMAGE=quay.io/ansible/ansible-builder:latest FROM $EE_BASE_IMAGE as galaxy ARG ANSIBLE_GALAXY_CLI_COLLECTION_OPTS=-v USER root ADD _build/ansible.cfg ~/.ansible.cfg ADD _build /build WORKDIR /build RUN ansible-galaxy role install -r requirements.yml --roles-path "/usr/share/ansible/roles" RUN ANSIBLE_GALAXY_DISABLE_GPG_VERIFY=1 ansible-galaxy collection install $ANSIBLE_GALAXY_CLI_COLLECTION_OPTS -r requirements.yml --collections-path "/usr/share/ansible/collections" FROM $EE_BUILDER_IMAGE as builder COPY --from=galaxy /usr/share/ansible /usr/share/ansible ADD _build/requirements.txt requirements.txt ADD _build/bindep.txt bindep.txt RUN ansible-builder introspect --sanitize --user-pip=requirements.txt --user-bindep=bindep.txt --write-bindep=/tmp/src/bindep.txt --write-pip=/tmp/src/requirements.txt RUN assemble FROM $EE_BASE_IMAGE USER root RUN whoami RUN cat /etc/os-release COPY --from=galaxy /usr/share/ansible /usr/share/ansible COPY --from=builder /output/ /output/ RUN /output/install-from-bindep && rm -rf /output/wheels RUN echo This is a post-install command! RUN ls -la /etc
作成したイメージを使ってPlaybookを実行
作成したイメージを使って、Playbookを実行してみます。 当然ながら問題なく動きました。
$ cd ansiblenavi $ ansible-navigator run --eei custom_ee:2.12 playbook/test.yml -i inventory/hosts -vv ansible-playbook [core 2.12.5.post0] config file = None configured module search path = ['/home/runner/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /usr/local/lib/python3.8/site-packages/ansible ansible collection location = /home/runner/.ansible/collections:/usr/share/ansible/collections executable location = /usr/local/bin/ansible-playbook python version = 3.8.13 (default, Jun 24 2022, 15:27:57) [GCC 8.5.0 20210514 (Red Hat 8.5.0-13)] jinja version = 2.11.3 libyaml = True No config file found; using defaults Skipping callback 'awx_display', as we already have a stdout callback. Skipping callback 'default', as we already have a stdout callback. Skipping callback 'minimal', as we already have a stdout callback. Skipping callback 'oneline', as we already have a stdout callback. PLAYBOOK: test.yml ************************************************************* 1 plays in /home/fedora/ansiblenavi/playbook/test.yml PLAY [all] ********************************************************************* META: ran handlers TASK [ping] ******************************************************************** task path: /home/fedora/ansiblenavi/playbook/test.yml:6 ok: [172.16.214.188] => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"}, "changed": false, "ping": "pong"} META: ran handlers META: ran handlers PLAY RECAP ********************************************************************* 172.16.214.188 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
イメージのデバッグ
作成したイメージを確認してみましょう。Podmanでカスタムイメージを使ってコンテナーを作成し、シェルに入ってみます。 コマンドを実行すると、それぞれセットアップ済みであることがわかります。
//カスタムイメージを使ってコンテナを実行 $ podman container run -it localhost/custom_ee:2.12 bash //rpmパッケージの確認 bash-4.4# rpm -q krb5-devel krb5-devel-1.18.2-21.el8.x86_64 //Pythonモジュールの確認 bash-4.4# pip list | egrep "awxkit" awxkit 21.5.0 //ansible-galaxy collectionの確認 bash-4.4# ansible-galaxy collection list Collection Version ----------------- ------- ansible.posix 1.4.0 awx.awx 21.5.0 community.general 5.5.0
基本的にはベースイメージを使ってAnsibleのジョブをコンテナーを使って実行すればよいですが、繰り返し作業するようなジョブの場合は、事前に必要なコンポーネントを組み込んでイメージ化しておいたほうが、実行ごとにイメージをビルドするより効率的でしょう。
何度も繰り返し作業するような場合にAnsible Builderが必要になってくると思います。