Docker + Itamae でレシピ作成の試行錯誤を 高速化
#itamae #docker
概要
Docker +
Itamae でレシピ作成の試行錯誤を 高速化
します
目的
- Itamae のレシピ作成時間を短縮
- 特に工夫をしないと、レシピのプロビジョニングリトライは非常に時間がかかる
- 例えば、Ubuntu 環境に rbenv + ruby(2.1.3) + rails(4.1.8) 環境をインストールしたところ 15 分かかりました
何も工夫をしなければ再試行に + 15 分かかります
- 例えば、Ubuntu 環境に rbenv + ruby(2.1.3) + rails(4.1.8) 環境をインストールしたところ 15 分かかりました
- 普段のプログラミング同様、何事も一発で成功することは少ない。試行錯誤は発生する
- 特に工夫をしないと、レシピのプロビジョニングリトライは非常に時間がかかる
※ Itamae に限った話ではないので、プロビジョニングツール全般に応用可能
前提
- Vagrant で構築した CoreOS 環境 の上に Docker で作成した Ubuntu 14.04 のコンテナを作成し、その環境を利用します 1
- Docker の基本操作の知識が必要です 2
- Immutable なレシピ(冪等性を気にしない)
試行
要件
- OS: Ubuntu 14.04
- rbenv + ruby 2.1.3
- rails 4.1.8
- WebServer: WEBric
- DB: sqlite
- Todo アプリケーションを scaffold して rails 起動
手順
-
下記記事の手順に従い、 Ubuntu のコンテナを立ち上げる
-
Vagrant で Windows 上の VirtualBox に CoreOS のインスタンスを作成し、 Ubuntu 14.04 LTS のコンテナを作成し、 SSH で接続可能にする
- docker run 時に
-p 80:3000
のオプションも追加して実行しておく ( WEBric のポートフォワード )
- docker run 時に
-
Vagrant で Windows 上の VirtualBox に CoreOS のインスタンスを作成し、 Ubuntu 14.04 LTS のコンテナを作成し、 SSH で接続可能にする
-
イメージの確認
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu trusty 04c5d3b7b065 8 days ago 192.7 MB
- 作成した Ubuntu 14.04 コンテナを確認
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0e50ba901b58 sample/ubuntu:trusty "/usr/sbin/sshd -D" 4 seconds ago Up 3 seconds 0.0.0.0:80->3000/tcp, 0.0.0.0:2222->22/tcp berserk_ardinghelli
- こちらの Itamae recipe を利用して Ruby 2.1.3 + Rails 4.1.8 環境を構築します
sudo docker run -d -p 2222:22 -p 80:3000 sample/ubuntu:trusty /usr/sbin/sshd -D
- Rails 環境の構築まで成功したら、 Docker の commit を実行してイメージを作成します
$ docker commit <container name | id> rails_sample
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
rails_sample latest 777715acc917 26 seconds ago 546.9 MB
sample/ubuntu trusty 544a982d72bf 51 minutes ago 255.3 MB
ubuntu trusty 04c5d3b7b065 8 days ago 192.7 MB
- コンテナを停止・削除して、 commit した新規イメージでコンテナを再作成します
$ docker stop <container name | id>
$ docker rm <container name | id>
$ sudo docker run -d -p 2222:22 -p 80:3000 rails_sample /usr/sbin/sshd -D
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3d013b1fe510 rails_sample:latest "/usr/sbin/sshd -D" 4 seconds ago Up 3 seconds 0.0.0.0:80->3000/tcp, 0.0.0.0:2222->22/tcp elegant_colden
- rails 環境構築用のレシピに Todo アプリケーションを scaffold して、 Rails を起動するまでの記述を追加します
変更前レシピ
execute 'apt-get update' do
command 'apt-get update -y'
end
package "build-essential" do
action :install
end
include_recipe 'rtn_rbenv::user'
変更後レシピ
execute 'apt-get update' do
command 'apt-get update -y'
end
package "build-essential" do
action :install
end
include_recipe 'rtn_rbenv::user'
# rails setup の include を追加
include_recipe './rails_setup.rb'
package "libsqlite3-dev" do
action :install
end
execute "setup rails" do
cwd "/home/core"
user "core"
command <<-EOS
. /home/core/.bash_profile
rbenv rehash
rails new todo --skip-bundle
cd todo
cat << EOT >> Gemfile
gem 'execjs'
gem 'therubyracer'
EOT
bundle install
rails generate scaffold Tudu name:string estimate:integer results:integer complete:boolean
bundle exec rake db:migrate
bundle exec rails server -d
EOS
end
※ model 名 todo は rails に予約されているので、 tudu にしています
- itamae 実行
$ bundle exec itamae ssh -p 2222 -j node.json -i /path/to/your/key/key_name -h 172.17.8.101 -u core rails_setup.rb
- 起動確認
データを2件登録してみました
実行時間の比較 (
+
=> 
) (
+
=>
)
+
=> 
- 途中で Docker のイメージを作成せずに、 itamae のレシピを全て再実行した場合
(15 分 × 2) + 2 分 = 32 分
+
=>
- 途中で Docker のイメージを作成した場合(今回紹介した手順)
15 分 + 2 分 + N 分 = 17 + N 分
N 分 は新規イメージの作成にかかる時間。
今回の例だと docker commit の実行は 10 秒程度で終わりました。
その他オペレーション込みで 1 分程度。
たった 1 回の試行でここまで差がつくので、
試行回数が多ければもっと大きな差がつくでしょう。
普段のプログラミングと同様、レシピの作成が一発で成功する方が少ないと思うのですが、
皆さんいかがでしょうか?
効率的にレシピを作成するノウハウを余り見かけないので、今回の記事を作成しました。
私は基本的に(リアルワールドで)誰とも情報交換していないこともあり、情報弱者の可能性は高く、
今回紹介した方法より優れた方法はたくさんあるかもしれません。
この記事への突込みが入って、より優れた方法を引き出すきっかけになれば、
それはそれでいいかな、と思います。
作業フロー
- レシピ内の最小ステップ 3 をインクリメンタルに作成
- dry-run
- 成功
- 次のステップへ
- 失敗
- レシピ修正
- 成功
- プロビジョニング実行
- 成功
- コンテナをイメージ化
- 新規イメージで新規コンテナ作成
- 失敗
- レシピ修正
- プロビジョニングに失敗したらイメージからコンテナを再作成してリトライ
- 成功
- dry-run
- 新規コンテナで作業再開
- 全てのレシピが完成するまで 1-2 を繰り返す
- レシピ全体を通して実行
- レシピが完成したら作業用のイメージ、コンテナを破棄
補足
-
Vagrant + sahara などでもスナップショットを活用して作業用の中間イメージを作成できるが、 docker ほど早くない。
vagrant + sahara のみを使っていて、 Docker を利用したことがない方は是非試してみてください。 -
レシピ試行の際の1回あたりの実行時間が長いと、単純に時間がかかるという以外に下記の弊害がある
-
思考が途切れる
-
眠くなる
-
試行錯誤を繰り返すたびに、作業のパフォーマンスが下がっていく。
戯れ言
-
Docker を利用した記事で Rocket (
) のアイコンを使うブラックジョーク 4