SlideShare a Scribd company logo
ChefとPuppetの比較
~Puppetユーザから見たChef~(仮)
クックパッド株式会社
菅原 元気
自己紹介
菅原 元気 (@sgwr_dts / id:winebarrel)
白金台のほうから来ました
● クックパッド株式会社勤務
● インフラエンジニア
● Ruby・AWS関連ツールを公開しています
○ https://bitbucket.org/winebarrel/
○ https://github.com/winebarrel/
本日の趣旨
Chefをディスりに来ました
本日の趣旨
     *      *
  *     +  うそです
     n ∧_∧ n
 + (ヨ(* ´∀`)E)
      Y     Y    *
『Puppetの優れている部分を話せ(意訳)』
といわれて横浜まで来ました
本日の趣旨
吉田 真吾 14:49
... Puppetのほうがこんなに便利だ、という趣旨でお話できることなどはございま
せんでしょうか?(中略)Puppetでないとできない(より便利な)ことも多いのではな
いかと思っているのですが。
本日の趣旨
プレゼンをきいてPuppetに
乗り換える方はいないと思いますが…
● Puppetにも良い機能があるので、要望・機能拡
張でChefの改善にもつながるかな
● これからPuppet or Chefを選択する人は、選参
考になるかな
…という感じです
弊社とPuppetのおつきあい
2009年
一部サーバにPuppetを導入
大嫌いでした
● 適用時にエラーがいっぱい
● リソース競合の解消がめんどくさい
● サーバとの認証でエラーがでる
● 外部DSLがわかりにくい
etc.
弊社とPuppetのおつきあい
2010年
AWSの検証開始
とりあえずpuppetを選択
弊社とPuppetのおつきあい
2011年
AWSに移行
現在とおおむね同じPuppetの構成
● ENCは未使用(ノードの更新は手動)
● manifestの書き方がめちゃくちゃ
(スタイルガイドがなかった?)
弊社とPuppetのおつきあい
2011年
Puppetに嫌気が差していたので
Chefに移行しようとしていた
…が、諸事情により断念
弊社とPuppetのおつきあい
2012年
VPCに移行
Puppetまわりも刷新
● ENCの導入
● スタイルガイドに従ってリファクタリング
● 各種プラクティスに従って設計を変更
(継承廃止!)
現在のサーバ構成
● クライアントサーバ構成
● サーバ台数は500〜600台
● 基本的にすべてpuppetで管理
クライアント側の機能の比較
クライアント側の機能の比較
ディレクトリ構成
Puppet(クックパッドの場合)
├── lib
├── manifests
├── modules
│ ├── apache
│ │ ├── files
│ │ ├── manifests
│ │ └── templates
│ ├── nginx
│
├── roles
│ ├── app_server
│ │ ├── files
│ │ ├── manifests
│ │ └── templates
│ ├── db_server
│ │ ├── manifests
│ │ └── templates
│
└── types
Chef
├── cookbooks
│ ├── apache
│ │ ├── attributes
│ │ ├── definitions
│ │ ├── files
│ │ ├── libraries
│ │ ├── providers
│ │ ├── recipes
│ │ ├── resources
│ │ └── templates
│ └── nginx
│ ├── attributes
│ ├── definitions
│ ├── files
│ ├── libraries
│ ├── providers
│ ├── recipes
│ ├── resources
│ └── templates
├── data_bags
├── nodes
│ ├── app-001.json
│ └── db-001.json
├── roles
│ ├── app.json
│ └── db.json
├── site-cookbooks
└── solo.rb
クライアント側の機能の比較
ディレクトリ構成
● PuppetにChefのような
決められたディレクトリ構成はない
● ベストプラクティスを追求すると
似たような構成になると思います
クライアント側の機能の比較
モジュール(クックブック)とロール
Puppet
# manifest
class nginx {
package { 'nginx':
ensure => '1.2.2.1',
}
service { 'nginx':
ensure => running,
enable => true,
require => Package['nginx'],
}
file { '/etc/nginx/enginx.conf':
ensure => present,
source => template('...'),
owner => 'root,
...
notify => Service['nginx'],
}
}
# role
class app {
include nginx
file { '/etc/hosts':
...
}
}
Chef
# recipe
package 'nginx' do
action :install
version '1.2.2.1'
end
service 'nginx' do
action { :enable, :start }
end
template '/etc/nginx/nginx.conf' do
source 'nginx.conf.erb'
owner 'root'
mode 0644
notifies :reload , 'service[nginx]'
end

# role: app.json
{
"run_list": [
"role[nginx]"
]
}
クライアント側の機能の比較
モジュール(クックブック)とロール
Puppet
# カスタムタイプ
define sysctl($value) {
exec { "exec_sysctl_$name":
command => "sysctl -w $name=$value}",
unless => "sysctl -n ${name} | 
fgrep -q $value",
path => '/bin:/sbin:/usr/sbin:/usr/bin',
}
# ...
sysctl { 'kernel.domainname':
value => 'example.com',
}
Chef
# カスタムリソース
define :sysctl do
bash "exec-sysctl-#{params[:name]}" do
code <<-EOS
sysctl -w #{params[:name]=#{params[:value]}
EOS
not_if <<-EOS
sysctl -n ${params[:name]} | 
fgrep -q #{params[:value]}
EOS
end
end
# ...
sysctl 'kernel.domainname' do
value 'example.com'
end
クライアント側の機能の比較
モジュール(クックブック)とロール
● 基本的にはほとんど同じだと思います
○ 見えない人は3回瞬きしてください
● ChefのRuby DSLはうらやましいです
○ PuppetのRuby DSLはお亡くなりになります
○ 既存のDSLを拡張するようですが(何故…)
● ビルドインのリソースは
Chefのほうが充実しているかも
クライアント側の機能の比較
モジュール(クックブック)とロール
● Puppetのロールの実態はモジュールです
○ 単にモジュールをまとめるモジュールというだけ
● ロールにリソースを定義できるので、Chefよりも
やや柔軟かも
クライアント側の機能の比較
モジュール(クックブック)とロール
● ohaiの代わりにfacterというツールで
システム情報を収集します
クライアント側の機能の比較
モジュール(クックブック)とロール
● Puppetはリソース毎に依存性を定義します
○ 未定義の場合順番はランダム
○ 上から順に適用して欲しいこともあります…
● Chefは記述順に適用
○ リソース毎に依存性を定義できるのかは、
分かりませんでした(あったら教えてください)
クライアント側の機能の比較
Puppet独自の機能
Ruby DSLが使えないのは大変残念ですが
いくつかPuppet独自の機能があります
(便利かどうかはさておき)
クライアント側の機能の比較
継承
Puppet Style Guide
"Inheritance should be avoided."
class freebsd inherits unix {
File['/etc/passwd'] { group => 'wheel' }
File['/etc/shadow'] { group => 'wheel' }
}
クライアント側の機能の比較
継承
● 一言でいえば「使うな」
二言で言えば「死んでも使うな」
● 使って良いことはありません
○ リソース競合の解決が難しくなります
○ 仮想リソースという解決策もありますが…
■ http://gihyo.jp/admin/serial/01/puppet/0013
クライアント側の機能の比較
Parameterised Classes
● モジュールをテンプレートとして使えます
● Chefだとロールに属性を定義して
クックブックに渡す感じでしょうか?
# module
class apache($version) {
... class contents ...
}
# role
class webserver {
class { 'apache': version => '1.3.13' }
}
クライアント側の機能の比較
Run Stage
● 適用順を制御できます
● Chefで必要になる機能ではないですね…
stage { 'first': before => Stage['main'] }
stage { 'last': require => Stage['main']
}
class {
'apt-keys': stage => first;
'sendmail': stage => main;
'apache': stage => last;
}
クライアント側の機能の比較
Function
server-idを設定する関数
module Puppet::Parser::Functions
newfunction(:mysql_server_id, :type => :rvalue) do |args|
ip_addr = lookupvar('ipaddress')
ip_addr = IPAddr.new(ip_addr)
# IPアドレスは下位 16ビットを整数値として使う
ip_addr = (ip_addr.to_i & 0xFFFF)
server_id = '%02d%03d%05d' % [
0, # 0〜41の連番
392, # 国コード(http://ja.wikipedia.org/wiki/ISO_3166-1_numeric)
ip_addr,
]
# 先頭の0は削除
server_id.sub!(/A0+/, '')
return server_id
end
end
# my.cnf.elb
...
server-id = <%= scope.function_mysql_server_id %>
...
クライアント側の機能の比較
Function
● 共通で使う関数を定義できます
○ マニフェスト・テンプレート、どこでも使えます
● シンタックスは例に漏れずダサいです
● Chefはグローバル関数の定義場所が
よく分からなかったです…
クライアント側の機能の比較
まとめ
● Puppetは「Ruby DSLを使えないのがイけてな
い」に尽きると思います
● とはいえ似たような感じです
● Puppet独自の機能がありますが、だからといっ
てPuppetに優位性があるかは微妙です
● ある程度の機能差はそのうち埋まる気がします
クライアント側の機能の比較
たぶん両方で使えるTips
● モジュール(クックブック)は細かく分けましょう
● ミドルウェアのバージョンは極力書きましょう
● ミドルウェアのメジャーバージョンはモジュール
を分けましょう
● 設定ファイルの抽象化はロール単位でやるとよ
いです
クライアント側の機能の比較
たぶん両方で使えるTips
● まめに適用しないと腐ります
● オンラインで適用できるようにしておくと腐敗を
防げます
○ restart等を避けるなど
● Puppet configuration PatternsはChefでも参
考になると思います
● Chef/Puppetよりさらに前の処理を行うツールを
作っておくといろいろ捗ります
運用の機能の比較
運用の機能の比較
chef-solo
● puppet-applyというコマンドで同じようなことが
できます
● マニフェスト(レシピ)単位で指定するのでちょっ
と感じが違うかも
$ puppet apply -l /tmp/manifest.log manifest.pp
$ puppet apply --modulepath=/root/dev/modules -e "include ntpd::server"
$ puppet apply --catalog catalog.json
運用の機能の比較
knife
● knifeの代わりとしてcapistoranoでサーバへの
登録(というかデプロイ)を行います
● Puppetのサーバはファイル管理なので、デプロ
イの実装は簡単です
運用の機能の比較
knife-solo
● 同様の機能はPuppetにはありません…
● 手元のちょっとした修正を適用できるのが良さ
そうですね
○ knife-solo: レシピ修正→適用テスト→git push
○ puppet(C/S): レシピ修正→git push→適用テスト
運用の機能の比較
chef-server
Puppetのキラー機能 その①
puppet-master (サーバ)
● 情報をファイルで管理
● ファイルをサーバにただ置くだけ
● 変更はサーバが自動検知
● gitでそのままファイルを
管理・デプロイできる!
chef-server
gitで設定を管理すると…
● 特別なツールがいらない
● 他のツールと組み合わせやすい
● GitHubと組み合わせて
レビュー・pull reqできる!
運用の機能の比較
運用の機能の比較
chef-server
chef-server
● 情報をDBで管理
● 変更はknife経由だけ?
● バージョン管理はできるようですが…
○ diffとかとれるんでしょうか?
● gitとの組み合わせ事例も一応ありますね
運用の機能の比較
ノード管理
Puppetのキラー機能 その②
ENC(External Node Classifiers)
● ノード情報を動的に定義
● 変数(Chefの属性)も動的に定義
● EC2のAPIを使うことで
ノード管理をAWSに委譲できる!
運用の機能の比較
ノード管理
Chefの場合…
● 動的なノード定義の情報を探したのですが見つ
からず…
● EC2でサーバが増減する場合、どのように管理
しているのでしょうか?(cronで定期的に更
新?)
運用の機能の比較
chef-server+gitとENCについて
Opscodeが本気になれば、すぐに実装される気が
します。ただ、chef-serverは総合的なサーバ管理
ツールを目指しているように見受けられるので、ポ
リシー的にすぐに実装はされないかなーと
運用の機能の比較
chef-server+gitとENCについて
knife-soloで運用するのも手ですが、すべての情
報がrsyncで転送されるのが気になります…
(サーバ100台に適用、とか困りそうです)
運用の機能の比較
どなたかgitの使えるの
軽量chef-serverを
作るとよいと思います
運用の機能の比較
その他
● 「dry-runできないんだ、やーい」と思ってたら、
とっくに実装されてました…
● PuppetにもWeb UIはありますが、あんまり使っ
たことはないです
● Puppetでもそうなんですが、クライアントをデー
モン化してる方はいるんでしょうか?ものすごく
怖いのですが…
おまけ
おまけ
さくっと実装できそうだったので
chef-solo-encというのをつくりました
chef-soloでENC的な機能を実現します
おまけ
DEMO

More Related Content

ChefとPuppetの比較