Ansible入門する
現在のプロジェクトでAnsibleが使われていて、ちょっとセットアップ法や概念を知る必要があったので、この際一からやってみます。
弊社の江川先生の例を参考に、とりあえずの練習用のお題として以下を目標にします。
- (1)ubuntu環境のdockerコンテナ/イメージをビルドし、sshd立ち上げたコンテナを2台作る。
- (2)実行中のコンテナ群に対して同じモジュールのインストールをansibleでやってみる。
(2)の作業をAnsible側でplaybookを作ることで試してみます。
(Ansible2.0からはDocker Connection Pluginによってコンテナ側でsshdを立ち上げる必要ないっぽいんですが、あくまで通常のLinuxインスタンスのデプロイのようにやってみます。)
Ansible is 構成管理ツール
Ansibleは Chef , Puppet のような 構成管理ツールの一種となります。
「非ruby」、「デプロイ先でのエージェント不要」、「設定ファイルが少ない/記述がシンプル」などの特徴がChefとの大きな違いのようです。
なんでシェルスクリプトでのデプロイだとダメなんですか?
chefやAnsible等の構成管理ツールの利点は、デプロイ手順の冪等性の担保だそうです。つまり、同じデプロイコードを何度叩いても常に結果が同じになるようにしようぜ、ということ。
シェルスクリプト等でのデプロイと違い、「現在の状態」に対する判定処理を自前で書くことなく、DSLを通してデプロイ済みの状態と新しい状態の差分を吸収させることを目的としています。
「サーバを構築する」という以上に「サーバのあるべき姿を規定する」ことがこの手の構成管理ツールの役割なんだそうです。
サーバー多くなんないと意味ないのと、そもそも世間的にはコンテナとかimageでデプロイ毎にdisposableにしようぜって流れかとは思うんですが、やってみます。
テスト用Dockerコンテナのセットアップ
今回はこんな感じのイメージからコンテナを複数立てます。
pythonとSSH環境だけは必要なので入れておきます。
「siteuser」にSUDO権つけときます。
Dockerfile
From ubuntu:14.04
MAINTAINER fushimi <xxxx@xxx.co.jp>
RUN apt-get update
RUN apt-get install -y software-properties-common
RUN apt-get install -y ssh \
python-apt
RUN /etc/init.d/ssh start
ENV username siteuser
ENV home /home/${username}
ENV password hogehoge
RUN useradd -G sudo -m ${username}
RUN echo ${username}':'${password} | chpasswd
CMD /etc/init.d/ssh start && tail -f /dev/null
image作ります。ansible_testってimage名にします。
docker build -t ansible_test/latest ./
web1,web2って名前で2つばかりコンテナを立ててみます。とりあえずSSHのポート用にdocker-machineの8001,8003をコンテナの22番に当てておきます。
docker run -i -t -d --name web1 -p 8000:80 -p 8001:22 ansible_test/latest
docker run -i -t -d --name web2 -p 8002:80 -p 8003:22 ansible_test/latest
動いてます。
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c3c562a5a54f ansible_test/latest "/bin/sh -c '/etc/ini" 6 minutes ago Up 6 minutes 0.0.0.0:8001->22/tcp, 0.0.0.0:8000->80/tcp web1
14c038eb3f54 ansible_test/latest "/bin/sh -c '/etc/ini" 6 minutes ago Up 6 minutes 0.0.0.0:8003->22/tcp, 0.0.0.0:8002->80/tcp web2
docker-machineのIPが192.168.99.100 で出来てるので、これで各ポートからパスワード認証でsshができるようになりました。
ssh -p 8001 siteuser@192.168.99.100
ssh -p 8003 siteuser@192.168.99.100
テスト環境のセットアップはここまでです。
これらを「稼働中のコンピュータ」と想定して、ansibleによるプロビジョニングの実験を行いたいと思います。
Ansible 設定
Inventryファイル
Ansibleがつなぎに行くサーバ群の設定yml。慣習として「hosts」というファイル名にするようです。
普通は公開鍵認証でつなぎに行って、アイパスもここに書いたりしないですがとりあえず実験として目をつぶっておきます。
hosts
[web]
web ansible_connection=ssh ansible_sudo_pass=hogehoge ansible_ssh_pass=hogehoge ansible_user=siteuser ansible_port=8001 ansible_host=192.168.99.100
web2 ansible_connection=ssh ansible_sudo_pass=hogehoge ansible_ssh_pass=hogehoge ansible_user=siteuser ansible_port=8003 ansible_host=192.168.99.100
PlayBook
hostsで規定したサーバ群に対してデプロイを実行します。
Ansibleの肝です。 ここのDSLを通すことによってAnsibleはサーバーの状態の差分管理を行います。
vimだけインストールするタスクを書きました。
- name: TEST
hosts: all
become: yes
remote_user: "{{ ansible_user }}"
tasks:
- apt : pkg=vim state=installed force=yes
実行
playbookを走らせます。
ansible-playbook task.yml -i hosts
結果
PLAY [TEST] *********************************************************************
TASK [setup] *******************************************************************
ok: [web]
ok: [web2]
TASK [apt] *********************************************************************
changed: [web]
changed: [web2]
PLAY RECAP *********************************************************************
web : ok=2 changed=1 unreachable=0 failed=0
web2 : ok=2 changed=1 unreachable=0 failed=0
もう一回走らせてもvimのapt-getは実行されません。
PLAY [TEST] ********************************************************************
TASK [setup] *******************************************************************
ok: [web]
ok: [web2]
TASK [apt] *********************************************************************
ok: [web]
ok: [web2]
PLAY RECAP *********************************************************************
web : ok=2 changed=0 unreachable=0 failed=0
web2 : ok=2 changed=0 unreachable=0 failed=0
確認すると、vimが入ってます。
ssh -p 8003 siteuser@192.168.99.100
which vim
/usr/bin/vim
まとめ
こんな感じでデプロイができました。
頻繁にデプロイがあったりサービスが複雑になってこないと「それshellのif文でよくね?」となってメリットが薄いですが。。
Docker用プラグインやAWS用のプラグインで面白いことそれなりにできそうですね。
(今回、Ansibleと言うより、すぐに試用環境をぶっ壊せるコンテナ環境の良さに改めて目が向いた感じです)