大きく分けて二つの話をしました。
Chefを導入する時の「考え方」
Chefのような構成管理ツールは万能でやり方もたくさんある(TMTOWTDI)ので、最初にどういうポリシーで組み立てるかが重要になります。今回「本気で使う」にあたり、以下のようなポリシーを設定しました。
- 原則サーバ上で作業せず、Chefで環境設定を実装する
- 公開されたcookbooksを再利用する
- opscode-cookbooksにあればそれを探す
- communityやgithubにあるcookbookを使う
- あきらめの心を持つ
- 必要ならばopscode-cookbooksなど既存のcookbookをforkして手を入れる
- 半日調べて難しそうなことはあきらめる(自前Chef recipe→それでも駄目なら本当に手作業)
よく言われているように、opscode-cookbooksは様々なOS/distributionで使えるように汎用化されていたり、LWRPやdefinitionを多用していてrecipe本体を読み解こうとするといきなりは難しいのですが、READMEでの利用ガイドがそれなりに書かれているため、それに従って試行錯誤してみるだけで、「まずはopscode-cookbooksにあればそれを探す」が実現できます。
それでも駄目であれば、あきらめの心で自前のcookbookを書くことになりますが、実は以下の2点だけでそれなりのことができます。
- パッケージ入れたい → recipeにpackageとserviceを書く
- 設定ファイルを編集したい → templates に突っ込んでそこを編集して配布する
直ぐにできないことは割り切り、できるところからやれば良いんです。できた部分は、きちんとレポジトリ上で差分管理がはじめられるわけですから。
問題提起:プログラムのデプロイをChefでどこまでやるべきか
実は本題はこっちだったのですが、バランスを間違えました(ノ∀`)タハ-
opscode-cookbooksにはapplicationというcookbookがあり、アプリケーションのデプロイを簡単に定義できるようになっています。Capistrano風の構造でレポジトリからファイルを設置して、Railsであれば簡単にUnicornもしくはPassengerの設定、プロセス監視までやってくれます。これがくせ者でした。
後から考えれば、RedmineやWordpressなどのミドルウェアよりのアプリケーションを設置するためのcookbookだったんだろうと思えるのですが、上の原則通りopscode-cookbooksでまずは試すという方針が有り、以下のような試行錯誤をしました。
- opscode-cookbooks/application_rubyをそのまま使ってみる
- runit_serviceでUnicornのプロセス管理だけChefで書く
- CapistranoのrootまでをChefで生成
- Unicornのgraceful restartで問題あり
- 古いプロセスが落ちず、新しいソースコードを読んだプロセスがAddress in useで上がらない
- 原因は未調査
- Chefではほぼなにもしない ← イマココ
- Capistrano rootディレクトリの作成
- 各種ログディレクトリの作成
- ログファイルlogrotateの設定ファイル
- Unicornを立ち上げるinit.d script配布
- MySQLのデータベース/ユーザ作成
何の理由でUnicornが落ちるかという不安もあるので、runitのようなプロセス管理を使おうと思ったのですが、デプロイは完全にCapistranoに任せようとすると、初回時に「鶏とたまご」問題があります。
簡単に言うと、Unicorn自体はデプロイ時のbundle installで入るため、一度デプロイされないとUnicornが存在せずChefの実行がこける(サービス起動できないため)わけです。仕方無いので、初回のみ空のRailsプロジェクトをgithubに用意してダミーデプロイをしました。相当に筋が悪いやり方ですが、Unicorn管理を諦めたので最終的には未使用です。
質問:Chefでどこまでやっていますか?
ざっくり以下の2点が考えるポイントかなと思います。
- サーバ構築時のアプリケーションの初回デプロイ
- (デプロイされるまでそのサーバにアプリは無いがそれで良いのかどうか)
- APサーバ(Unicorn等)のプロセス管理
というわけで、ハッシュタグ等でご意見ください。
– #opschef_ja