ぼくのかんがえた itamae/serverspec 構成フレームワーク 〜 kondate 〜
TRANSCRIPT
ぼくのかんがえた Itamae/Serverspec 構成フレームワーク ~ 板前の献立 ~
!
2015/12/09 @sonots
Itamae meetup 1
自己紹介• 瀬尾直利 @sonots
• DeNA 分析基盤
• Fluentd コミッタ
• Ruby コミッタ NEW!
• Specinfra のコミット権も あまり活動できてない🙇
• 日本語職業シリーズ OSS 同盟
(Haikanko, Yohoushi)
アジェンダ• 弊社での Itamae 利用
• Itamae のディレクトリ構成
• うちでのディレクトリ構成 • Chef vs Itamae 感想
弊社での Itamae 利用• 全社的に使っているわけではない🙇
• 全社的には Chef
• (古い環境では) Touryo も現役 • オレのオレによるオレのためのプロビジョニング(みたいな扱い)
• うちのチームで作ったアプリの環境を作るのに使用 • 整って来たので他の所にも使い始めている
• ディープラーニングなチームのためのインフラ構築, etc
うちでの実行方式• デプロイサーバから itamae ssh で実行
• ホスト数がそんなに多くない (10~20台程度) • 増えても並列実行の仕組みでカバー
• tar ボールを s3 にあげて、各ホストでダウンロードして
local 実行、みたいなナウいことはやってない
deploy
Itamae のディレクトリ構成
Itamae 標準ディレクトリ構成• itamae の基本はレシピ指定
!
!
!• 標準ディレクトリ構成は決まってない • chef のような run_list (どのレシピを流すのか)や
roles (役割) をどこで決めるのかは決まっていない
$ itamae ssh --host host001 \ recipe.rb -y node.yml
Itamae 推薦ディレクトリ構成 (1)• wiki にオススメ構成は書いてある
├── cookbooks │ └── nginx │ ├── default.rb │ ├── files │ │ └── etc │ │ └── nginx │ │ └── conf.d │ │ └── static.conf └── roles └── web.rb
Itamae 推薦ディレクトリ構成(2)• cookbooks の下に middleware レシピを書く
• roles の下に role レシピを書いて、include_recipe でどの middleware を入れるのか指定
!
!
• $ itamae ssh --host host001 roles/web.rb
include_recipe "../cookbooks/nginx/default.rb"
├── cookbooks │ └── nginx │ └── default.rb └── roles └── web.rb
ちょっと足りない• ホストとロールの紐付け補助が欲しい → 究極的にはホストの指定だけで流したい !
!
!
• serverspec と itamae を同じレポジトリで管理して、レシピとテストを対に書きたい → role とレシピの紐付けを itamae の仕組み (include_recipe) で行えないので、汎用マークアップ言語で記述
$ itamae ホスト名 $ serverspec ホスト名
ぼくのかんがえた Itamae/Serverspec 構成フレームワーク
Yet another nodes management framework (?) for itamae/serverspec
kondate ディレクトリ構成
├── .kondate.conf # kondate configuration
├── hosts.yml # manages hostnames and its roles
├── properties # manages run_lists and attributes
│ ├── nodes # host specific properties
│ ├── roles # role properties
│ └── environments # environment properties
├── recipes # itamae recipes
│ ├── middleware # middleware recipes
│ └── roles # role recipes
└── spec # serverspec specs
├── middleware # middleware recipes specs
├── roles # role recipes specs
$ kondate init
.kondate.conf• kondate の設定ファイル
• ディレクトリツリーの変更が(ある程度)できる
• Host Plugin ディレクトリの指定と設定(後述)
middlware_recipes_dir: recipes/middleware roles_recipes_dir: recipes/roles middleware_recipes_serverspec_dir: spec/middleware roles_recipes_serverspec_dir: spec/roles nodes_properties_dir: properties/nodes roles_properties_dir: properties/roles environments_properties_dir: properties/environments secret_nodes_properties_dir: secrets/properties/nodes secret_roles_properties_dir: secrets/properties/roles secret_environments_properties_dir: secrets/properties/environments plugin_dir: lib host_plugin: type: file path: hosts.yml
hosts.yml• デフォルトの `File` Host Plugin の設定ファイル • ホストのロールを定義
!
!
• $ kondate itamae ホスト名 と実行すると、hosts.yml
から role 一覧を取得し、properties/roles/ロール.yml に定義されたレシピ一覧を実行する
• ※ Host Plugin は独自に作成することができる
ホスト名: [ role1, role2 ]
properties ディレクトリ• chef でいう nodes, roles, environments ディレクトリ
!!!!!
• environments/環境.yml、roles/ロール.yml、nodes/ホスト名.yml といったファイルに、どのレシピを実行するのか定義する
• nodes > roles > environments の強さでマージされる
├── properties # manages run_lists and attributes
│ ├── nodes # host specific properties
│ ├── roles # role properties
│ └── environments # environment properties
property ファイルの書き方(1)• attributes 下に、「レシピ名: 属性値のハッシュ」の形式で書く
!!!!!!!
• レシピ名になっている attributes のキーから run_list を取得
• itamae のレシピ内では、node['attributes']['ruby']['versions'] のように attributes にアクセス可能
• 長いので attrs['ruby']['versions'] という書き方も用意している
attributes: ruby: versions: [2.2.3] node: versions: [v0.12.2] global: v0.12.2 nginx:
property ファイルの書き方(2)• vs Chef
!!!!!!!!!
• chef では run_list 定義と attributes 定義が別々だったが統一
• 「attributes のキー名にはレシピ名を使う事」のような俺々ルールにいつもしているので、kondate ではそれが強制される設計になっている
$ cat node.json { "name": "localhost", "run_list": [ "recipe[ruby]" ], "default_attributes": { "ruby" : { "versions": [2.2.3] } } }
recipes• middleware レシピと role レシピという概念
!
!
!
• middleware レシピはミドルウェアをインストールする普通のレシピで、nginx/default.rb などがおかれる場所
• roles レシピはロール固有のレシピをおく場所
├── recipes # itamae recipes
│ ├── middleware # middleware recipes
│ └── roles # role recipes
Role レシピという概念• 最初は recipes 直下に全部書いていた
• 例えば /var/log/app1 を作る、という処理
• 最初は app1 レシピを作ってそこに書いていた → 他の
role から再利用されないレシピであることに違和感
!
!
!
!• Role レシピという新しい概念に分離し、その role でのみ実行するようにした
recipes ├─ nginx/default.rb
└─ app1/default.rb
spec• recipes に対応した serverspec テスト
!
!
!
• $ kondate itamae ホスト名に対して
• $ kondate serverspec ホスト名
のように実行。role を取得して、必要な recipe に対する serverspec テストのみ流す
└── spec # serverspec specs
├── middleware # middleware recipes specs
└── roles # role recipes specs
Host Plugin (1)• デフォルトは hosts.yml に定義を書く file プラグインを利用
• AWS EC2 の Roles タグから role 一覧を取得したい、社内のホスト管理APIサーバから role 一覧を取得したい、というケースがありそう
• 自由に定義できるように Host Plugin という仕組みを用意した。
Host Plugin (2)# lib/kondate/host_plugin/file.rb require 'yaml' module Kondate module HostPlugin class File < Base # @param [HashWithIndifferentAccess] config def initialize(config) super end ! def get_environment(host) ENV['ENVIRONMENT'] || 'development' end ! def get_roles(host) YAML.load_file(@config.path)[host] end end end end
その他悩んだ設計ポイント
複数ロール問題について(1)• 一つのホストに複数の role を付けられる設計
• roles/ロール1.yml と roles/ロール2.yml をどのようにマージするのかという問題 ← hash の deep_merge だと片方を上書きしてしまう
attributes: ruby: versions: [1.9.3, 2.2.3] nginx:
attributes: ruby: versions: [2.0.0, 2.2.3] nginx:
roles/app1.yml roles/app2.yml
どっちが強いのか定義できない
複数ロール問題について(2)• 現在の kondate は role 毎に itamae を実行(2つ
role があれば、2回実行)することにしている • 遅いけど、そもそも1つのホストに2つロールを付けるんじゃない(怒)というスタンス
感想&まとめ
Chef vs Itamae 感想 (1)
• 前提:弊社の chef は knife-solo、berkshelf 利用
• knife-solo は一度 berkshelf で cookbook を全て落として来て、リモートに転送して、リモートでchef-solo
実行する → 遅い、分かりにくい
• Itamae は rubygems を使っていて、Itamae ssh で手元から実行する → 分かりやすい、デバガを仕込める
• 今の小さい規模には Itamae が fit している
Chef vs Itamae 感想 (2)
• Itamae は Chef のようにディレクトリ構成を規定してくれていない
• でも、Chef の場合も結局ラッパーを書いて動かしたりする (弊社にも dena-chef ラッパーがいる)
• 各々で構成決められるので良いのでは
まとめ• Kondate という枠組みを用意して Itamae 使ってます
• 各社好みで構成を決めたくなると思うので、その時に参考にしてみてください🙏
• Kondate の構成がフィットするならそのままご利用ください :D