世の中、猫も杓子もAnsibleなので、そろそろ勉強をしないとまずい…ということで、重い腰を上げてAnsibleをしてみました。
とはいえ、自宅環境はサーバ1台のみなので、今回はDockerでWordpressコンテナを立ち上げることを最終目標にしていきます。
環境はこんな感じです。
# python3.6 -V
Python 3.6.2
# pip3.6 -V
pip 9.0.1 from /usr/local/python362/lib/python3.6/site-packages (python 3.6)
# cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)
# docker -v
Docker version 17.03.1-ce, build c6d412e
執筆時点でAnsible歴二日くらいなので、間違いがあったらご指摘頂けますと幸いです。
Ansibleとは
先生曰く、「Ansible is a radically simple IT automation engine that automates cloud provisioning, configuration management, application deployment, intra-service orchestration, and many other IT needs.」だそうです。
ITにまつわる色々な作業をシンプルに自動化するエンジン、とのことですが、wikiには構成管理ツールって書いてありました。
習うより慣れろ、ということで、実践します。
Ansibleの準備
pipします。dockerも入れます。
# pip3.6 install ansible docker
(略)
# ansible --version
ansible 2.4.0.0
ファイル置き場の作成
ファイル置き場については、Ansibleのページにベストプラクティスとかありますが、これは自宅程度の規模ではやりすぎだろう…ということで取りあえず
# mkdir -p /labo/ansible/inventory
# mkdir /labo/ansible/playbook
という感じで作りました。
inventoryを作る
Ansibleを実行するにあたり、どのシステムを対象とするのか、その対象をまとめたものがinventoryファイルとなります。
ファイルはINI形式を模したものとなっており、書き方は(作りこまなければ)シンプルです。
[mother]
localhost
[containers]
wordpress
尚、[]の部分はグループとなります。グループ名で指定した場合、そのグループ配下のすべてのシステムが対象となります。
グループに所属しないシステムも書けますが、何となくlocalhostもグループに入れました。
playbookを作る
Ansibleに自動で構成とかを色々させるにはplaybook(=脚本)が必要になります。
playbookにああしようこうしようという手順を書いたら、それをAnsibleが実行してくれるイメージです。
では、wordpressをコンテナで起動すべく、まず軽く書いてみます。YAMLです。
wordpress:latestのイメージをpullしてきて、docker container run -d --name=wordpress --hostname=wordpress --rm wordpress:latest
を実行する、というのをplaybookで表現すると以下です。
1 - name: Wordpress Container Maker
2 hosts: localhost
3 connection: local
4
5 vars:
6 hostname: wordpress
7
8 tasks:
9 - name: Create a wordpress container
10 docker_container:
11 name: wordpress
12 hostname: "{{ hostname }}"
13 image: wordpress:latest
14 detach: yes
15 auto_remove: yes
上記の1~3行目がTarget Sectionと呼ばれるもので、実行対象のホストなどを指定するセクションです。
- 1 [name] 後から見てわかりやすいコメントを記載してます。
- 2 [hosts] タスク実行対象です。コンテナを起動するのはlocalhostに対してなので、そのように記載しています。
- 3 [connection] localとすることで、ssh接続をせずにlocalhostに接続します。
上記5~6がVariable Sectionです。
ここでは、変数を設定することができます。変数の書き方はTask Sectionで。
- 6 [hostname] Task Sectionでコンテナのホスト名を指定するのですが、これが後々変わる可能性もありますので、変数化しておきます。
上記の8~最終行がTask Sectionと呼ばれるものでAnsibleが実行するタスクを記載していきます。
タスクというのは、モジュールとそれに対する引数で構成されます。モジュールとは、ある処理をするための機能を提供するもの(スクリプト)です。
- 8 [tasks] Task Sectionの始まりの部分です。
- 9 [name] コメントのようなものです。
- 10 [docker_container] このモジュールを使うことにより、コンテナの設定や操作を実施します。
- 11 [name] ここは従前のnameとは違い、コンテナ名の指定となります。
- 12 [hostname] コンテナのホスト名を指定します。ここではVarsで設定した変数を使ってます。
- 13 [image] コンテナを起動するためのイメージを指定します。DockerfileのFROMに書くものと同じです。
- 14 [detach] docker container runの-dに相当します。
- 15 [auto_remove] docker container runの--rmに相当します。
12行目の変数ですが、通常は{{ 変数 }}という形で書きます。
ただし、変数が引数の先頭に来てしまう場合は、"{{ 変数 }}"のように、ダブルクォートで括ってやる必要があります。
起動
playbookが完成したので、起動します。
インベントリは通常/etc/ansible/hostsを探しますが、今回は-iにてインベントリを絶対パスで指定してます。
# ansible-playbook -i /labo/ansible/inventory/hosts wordpress.yml
PLAY [Wordpress Container Maker] ********************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************
ok: [localhost]
TASK [Create a wordpress container] *****************************************************************************************************
changed: [localhost]
PLAY RECAP ******************************************************************************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0
#
failedがなければOKです。
Wordpressコンテナ内をいじる
さらに、完成したWordpressコンテナをいじ…りたいのですが、残念ながらwordpressのimageには、pythonが含まれていないため、Ansibleで制御ができません…。
従って、wordpressコンテナにpythonをインストールしてやる必要があります。
1 - name: Create a wordpress Container
2 hosts: localhost
3 connection: local
4
5 vars:
6 hostname: wordpress
7
8 tasks:
9 - name: Create a wordpress container
10 docker_container:
11 name: wordpress
12 hostname: "{{ hostname }}"
13 image: wordpress:latest
14 detach: yes
15 auto_remove: yes
16
17 - name: Configure the wordpress container
18 hosts: wordpress
19 connection: docker
20 gather_facts: False
21
22 tasks:
23 - name: install python
24 raw: apt-get update && apt-get -y install python
25 - name: Copy a file
26 copy: src=poipoi dest=/.
一応、上記のようにgather_facts(20行目)をFalseで抑止(Python使うので)し、rawでaptコマンドを直で流し込みすればいけますが、
特にauto_remove: yesな環境の場合、毎回毎回起動するたびにpythonのインストールが走って、時間がかかります。
尚、copyの部分(26行目)は、pythonをインストールしていないとできません。
もう一つのアプローチとしては、そもそものimageを準備するということになります。
docker image buildで作った独自のカスタムimageをplaybook内で呼んでやれば、
上記の力技より起動時の時間は短縮されます。
ただ、ansible内で設定が閉じないので、管理対象物は増えます。
どちらが良いかというと、一長一短ですが、基本的には餅は餅屋の精神で後者かなぁ…という気はします。
なんでも出来るからと言って、それそっちで無理やりやる必要ある?ってことまでやらせてしまうのはいまいち気が進みませんね。
ということでimageを別途準備したのちのコンテナ内ガサゴソは別途記事立てます。