概要
コンテナイメージをPodman(ポストDocker?)とAnsible Benderを使って、Dockerfileを使わずに作る方法について記載。
Podmanに関しては事前知識、設定など使えるようになるまでに幾つかのハマりどころがあったので、本題とは異なる内容(ただし知っていたほうが良さそうなこと)もそれなりに書いている。
記事の背景
二年ほど前から、興味半分でDockerとAnsibleを使ってコンテナを作り始めた。我流なのでもっと良い方法はあると思うが、以下のような感じでコンテナ構築を行うことが多かった。
- (1) Dockerfileに以下の内容を記載
- Ansibleをインストール
- AnsibleのPlaybook関連ファイル一式をコンテナにコピー
-
ansible-playbook
のコマンドを書いてイメージ構築 - コンテナ起動時に実行するエントリーポイントのシェルスクリプト(
entrypoint.sh
などの名前のファイル)をコンテナにコピー
- (2) Dockerイメージの作成
-
docker build ...
を実行
-
- (3) Dockerコンテナを起動
-
docker run ...
を実行 - エントリーポイントのシェルスクリプトの中で、
ansible-playbook
を実行
-
ソースコードで表現するとおおよそ以下のイメージ。
(正確さに欠けるのはお許しを)
- Dockerイメージ作成時のソース
FROM ubuntu
# Ansibleをインストール
RUN apt -y update && \
apt -y install ansible
# AnsibleのPlaybook関連ファイル一式をコンテナにコピー
ADD ./playbook /
# ansible-playbookのコマンドを書いてイメージ構築
WORKDIR playbook
RUN ansible-playbook setup.yml
# エントリーポイントのシェルスクリプトをコンテナにコピー
WORKDIR /
ADD ./entrypoint.sh /
- コンテナ起動時のソース
# !/bin/bash
cd playbook
ansible-playbook entrypoint.yml
ソースを見るとおわかりの通り、ほとんどAnsibleに関するコマンドしか実行していない。Dockerfileとエントリーポイント用シェルスクリプトentrypoint.sh
は、Dockerコンテナを作るために不可避なファイルで(言い方は悪いが)仕方なく使っているようにだんだん思えてきた。そして「Dockerfileもエントリーポイント用シェルスクリプトも使わずに、全てAnsibleだけでDockerコンテナを作れたらいいのに」という気持ちが強まってきていた。
Ansible Containerでのつまづき
そんな思いの中、Ansibleに関する書籍を読んでいたところ、「Ansible ContainerでPlaybookのみでコンテナを作成可能」であることを偶然知る。「これこそ探していたツール。早速使ってみよう!」と思ってググりながらセットアップ開始。
ツールが使えるようになるまで2度3度ハマり、ようやく「ansible-container build
」コマンドでDockerイメージを作れる状態にまで持ってこれた。(Ansible Containerのセットアップ方法を書くとかなり脱線してしまうのでここでは割愛)
が、実際にイメージをビルドしようとすると、一通りPlaybookを実行し終えた後、最後の方で下記のようなエラーが出てきてイメージが作成されない…。
docker.errors.APIError: 400 Client Error: Bad Request ("file with no instructions.")
これに関して調査すると、海外のQAサイトで「Ansible Containerは非推奨になったみたいだよ」というコメントを見つける。日本語サイトでも下記のような関連記事があり、代わりに「Ansible Bender」を使うほうが良さそうだと判明。
- Ansibleを使ってdockerコンテナを立ち上げる
前置きが長くなったが、このような経緯を踏まえて、Ansible Benderを使えるようにする手順を以下に示す。
手順
- 主に参考にしたサイトは下記のAnsible Benderの公式サイト
公式サイトにも書かれているように、Ansible Benderを動かすためにはPodmanとBuildahが必要になる。そこで、まずはPodmanとBuildahのインストール方法とやっておいた方が良い設定について記載する。Ansible Benderのインストール方法が出てくるのは本節の最後になるが、しばしお付き合いいただきたい。
(1) Podmanのインストール
Ansible Benderが利用するのはDockerではなく、Podmanと呼ばれる新たなコンテナ構築ツール。PodmanはDockerとほぼ同じ使い方ができて、デーモンレス(サービス起動が不要)かつルートレス(ルート権限が不要)でイメージやコンテナが構築できる。
以下サイトにディストリビューション毎のインストール方法が書かれおり、記載内容に従えばインストール可能。
- Podman Installation Instructions
(2) Buildahのインストール
BuildahもPodmanと同様に、デーモンレスでコンテナイメージを作成できるツール。(詳細をまだ理解できていないので、必要に応じて追記予定)
インストール方法は下記サイトに記載。
- GitHubのBuildahのリポジトリ
(3) Podmanに関する設定
ユーザIDマッピングの設定
Podman(およびAnsible Bender)をユーザ権限でルートレスで使いたい場合は、以下のような「UID mapping」と呼ばれる設定が必要。
$ sudo sh -c "printf \"\n$(whoami):100000:65536\n\" >>/etc/subuid"
この設定を行うと、例えばPodmanコンテナ内の「rootのユーザID=0」はホストOS(コンテナ外)では100000プラスされて、「コンテナのrootユーザーID=100000」にマッピングされる。したがって、ホストOSのroot権限を持っていなくてもコンテナ操作ができる。
Podmanイメージがストレージを大量に使ってしまう問題への対処
Podmanのイメージやコンテナは、ホームディレクトリの~/.local/share/containers/storage/
以下に格納される。デフォルトだと、イメージを作り直す度にイメージのファイル一式が(差分ではなく素のままで)追加されていき、ストレージを大量に使ってしまう問題がある。(筆者の環境でも、最初はイメージをビルドする度にストレージの残りがどんどん減っていったので焦った…)
この問題を解決するため、ルートレスコンテナ向けのストレージドライバであるFUSE-OverlayFSをインストールして、Podmanの設定ファイルに反映する。
FUSE-OverlayFSは下記サイトからインストール可能
- GitHubのfuse-overlayfsのリポジトリ
上記サイトREADMEで最後の方に記載された下記コマンドで、fuse-overlayfsのバイナリファイルができる。
$ buildah bud -v $PWD:/build/fuse-overlayfs -t fuse-overlayfs -f ./Dockerfile.static.ubuntu .
インストール後、~/.config/containers/storage.conf
に以下を記載すればOK。以後はストレージが食いつぶされることは無くなるはず。
[storage]
driver = "overlay"
[storage.options]
mount_program = "/usr/bin/fuse-overlayfs"
- この問題に関する参考サイト
(4) AnsibleおよびAnsible Benderのインストール
(ようやく本題のAnsible Benderのインストール方法の説明ができる。)
前提として、Ansible BenderはPython3.6以上でないと動かない。そこでまずはAnsibleのコントロールノードにPython3.6以上をインストールする必要あり。
続いて、バージョンが3.6以上のPython環境(仮想環境でも非仮想環境でもいい)にAnsibleとAnsible Benderをpip(3)コマンドでイントールする。
$ pip3 install ansible
$ pip3 install ansible-bender
上の例では、Ansibleをpip3のコマンドでインストールしているが、既にインストールしているAnsibleを使いたい場合は、Playbookのymlファイル(後ほど作成)を格納するディレクトリにansible.cfg
を作り、次のような設定を追記すればAnsibleがPython3を参照するようになるはず。
[defaults]
# python3のバイナリが格納されたパスを追加
interpreter_python=/usr/bin/python3
これで、Ansible Benderを使う準備が整った
動作サンプル
とりあえずは適当に空のディレクトリを作って
$ ansible-bender init
と入力すると、雛形のファイルplaybook.yml
ができる。
これ以下のように編集すると、CentOS7ベースのhttpdコンテナイメージが作れる。
---
- name: Containerized version of httpd
hosts: all
vars:
ansible_bender:
base_image: centos:7
target_image:
cmd: /usr/sbin/httpd -D FOREGROUND
name: httpd
tasks:
- name: install dependencies needed to run project httpd
yum:
name: httpd
state: present
ポイントは、playbookのvarsセクションの変数ansible_bender
。ここに、作成するコンテナに関する情報を書く。ansible_bender
配下で使用可能な変数一覧は下記に記載されている。
- Anible BenderサイトのConfiguration
上記のplaybookを下記のようにビルドして、Podmanイメージを作成
$ ansible-bender build playbook.yml
22:46:53.683 utils.py ERROR Getting image source signatures
22:46:54.479 utils.py ERROR Copying blob sha256:75f8…
(筆者の環境では幾つかエラーメッセージが出るが、原因は未解明)
PLAY [Containerized version of httpd] ******************************************
TASK [Gathering Facts] *********************************************************
ok: [httpd-20200814-224645662649-cont]
TASK [install dependencies needed to run project httpd] ************************
changed: [httpd-20200814-224645662649-cont]
PLAY RECAP *********************************************************************
httpd-20200814-224645662649-cont : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Getting image source signatures
Copying blob sha256:613b…
Copying blob sha256:7d45…
Copying config sha256:e05f…
Writing manifest to image destination
Storing signatures
e05f…
Image 'httpd' was built successfully \o/
httpdのイメージが出来ていることを確認
$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/httpd latest e05f33470bcd 11 minutes ago 332 MB
コンテナを起動
$ podman run --name httpd -p 10080:80 -dit httpd
http://localhost:10080/ でApacheのテストページが表示されることを確認。
未解決の問題
イメージを作成する際にDockerfileをAnsible Playbookで書けるようにはなった!
が、コンテナ起動時のエントリーポイントコマンドをターゲットノードからAnsibleで実行する方法はまだわかっていないので、引き続き調査予定。