注 2016年現在、werckerの仕様変更に伴い、これは動作しません。
概要
GithubへのPush毎に、werckerでAnsibleのPlaybookとServerspecでのテストを自動実行するようにしました。
拙作のansible-Redmineのv3.0.2対応に併せて実現しています。
これまではVagrantを起動して確認していましたが、GithubへのPush毎に自動的に実行されるので、楽になりそうです。
作成にあたっては次のエントリを参考にさせて頂きました。
CircleCIでDockerコンテナに対してansibleを実行しserverspecでテストをする
[drone]OSS版DroneでDockerコンテナに対してansibleを実行しserverspecでテストをする
エントリと違う点としては、次の3点があります。
- wercker以外の別のDockerホストの環境でも使いやすいことを目指した。
- AnsibleとServerspec専用のコンテナを用意した。
- Ansibleの実行先に専用のコンテナを用意することで、実行先の設定を予め固定するなど実際の環境になるべく近いようにした。
ansible-Redmineにwercker.ymlを設置し、wercker - ANSIBLE-REDMINEで実行しています。
wercker.ymlをシェルスクリプトに書き換えると、他のDockerホストでも簡単に実行できると思います。
volanja/docker-ruby2.2.0コンテナ
CentOS6をベースに、Ruby2.2.0をインストール済みのコンテナです。
Redmineインストール毎にRubyをインストールするのは時間が足りないので、予め用意しました。
DockerのAutomated Buildで作成しています。
Docker Hub - volanja/docker-ruby2.2.0
SSH鍵はビルド毎に作成しており、受け渡しにvolumeを使用しています。
起動後はSSH公開鍵の設定などを行います。
docker run -d -P --cap-add=NET_ADMIN --hostname=cadence -v `pwd`/ssh:/var/tmp:rw --name target volanja/docker-ruby2.2.0
echo 'service sshd restart; mkdir /root/.ssh/ ; cat /var/tmp/authorized_keys >> /root/.ssh/authorized_keys' | /usr/local/bin/docker-enter target
dockerコンテナ上でのiptables設定
Docker Hub - volanja/docker-ruby2.2.0の注意点です。
Ansibleのplaybook中でiptablesの設定ファイル(/etc/sysconfig/iptables)の書き換えとiptablesの再起動を行いますが、docker上では2つの問題が有り、対応しています。
- /etc/sysconfig/iptablesがない。
centos:centos6にはファイルがありません。
そこで、Dockerコンテナのビルド時にCOPYすることで対応しました。 - iptablesの再起動が出来ない。
dockerコンテナのビルド時にecho 'IPTABLES_MODULES_UNLOAD=no' >> /etc/sysconfig/iptables-config
を行うと共に、docker runの実行時に--cap-add=NET_ADMIN
を付加することで対応しました。
次のエントリを参考にさせて頂きました。
Dockerコンテナ内で service iptables stop/status をエラーにしない
volanja/docker-ansibleコンテナ
CentOS6をベースに、AnsibleとServerspecをインストール済みのコンテナです。
DockerのAutomated Buildで作成しています。
Docker Hub - volanja/docker-ansible
SSH鍵はビルド毎に作成しており、受け渡しにvolumeを使用しています。
Ansible Playbookの受け渡しにもvolumeを使用しています。
SSH鍵の設置を行った後に、AnsibleのPlaybook実行とServerspecの実行を行います。
docker run -d -P --name serv --link target:dest -v `pwd`:/root:rw -v `pwd`/ssh:/var/tmp:rw -t volanja/docker-ansible
echo 'env; mkdir ~/.ssh; cp /var/tmp/id_rsa_docker ~/.ssh/id_rsa ; chmod 600 ~/.ssh/id_rsa ' | /usr/local/bin/docker-enter serv
echo 'cd /root; ansible-playbook site_wercker.yml -i hosts_wercker' | /usr/local/bin/docker-enter serv
echo 'cd /root; rake serverspec:Install_Redmine' | /usr/local/bin/docker-enter serv
docker-ansibleとdocker-ruby2.2.0間の通信
Docker Links
2つのコンテナ間のdockerのLinksと呼ばれる機構を利用して通信しました。
これにより、コンテナのみで通信することが出来ます。
初めにdocker-ruby2.2.0コンテナを起動します。
# (必要な部分のみ抜粋)
docker run -d -P --name target volanja/docker-ruby2.2.0
続いて、docker-ansibleコンテナをdocker-ruby2.2.0にリンクする形で起動します。
linksを使用する場合は、コンテナ名:エイリアス名
と指定します。エイリアス名はdest
としました。
# (必要な部分のみ抜粋)
docker run -d -P --name serv --link target:dest -t volanja/docker-ansible
docker-ansibleコンテナ内にはdocker-ruby2.2.0コンテナのIPアドレスやポートの情報が環境変数と/etc/hosts
内に書き込まれます。
Ansibleのhosts情報にはdest
を指定します。
/usr/local/bin/docker-enter serv
env |grep DEST
DEST_PORT=tcp://172.17.0.8:22
DEST_PORT_22_TCP=tcp://172.17.0.8:22
DEST_PORT_80_TCP=tcp://172.17.0.8:80
DEST_PORT_22_TCP_ADDR=172.17.0.8
DEST_PORT_80_TCP_ADDR=172.17.0.8
DEST_ENV_RUBY_VERSION=2.2.0
DEST_PORT_22_TCP_PORT=22
DEST_PORT_80_TCP_PORT=80
DEST_NAME=/serv/dest
DEST_PORT_22_TCP_PROTO=tcp
DEST_PORT_80_TCP_PROTO=tcp
cat /etc/hosts |grep dest
172.17.0.8 dest
次のエントリを参考にさせて頂きました。
Dockerコンテナ間のlink,database.ymlの書き方
SSH鍵の共有
docker-ansibleからdocker-ruby2.2.0にはSSHで接続します。
SSH鍵は毎回wecker上で作成し、共有ディレクトリ経由で各コンテナに渡します。
SSH鍵の作成
mkdir `pwd`/ssh
ssh-keygen -f `pwd`/ssh/id_rsa_test -N ''
cat `pwd`/ssh/id_rsa_test.pub >> `pwd`/ssh/authorized_keys
Dockerを使うときの注意点
werckerのdockerはdocker exec
が使えない。
wercker.ymlを書くときの注意点です。
Dockerのバージョンが古く、docker execが使用できません。
代替策としてjpetazzo/nsenter
でdocker-enter
をインストールして使用しています。
$ docker -v
Docker version 1.2.0, build fa7b24f
以上