SlideShare a Scribd company logo
(株) paperboy&co. 宮下 剛輔 2009/12/3
自己紹介 宮下 剛輔 mizzy, id:MIZZY gosukenator(twitter, gmail) http://mizzy.org/ ペパボで技術責任者というのをやってます 子だくさん 11/24 に 4 人目が生まれました 主に Perl 界隈で活動してます が、最近停滞気味… ドクターペッパー好きとして一部で知られてます
 
 
アジェンダ エラー通知 ノード情報管理 クラス exec リソース モジュール化 最近の機能追加
 
エラー通知 Puppet にはエラーだけ通知する仕組みがない? tagmail は特定のクラスに関するログの通知先アドレスを指定できるが、エラーのみ通知、ということができない 正常なログを送ってもらってもうざいだけ なので、別の方法を考える syslog 設定で、 err  以上のレベルのログを分離してやると、あとはどうにでもできる
エラー通知 puppet.conf [puppetd] syslogfacility = local0 syslog.conf local0.err;local0.crit;local0.alert;local0.emerg /var/log/puppet/error.log
 
ノード情報管理 最初は LDAP でやってみた イマイチだった LDAP でノード管理するメリットがあまりない LDAP に精通してる人がいない
ノード管理 現在は Cobbler を利用 Cobbler ではノード情報の登録が必須で、それを Puppet にも流用できて一石二鳥 Cobbler は dnsmasq と連携できるので、 DNS/DHCP にもノード情報が使える cobbler-ext-nodes コマンドが付属していて、即 Puppet と連携できる
external nodes 設定 /etc/puppet/puppet.conf での設定 [puppetmasterd] external_nodes  = /usr/bin/cobbler-ext-nodes node_terminus   = exec
cobbler-ext-nodes コマンド 以下のような情報を返す $ cobbler-ext-nodes smtp.lolipop.jp classes :  [base, smtp] parameters : {from_cobbler: 1, tree: 'http://@@http_server@@/cblr/links/CentOS5.3-x86_64'}
 
クラスの分け方 サーバの役割別 サーバの役割に応じたクラス分け 粒度は大きめ web, app, batch, storage, db-master, db-slave, reverse-proxy メリット サーバの役割をひとつにしておけば、 include  するクラスはひとつなので、リソースの重複がない デメリット 一時的に別の役割も兼ねる、といったことが柔軟にできない 重複しやすそう
リソースの重複 class   web  { package  { ‘httpd’: ensure => present } } class   reverse-proxy  { package  { ‘httpd’: ensure => present } } node   hoge  { include  web, reverse-proxy ↑ httpd リソースが重複して怒られる }
もう一つのクラスの分け方 機能別 役割よりも更に粒度を小さく機能に分解 httpd, smtpd, storage-api, storage-tracker, storage-node メリット リソースが重複しにくいので、一時的に別の役割を兼ねる、といったこともやりやすい アクセスが少ないうちは兼用、増えたら兼用をやめる、といったことができる デメリット リソース重複しないようにマニフェスト定義するのが面倒 virtual リソースを使いまくることになる
 
exec 脳の恐怖 構築の自動化をスクリプトでやってると、 Puppet を導入しても、何でも exec で実行してしまおうとする exec で実行してしまうと、何度実行しても同じ結果になる、という保証がないので危険 マニフェストは「実行」するものではなく「適用」するもの、と捉えるべき exec を濫用するとマニフェストのメンテもしづらくなる
exec を濫用したマニフェスト exec  {  'sysctl add': command  =>  'echo "net.ipv4.netfilter.ip_conntrack_max = 131072" >> /etc/sysctl.conf && /sbin/sysctl -p', onlyif  =>  "test -f /etc/sysctl.conf", unless  =>  "grep 'net.ipv4.netfilter.ip_conntrack_max' /etc/sysctl.conf 2>/dev/null" }
exec を適切に利用したマニフェスト file  {  '/etc/sysctl.conf': ensure   =>  present, source   =>  "puppet://$server/sysctl.conf", } exec  {  '/sbin/sysctl -p': subscribe   =>  File['/etc/sysctl.conf'], refreshonl y =>  true, }
 
モジュール化で使えるテクニック http://trombik.mine.nu/~cherry/w/   の trom bik さんに教えて頂いたテクニック モジュールでデフォルト値を定義しつつ、ノード固有の値で上書きしようとすると、普通のやり方では怒られるので、それを回避する方法をご紹介
モジュールの定義 class   apache_defaults  { $ssl  =  true } class   apache   inherits   apache_config  { $ssl_flag  =  $ssl  ? { false   => "", default  => "-DSSL" } ... }
ノード定義でデフォルト値を上書き node   "sample1.example.com"  { class   apache_config   inherits   apache_defaults  { $ssl  =  false } include   apache }
デフォルト値を使う場合 node   "sample1.example.com"  { class   apache_config   inherits   apache_defaults  { } include   apache }
ノード定義内でのクラス定義 この方法は、ノードをファイルで管理してる場合じゃないと使えない なので、 external-nodes  では使えない
 
ノード定義で正規表現が利用できる 0.25.0 からの機能 node   /^www+$/  { include   common }
配列への追加 0.24.6 からの機能 $ssh_users  = [ 'myself' ,  'someone' ] class   test  { $ssh_users  += [ 'someone_else' ] }
セレクタでの正規表現とキャプチャ 0.25 からの機能 $system  =  $operatingsystem  ? { /(redhat|debian)/ =>  "our system is  $1 " , default =>  "our system is unknown" , }
ケースでの正規表現とキャプチャ 0.25 からの機能 case  $hostname { /^j(ack|ill)$/ :   { notice( "Welcome  $1 !" ) } default :  { notice( "Welcome stranger" )   } }
if での比較演算 0.24.6 からの機能 if  $server  ==  "mongrel"  { include   mongrel } else { include   nginx }
 

More Related Content

Puppet Best Practices? at COOKPAD