Ansible Docker Connection Pluginを使う¶
1年以上前の2014年4月にこんな記事を書きました docker containerに対して直接ansibleを実行する それからいろいろあって、Ansible 2.0では標準でDocker Connection Pluginが入っています。(といってもぼくの実装ではありませんが)
Docker Connection Pluginとは¶
まず、 Connection Plugin について説明します。Ansibleでは通常SSHを使って対象となるホストに接続します。 しかし、 Connection Plugin を使うことで、接続方式を切り替えることができます。
代表的なものは local connection です。以下のように書くと、sshではなく、localhostでそのまま実行されます。sshのlocalhostと異なる点は、sshはまったく使わずに、そのままのユーザーがのまま実行する、という点です。開発時に便利ですね。
- hosts: all
connection: local
tasks:
- file: path=/tmp/this_is_local state=directory
その他、以下のconnection pluginが用意されています。paramikoやwinrmは使ったことがある方も多いかと思います。
- accelerate
accelaretモード(過去の遺産なので覚える必要なし)
- chroot
chroot
- funcd
Func: Fedora Unified Network Controller 経由
- zone
SolarisのZone
- jail
FreeBSDのJail
- libvirt_lxc
virtのLXC
- paramiko
sshのpython実装
- winrm
Windows
この中の一つがdocker connection pluginです。
Docker connection pluginの利点¶
Docker Connection Pluginを使うことで、Dockerコンテナに対して直接Ansibleを実行できます。 具体的には docker exec でコマンド実行を、ファイルのコピーは docker cp を実行します。 Dockerコンテナの中にsshdを建てる必要はありません。
DockerfileによるBuildが一番シンプルであることは確かです。しかし、
Layerを増やさないために \ で何行も増やしていく場合がある
templateがないため、複数種類のimageを作り分けるのがめんどう
他はAnsibleで管理しているのに、ここだけDockerfileになると管理が分断されてしまう
などの理由で、Ansibleを使いたくなる場合がありますので、そういう場合に有用です。
なお、私はDockerfileで済ませられるのであればその方が良いと思います。Ansibleをわざわざ使う必要はないでしょう。しかし、複雑な構成になってくると、Ansibleの方が便利な場合もあると考えられるため、ここで紹介している次第です。
Docker connection pluginを使う¶
能書きはこのあたりにして、早速使ってみましょう。ほとんどの人はAnsible 2.0RC1を使っていると思いますので、新たなインストールは必要ないですが、万が一 1.9.4を使っている人は こちら から docker.py をダウンロードし、 connection_plugins というディレクトリを作成してその中に置きましょう。以下のような構成になります。
.
|-- connection_plugins
| `-- docker.py
|-- hosts
`-- site.yml
また、 pipで docker-py をインストールしておきましょう。(ansible v2.0では必要ないです)
あとは以下のようにplaybookを書きます。
- name: Dockerコンテナを起動
hosts: localhost
connection: local
vars:
base_image: ubuntu:latest
docker_hostname: test
tasks:
- name: Dockerコンテナを起動
local_action: docker image={{ base_image }} name={{ docker_hostname }} detach=yes tty=yes command=bash
- name: ホストを追加
add_host: name={{ docker_hostname }}
- name: Dockerコンテナ内を構成
hosts: test
connection: docker # ここで docker connectionを指定
tasks: # 好きなように書きます
- file: path=/tmp/docker state=directory
- file: path=/tmp/ansible state=directory
- group: name=admin state=present
- user: name=johnd comment="John Doe" uid=1040 group=admin
- copy: src=site.yml dest=/tmp/ansible/
post_tasks:
- local_action: shell /usr/local/bin/docker commit {{ inventory_hostname }} ubuntu:ansible
この例のplaybookは以下の二つから構成されています。
Dockerコンテナを起動
起動したDockerコンテナ内部を構成管理
1の方では、dockerモジュールを使って起動します。ここは普通にlocal接続です。2の方がDocker接続を使用しています。
重要なのは、 connection: docker という行だけが異なっており、そのほかは通常のPlaybookと何ら変わりないという点です。
最後に dokcer commit を実行して、イメージとして保存しています。それまでの箇所はすべて docker execなどで行われているため、保存されず、layerは全体で最後に docker commit を実行した時に出来る一つだけとなります。これにより、Dockerfileで何行も続けたり、ということをしなくてすみます。
commitも自動化¶
先ほどの例では post_tasks として、 docker commit を実行しています。しかし、 Ansible を使って Docker コンテナーをプロビジョニングする という記事では、callback pluginを使って毎回のtask実行毎にcommitをする例を示しています。
この方式はDockerfileによる方式と同じくlayerがたくさんできることになります。その代わり、キャッシュされるため、次回は高速になるという利点もあります。
RemoteのDockerホストを使う¶
Dockerホストは手元だけでなく、リモートでも構いません。
export DOCKER_HOST=tcp://192.168.0.10:4243
と DOCKER_HOST を環境変数で設定すれば、そのホストを経由してDockerコンテナにアクセスします。 試していませんが、Swarmなどでもきちんと動くと思います。
これで、
インスタンス起動などのクラウドサービスの利用
dockerホスト自体の構築
dockerコンテナ/イメージの構築
ELBの付け外しなど、デプロイに必要な機能
のすべてがAnsibleで可能となります。
まとめ¶
この記事ではAnsibleからDockerコンテナを直接触れる Docker Connection Pluginを紹介しました。一つのpythonファイルを置くだけで、Dockerコンテナにたいして通常のsshホストと同じことができるようになります。また、Dockerホストはローカルだけでなく、リモートに対しても可能です。
最後に。
最初の方に述べましたが、Dockerfileで済ませられるのであればその方が良いでしょう。なんでもAnsibleでやりたくなる気持ちも分かりますが、Ansibleを使わなくてはならない理由はありません。適材適所、不要な苦労をしないために、もう一度考えましょう。
そして、そもそもDockerコンテナ内部が複雑な時点で間違っていると思います。 golangをDockerでデプロイする で示したように、golangであれば、1バイナリだけ置けば動くため、「プロビジョニング」なんてものは存在しなくなります。現在はGoogleに転職したIanさんも (より)小さいDockerイメージを作ろう という記事を書いており、必要な最小限のファイルだけ置くのが理想です。
自動化をするまえに、「そもそも本当に必要なのか?」を考えましょう。
Comments
comments powered by Disqus