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と言うより、すぐに試用環境をぶっ壊せるコンテナ環境の良さに改めて目が向いた感じです)

Read More