はじめに
今更ながら capistrano
に感動したのでインフラエンジヤなりの視点で触ってみて使い方をまとめてみる。
capistrano とは
以下は自分が抱く capistrano
へのイメージ。
- 複数のノードに対して並列してコマンドを実行出来る!(うれしポイント)
- コマンドを
task
という単位で纏めて自動化出来る!(うれしポイント) - Ruby 製のデプロイツール!(やや、うれしポイント*1)
これだけ「うれしポイント」があれば複数台のサーバーにログインして色々とやんなきゃいけないインフラエンジヤが使わない理由が無いでしょ!ということで早速使ってみよー。
ちなみに今までは以下のようなイメージ。
メンテナンス作業等に capistrano
を常用するようになってからのイメージ。
ということで、本来の capistrano
の利用目的とは逸れてしまうかもしれないが、インフラエンジニヤが capistrano
を使うことで日頃の運用をちょっとでも楽に出来そうなので使い方について纏めてみることにする。
参考
環境を整える
Mac で boxen を使ってインストール
Mac
環境において boxen
を使って環境を構築している場合には /Users/${USER}/our-boxen/modules/people/manifests/${GITHUB_USER}.pp
に以下を追加する。
ruby::gem { "capistrano for 2.0.0-p247": gem => 'capistrano', version => '2.15.4', ruby => '2.0.0-p247' } ruby::gem { "capistrano_colors for 2.0.0-p247": gem => 'capistrano_colors', ruby => '2.0.0-p247' }
追加したら ./script/boxen --no-fde
でインストールする。(※手元の環境(OS X Mavericks
)ではインストール後に rbenv
で Ruby
のバージョンを指定しなければ capistrano
を利用することが出来なかった...あれ?)
Ubuntu では
手元の Ubuntu
環境では以下のように gem
でインストールした。
sudo gem install capistrano --no-ri --no-rdoc -V -v '2.15.4' sudo gem install capistrano_colors --no-ri --no-rdoc -V
Docker を使ってアクセス先のノードを準備する
以下のように Dockerfile
を書いて capistrano
を使ってアクセスする為のノードを何個か用意しておく。
# FROM inokappa/wheezy-7.2-basic # MAINTAINER YOHEI KAWAHARA inokappa # RUN apt-get update RUN apt-get -y install puppet openssh-server # RUN mkdir -p /var/run/sshd RUN useradd -d /home/sandbox -m -s /bin/bash sandbox RUN echo sandbox:sandbox | chpasswd RUN echo 'sandbox ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
使ってみる
初期化
適当にディレクトリをこさえてから capify
コマンドを実行して capistrano
を使う環境を準備する。
mkdir ${capistrano_dir} cd ${capistrano_dir} capify .
以下のように出力される。
[add] writing './Capfile' [add] making directory './config' [add] writing './config/deploy.rb' [done] capified!
これで準備は完了。
cap -T
cap -T
を実行すると capistrano
でデフォルトで登録されているタスクの一覧が出力される。
cap deploy # Deploys your project. cap deploy:check # Test deployment dependencies. cap deploy:cleanup # Clean up old releases. cap deploy:cold # Deploys and starts a `cold' application. cap deploy:create_symlink # Updates the symlink to the most recently deployed version. cap deploy:migrate # Run the migrate rake task. cap deploy:migrations # Deploy and run pending migrations. cap deploy:pending # Displays the commits since your last deploy. cap deploy:pending:diff # Displays the `diff' since your last deploy. cap deploy:restart # Blank task exists as a hook into which to install your own environ... cap deploy:rollback # Rolls back to a previous version and restarts. cap deploy:rollback:code # Rolls back to the previously deployed version. cap deploy:setup # Prepares one or more servers for deployment. cap deploy:start # Blank task exists as a hook into which to install your own environ... cap deploy:stop # Blank task exists as a hook into which to install your own environ... cap deploy:symlink # Deprecated API. cap deploy:update # Copies your project and updates the symlink. cap deploy:update_code # Copies your project to the remote servers. cap deploy:upload # Copy files to the currently deployed version. cap deploy:web:disable # Present a maintenance page to visitors. cap deploy:web:enable # Makes the application web-accessible again. cap invoke # Invoke a single command on the remote servers. cap shell # Begin an interactive Capistrano session.
もちろん、タスク自体は自分で追加することも出来るが、まずは一番下の cap shell
を使ってみる。
cap shell を使ってノードにログイン
以下のようにして cap shell
に続いて HOSTS=
オプションの後にノードのホスト名、又は IP アドレス、そして、USER=
の後にノードを作成した際に設定したユーザー(sandbox
)を続ける。
cap shell HOSTS=xxx.xxx.xxx.1 USER=sandbox
実行すると以下のように表示されるので適当にコマンド(pwd
)を叩いてみる。password
には USER=
で指定したユーザーのパスワードを入力する。
おお。ノード上でコマンドが実行されて結果が出力された...ん、でも、これだと普通に SSH
でログインしたのと変わらぬ。
さらに cap shell を使って複数のノードにログイン
前述の通り、capistrano
の旨みは複数のノードに対して並列してコマンドを投げることが出来る!だったので複数のノードに対して cap shell
を実行してみる。HOSTS=
オプションの後にノードを 2 つ並べて書いてみる。
cap shell HOSTS="xxx.xxx.xxx.1","xxx.xxx.xxx.2" USER=sandbox
おお。二つのノードで pwd
コマンドの結果が出力された!こりゃ便利。
cap shell
でアクセスしといて uptime
なんか適当な間隔で叩いておくといい感じですな。
タスクを追加する
cap shell
で複数ノードに対して一度にコマンドを実行する喜びをひと通り感じたところで、cap shell
だと一つのコマンドしか実行出来ない*2なあと思ったあなたは鋭い。実行させたいコマンドをひと通り並べたタスクを追加することでその疑問を一気に解決。
config/deploy.rb を修正する
${capistrano_home}/config/deploy.rb
を以下のように修正する。
require "capistrano_colors" desc "test" namespace :deploy do task :hoge do run "pwd" run "echo \"Hello Servers!\"" end end
修正したら以下のように実行する。
cap deploy:hoge HOSTS="xxx.xxx.xxx.1","xxx.xxx.xxx.2" USER=sandbox
以下のように出力される。
おお、それぞれのコマンドがノードで実行されている!
接続先のノードも deploy.rb に書いてみる
二つ、三つくらいのノードであれば HOSTS=
に繋げてかけるが、それ以上だとコマンドラインに並べる妙技は崩壊してしまう*3。ということで、コマンドを実行させたいノードを role
に書く。
require "capistrano_colors" role :ahoaho, "xxx.xxx.xxx.1","xxx.xxx.xxx.2" desc "test" namespace :deploy do task :hoge do run "pwd" run "echo \"Hello Servers!!\"" end end
これを実行すると...
cap deploy:hoge USER=sandbox
以下のように出力される。
また、異なる role
を複数記載することが出来る。さらに task
に対して role
を関連付けることも出来る。
require "capistrano_colors" role :ahoaho, "xxx.xxx.xxx.1","xxx.xxx.xxx.2" role :unko, "xxx.xxx.xxx.3","xxx.xxx.xxx.4" desc "test" namespace :deploy do desc "test hoge" task :hoge , roles: => :ahoaho do run "pwd" run "echo \"Hello Servers!!\"" end desc "test huga" task :huga , roles: => :unko do run "uptime" end end
上記の場合には role
の ahoaho
には hoge
を role
の unko
には huga
を実行される。
ということで
capistrano
のほんの触り部分しか書けていないがこれだけでもインフラエンジニヤは感動- 次回は 複数の
EC2
インスタンスノードにアクセスしてchef-solo
やpuppet apply
等を組み合わせてノードをデプロイ方法を書いてみたい