windowsでもansibleがしたいのでvagrant経由でdockerを使って二重仮想環境を構築する

Ansibleとは、Python製のプロビジョニングツールだ。Rubyで言うところのChef。
動作にはPythonが必要だが、残念なことにwindowsではpythonがまともに動かないようだ。
vagrantで2つのゲストを立てて片方をansibleにする方法もあるが、先日最新版がリリースされたdockerを使ってみた。
目標はこんな感じ。
f:id:saisa6153:20131211000758p:plain

説明すると、windowsホストで各種操作の母艦となるCentOS 6.5をVagrantで立ち上げる。
その中でまずdockerを使って、開発環境であるCentOS 6.4のコンテナを作り、母艦から操作できるよう設定する。
その後は母艦からsshするもよし、virtualenvというpython仮想環境上でansibleのplaybookを作成するもよし。
今回はコンテナの作成とansibleの動作確認ができたのでまとめ。
Windowsは8。

Windows <-> Vagrant (CentOS 6.5)

cygwinとか方法はたくさんある。
別にvagrantでなくても、virtual box直接動かしてputtysshするのでも全く問題無い。
僕はmingwを使って、vagrant upもsshもそこからしている。

CentOS 6.5へのDockerの導入

sudo rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
sudo sed -i.bak 's/enabled=0/enabled=1/' /etc/yum.repos.d/epel-testing.repo
sudo yum install docker-io

これだけ。

Dockerで開発環境(CentOS 6.4)を作る

sudo service docker start
sudo docker run -i -t centos /bin/bash

初回実行時のみ、イメージを取得するため時間がかかる。
ダウンロードが終わり次第、コンテナ上のbashに入る。
コンテナ内でexitすると、その時点でそのコンテナは停止する。

sudo docker ps -a

で、exit status 0になっているものが停止中のコンテナ。
ーaを付けなければ、動いているコンテナのみ表示できる。
stopしているコンテナに入りたいときは、

sudo docker start コンテナID
sudo docker attach コンテナID

で、コンテナに入ることができる。

コンテナ内から外につなぐ

デフォルトでコンテナ内から外に出られなかったら、母艦の/etc/sysctl.conf を編集する。

net.ipv4.ip_forward = 1

ゼロから1に。
参考: http://qiita.com/gitcell/items/7cfde70e7a73fa1d2f7b

独自イメージを作成して今後のベースにする

まっさらなcentosコンテナに入ってrootユーザのパスワードを設定、openssh-serverをインストール、sshdの起動設定を行い、/etc/ssh/sshd_config でUse PAMをnoにする。
参考: http://stackoverflow.com/questions/18173889/cannot-access-centos-sshd-on-docker

exitコマンドで一旦コンテナから出てdocker ps -aでコンテナIDを確認し、

sudo docker commit -m 'メッセージ' コンテナID ユーザ名/用途名

これで、sshに必要な最低限の環境を持ったイメージができる。
このイメージから作成したコンテナに対して操作を試して破壊して…を繰り替えることができる。
また、イメージの配布も可能。
ちなみに、コンテナの削除は

sudo docker rm コンテナID

イメージの削除は

sudo docker rmi イメージID

作成した独自イメージからコンテナにsshする

先ほど作成したイメージ名が saisa/sshd だとすると、まずはそのコンテナを走らせておく。

sudo docker run -d -p 22 saisa/ssh /usr/sbin/sshd -D

すぐに入力が戻ってくるので、docker psで走っていることとコンテナIDを確認してから

sudo docker inspect コンテナID

で、コンテナの情報を確認する。

(中略)
    "NetworkSettings": {
        "IPAddress": "172.17.0.17",
        "IPPrefixLen": 16,
        "Gateway": "172.17.42.1",
        "Bridge": "docker0",
        "PortMapping": null,
        "Ports": {}
    },
 (中略)

となっているので、このIPAddressに母艦からsshすればいい。

ssh root@172.17.0.17

python環境とAnsibleを準備

母艦のCentOS 6.5に入っているPythonは2.4だった。最新にしたりする。
pythonzは複数バージョンのpythonをクリーンにインストールできる。
ただバージョン切り替えができないので、それを行うのがvirtualenv。
virtualenvは機能過多で使いにくいので、virtualenvwrapperを併用。
参考: http://saisa.hateblo.jp/entry/2013/11/16/155601

curl -kL https://raw.github.com/saghul/pythonz/master/pythonz-install | bash
echo ' -s $HOME/.pythonz/etc/bashrc  && source $HOME/.pythonz/etc/bashrc' >> ~/.zshrc
source ~/.zshrc
sudo pip install virtualenv{,wrapper}
pythonz install 2.7.6

これで環境は整う。

mkvirtualenv -p ~/.pythonz/pythons/CPython-2.7.6/bin/python myproject

で仮想環境を作成できる。後はpip install ansible。
環境変数を読み込み直したりすると仮想環境が消えるので注意。
今回作成したmyproject環境に再び入るときは

workon myproject

仮想環境から出るときは

deactivate

Ansibleの動作テスト

とりあえずpingだけして操作が可能かを確かめたい。
id:kazuph1986 さんに教えてもらいました。ありがとうございます。
hostsファイルにdocker inspectで調べたipとログインユーザ名を明記するのがポイント。

(ansible)➜  ~  cat hosts
172.17.0.17:22 ansible_ssh_user=root

(ansible)➜  ~  ansible all -i hosts -m ping -k
SSH password:
172.17.0.17 | success >> {
    "changed": false,
    "ping": "pong"
}