chef soloからitamaeに完全移行した話+
TRANSCRIPT
Chef-SoloからItamaeに完全移行した話+
Itamae Meetup 2015/12/9 @toritori0318
自己紹介
• 鳥居 剛司 (@toritori0318/アルパカ大明神)
• 株式会社HAROiD
• http://www.haroid.co.jp/
• サーバ / オペレーションエンジニア
• Lua / Golang / Python / Node.js / Perl / Ruby
• 二児の父
Itamae
アジェンダ• 弊社の事情
• インフラ • 開発フロー • 課題
• Chef-SoloからItamaeへの移行 • 移行した結果 • まとめ
弊社のインフラ事情
開発フロー
開発フロー• 事前準備
• 独自configにvm情報追記/nodes.json作る/… • AMI作成
• rake aws:up vm=<vm> • rake aws:provision vm=<vm> • rake aws:spec vm=<vm> • rake aws:create_ami vm=<vm>
• クラスタ操作 • rake aws:cf:create_stack env=<env> • rake aws:cf:update_stack env=<env> params=<params> • rake aws:cf:delete_stack env=<env>
ツール• Vagrant
• Vagrant-aws
• Vagrant-ami
• Chef-Solo
• Berkshelf
Itamae
Gemfile
Chef-Solo時代の課題
Chef-Solo+ Berkshelfの煩雑化
• コミュニティクックブック多用
• プロビジョニングが遅い
• Chef-Soloの終焉?
• そしてChef-Zeroへ…
_人人人人人人人人_ > 突然のItamae < ‾Y^Y^Y^Y^Y^Y^Y‾
シンプルなChef# install gem install itamae
# 適当なレシピ作る
echo "package 'sl'" > recipe.rb
# itamae実行(ローカルホスト) itamae local recipe.rb # itamae実行(リモートホスト) itamae ssh -u hogeuser -h xxx.xxx.xxx.xxx recipe.rb # itamae実行(Vagrant) itamae ssh --vagrant --host vm_name recipe.rb
シンプルなChef# attributeを定義したjsonを指定して実行
itamae local -j node.json recipe.rb # レシピを複数つなげて実行
itamae local recipe01.rb recipe02.rb recipe03.rb
# dry-run itamae local --dry-run recipe.rb # ohai情報を参照 itamae local --ohai recipe.rb
_人人人人人人_ > これだ! < ‾Y^Y^Y^Y^Y‾
Chef-Soloからの移行ただし既存のフローや構造は(ほぼ)そのままで
ディレクトリ/ファイル構造(Chef-Solo)
PROJECT_ROOT/ cookbooks/ # Berksfileクックブック群 site-cookbooks/ # プロジェクト固有クックブック群 roles/ # ロール群 nodes/ # vm毎のnode.json vm_app.json vm_db.json ... data_bags/ # 秘密情報 Berksfile # Berksfile Vagrantfile # Vagrantfile
ディレクトリ/ファイル構造(Itamae)
PROJECT_ROOT/ cookbooks/ # プロジェクト固有クックブック群 base-cookbooks/ # 共通クックブック群 roles/ # ロール群 nodes/ # vm毎のnode.json vm_app.json vm_db.json ... secret/ # 秘密情報 entrypoint.rb # Itamaeから実行されるレシピのエントリポイント Gemfile # Itamaeプラグインなどの依存が書かれたGemfile Vagrantfile # Vagrantfile
nodes/json(Chef-Solo){ "td_agent": { "plugins": [ "config-expander", "redeliver", "map", "forest", "multi-format-parser" ] }, "environment": "development", "recipes": [ "role[base]", "role[app]", "recipe[td-agent::install]" ] }
nodes/json(Itamae){ "td_agent": { "plugins": [ "config-expander", "redeliver", "map", "forest", "multi-format-parser" ] }, "environment": "environments/development.rb", "recipes": [ "./roles/base.rb", "./roles/app.rb", "./cookbooks/td-agent/install.rb" ] }
entrypoint.rb# entrypoint.rb # nodes.jsonに記述されているrecipeを順番に読むだけのファイルnode["recipes"] = node["recipes"] || [] node["recipes"].each do |recipe| include_recipe recipe end
# itamae実行時にentrypoint.rbを指定 itamae local -j node.json entrypoint.rb
クックブック(Chef-Solo)<cookbook_name>
CHANGELOG.md
README.md
attributes/
default.rb
definitions/
files/
libraries/
metadata.rb
providers/
recipes/
default.rb
クックブック(Itamae)
<cookbook_name> attributes.rb # attributesをまとめたファイル xxx_recipe.rb # なんかレシピ templates/ # テンプレートファイル xxx.conf.erb
Berkshelf > Gemfile
# itamae gem 'json' gem 'itamae' gem 'itamae-secrets'
# plugins gem 'itamae-plugin-recipe-supervisor', \ :github => 'toritori0318/itamae-plugin-recipe-supervisor' gem 'itamae-plugin-recipe-consul', \ :github => 'toritori0318/itamae-plugin-recipe-consul'
Gemfile
Role
include_recipe "../cookbooks/nginx/install.rb" include_recipe "../cookbooks/app/deploy.rb" include_recipe "../cookbooks/app/supervisor.rb"
roles/app.rb
attributes
# includeするだけ include_recipe './attributes.rb'
attributes.rb# デフォルト値指定
node.reverse_merge!( td_agent: { includes: [], plugins: %w{ forest }, }, )
recipe.rb
Qiita書いた時に 課題になってたこと
Databags↓
itamae-secrets
itamae-secrets# インストール
gem install itamae-secrets
# ベースディレクトリを設定ファイルに書いとく
echo 'base: ./secret' >> .itamae-secrets.yml
# 秘密鍵生成 > ‘<basedir>/keys/default’
itamae-secrets newkey --method=aes-passphrase (パスフレーズ入力)
# 値保存
itamae-secrets set itakey itavalue
# 値取得
itamae-secrets get itakey
itamae-secrets
# require require 'itamae/secrets'
# 秘密情報格納ディレクトリ指定 node[:secrets] = Itamae::Secrets(File.join(__dir__, 'secret'))
# 値取得 itakey = node[:secrets][:itakey]
recipe.rb
itamae-secrets
• .gitignoreに秘密鍵ディレクトリ指定するのを忘れずに!
echo 'secret/keys' >> .gitignore
Chef-Server↓
Consul?
ex) Consulと組み合わせてロール単位にレシピ実行
# 1. 各ノードはイベントwatchしとく consul watch -type event -name itamae /path/to/watch_itamae.sh
# 2. レシピをgit(or S3)にアップロードしておく
# 3. プロビジョニングしたいタイミングでevent発行 consul event -name itamae -service web 'vm=web recipe=nginx'
watch_event_itamae.sh
# 標準入力からペイロード受け取り STDIN_STR=$(cat -) PAYLOAD=`echo $STDIN_STR | jq -r '.[0] .Payload' | base64 -d`
# key=value の組をパースしてvm名やrecipeを得る (snip)
# リポジトリ(or S3) からダウンロード git clone http://hogehoge/itamae-recipes.git /tmp/itamae-recipes
# itamae実行 itamae local --node-json nodes/${VM}.json ${RECIPE}
※やっていること
https://gist.github.com/toritori0318/0ad3aab875c73f68eaf3
Itamae移行後
Pros• 全体的にスリム化
• レシピ / 構造がスッキリ
• include_recipe / package / template / service / execute で大抵食っていける
• プロビジョニングが軽く/速くなった
• 問題解決しやすくなった
• レシピの問題
• ツール自体の挙動
Cons
• エコシステム
• Snippetsサイトがあると良いのかも…?
まとめ
まとめ• Chef-Soloから移行して幸せになった話
• 基本的な使い方であれば移行して困る場面は少ないはず
• 移行自体も思っていたより簡単
• もちろんChefが最適な環境もあるので適材適所
• むしろ Itamae > Chef は十分あり
• エコシステムはもう少し…
• レシピはどんどんシェアしましょう
https://github.com/itamae-kitchen/itamae/wiki/Best-Practice
現在はオフィシャルWikiに
ベストプラクティスが掲載されています
参考
参考• 今回のプロジェクト構成サンプル
• ベーシック • https://github.com/toritori0318/itamae-sample-project
• environmentsバージョン • https://github.com/toritori0318/itamae-sample-project/
tree/environments_version • itamae-secretsバージョン
• https://github.com/toritori0318/itamae-sample-project/tree/itamae-secrets-version
ご清聴 ありがとうございました