Ansible+DockerfileによるDockerイメージの作成
Dockerイメージの作成にAnsibleを使いたい場合、Packerを使う方法がよく知られています。
Packer の provisioners に Ansible を指定して Docker イメージを作成する - Qiita
ただ、Packerの売りは、Amazon EC2、VirtualBox、Dockerなどの各種VM用イメージを単一のソースから作れる点だと理解しているので、Dockerイメージだけ作成できれば十分な場合は、もっとシンプルな方法で良いのではないかと思います。
また別の方法として、コンテナを立てる → 立てたコンテナに対してAnsibleを実行する → コンテナをイメージ化する、という方法もあります。これは導入の楽な方法だと思いますが、Ansible実行のためのSSHサーバが大抵必要になります。この記事にもある通り、SSHサーバには鍵の管理やセキュリティアップグレードに関する問題が付いて回るため、SSHサーバなしで済むなら、そうしたいところです。
このような場合、Ansible公式のDockerイメージを使うと、単純かつSSHサーバが不要な形で、AnsibleをつかったDockerイメージの作成ができます。ビルドするイメージ自身にAnsibleを実行させるという点では、Packerに近い方法です。このエントリでは、この公式イメージの使い方を紹介します。
Ansible公式のDockerイメージの使い方
1. 公式イメージを選ぶ
公式イメージには、Ansibleと、自分自身をAnsibleの設定対象ホストにする設定が入っています。
公式イメージはDockerHubにあり、ansible/ubuntu14.04-ansible
レポジトリとansible/centos7-ansible
レポジトリが用意されています。
ansible/ubuntu14.04-ansible Repository | Docker Hub Registry - Repositories of Docker Images
ansible/centos7-ansible Repository | Docker Hub Registry - Repositories of Docker Images
ansible/ubuntu14.04-ansible
レポジトリには次のタグが用意されています。ansible/centos7-ansible
レポジトリもほぼ同じです。
- latest(develと同じ)
- 1.7
- 1.8
- devel(Githubにある開発版のAnsible)
- stable(最新のリリース版のAnsible)
1.7、1.8タグのイメージには、それぞれバージョン1.7、バージョン1.8のAnsibleが入っているはずですが、現状そうなっていないようです。pullしてみると、1.7の中にはバージョン1.8.2のAnsible、1.8の中には開発版のAnsibleが入っていました。修正されるまでは、1.7、1.8タグのイメージの使用はやめておいたほうが良いかもしれません。
使用したいレポジトリとタグを決めたら、docker pullします。
2. Ansibleを実行するDockerfileの作成
1で選んだイメージをベースイメージにして、Ansibleを実行するDockerfileを作成します。例えば次のような感じです。
ansible-docker-base/Dockerfile at master · ansible/ansible-docker-base · GitHub
FROM ansible/centos7-ansible:stable # or, for example, FROM ansible/ubuntu14.04-ansible:stable # Add playbooks to the Docker image ADD ansible /srv/example/ WORKDIR /srv/example # Run Ansible to configure the Docker image RUN ansible-playbook site.yml -c local # Other Dockerfile directives are still valid EXPOSE 22 3000 80 ENTRYPOINT ["/usr/local/bin/apachectl", "-DFOREGROUND"]
ほぼ通常どおりの方法でAnsibleを実行できますが、以下の点が違っています。
inventoryを与える必要はありません。公式イメージの中で、localhostがAnsibleの設定対象ホストとして既に設定されているためです。あえてinventoryを与えたい場合は、いつもどおり
-i
オプションで与えれば、そちらが優先されます。-c local
オプションを付けます。AnsibleはデフォルトだとSSH(場合によってはparamiko)で設定対象ホストに接続しますが、今回は自分自身に対して設定するので、SSHは不要です。-c local
オプションを付けると、Ansibleを実行したホスト上で直接モジュールの実行等をします。Playbookのhostsの値には、localhostを設定します。これも、公式イメージの中でlocalhostが設定対象ホストとして設定されているためです。上記のDockerfile内で扱っているPlaybookは、次のURLから参照できます。
ansible-docker-base/site.yml at master · ansible/ansible-docker-base · GitHub
作成したDockerfileをdocker buildすれば、イメージが作成できます。
使ってみた感想
この方法を使ってみて良いと感じた点は以下です。
導入が簡単です。Packerを入れる必要もないし、Packerの設定ファイルの書き方を覚える必要もないです。
EXPOSE、VOLUMEなどの命令を使って、リッスンするポート、マウントポイントなどのメタ情報をDockerイメージ内に入れ込めます。Packerのドキュメントを見る限り、現状のPackerにはそのような機能はなさそうです。
一方で、今一つと感じた点もあります。
Dockerイメージ内にAnsibleが入ってしまいます。Ansibleの良さとして、設定対象サーバに構成管理ツールを入れなくていいという点がありますが、この良さは失われてしまいます。
上述の通り、Ansible公式のDockerイメージだと、バージョン指定が今のところできません。バージョン指定をしたい場合の次善策として、公式イメージを使わず、指定したバージョンのAnsibleをインストールするDockerfileを自分で書く、という手もあります。ごく単純ですが、例えば次のような感じです。
FROM ubuntu:14.04 MAINTAINER YOUR_NAME_AND_EMAIL RUN apt-get -y update && \ apt-get install -y python-yaml python-jinja2 python-paramiko python-pip RUN mkdir /etc/ansible/ && \ echo '[local]\nlocalhost\n' > /etc/ansible/hosts RUN pip install ansible==1.8.2
Ansible公式イメージのDockerfileは次のURLにあるので、こちらを修正することもできます。
ansible/ansible-docker-base · GitHub
まとめ
AnsibleをつかったDockerイメージの作成方法として、Ansible公式のDockerイメージを使う方法を紹介しました。当たり前の方法のような気もしますが、DockerHubの公式イメージのダウンロード数を見ると、意外と使われていないようだったので、紹介してみました。