More Related Content Similar to Puppetのススメ (20) More from Gosuke Miyashita More from Gosuke Miyashita (20) Puppetのススメ2. 自己紹介 宮下 剛輔 mizzy, id:MIZZY gosukenator(twitter, gmail) http://mizzy.org/ ペパボで技術責任者というのをやってます インフラからウェブ開発まで広く見てます 子だくさん 2009/11/24に4人目が生まれました 12. なぜPuppetが必要か? 他の自動化手法に伴う問題 カスタムスクリプトでの自動化 解読、メンテが大変 自由度が高すぎて、書く人のスキルの差によるばらつきが大きい HDDイメージ複製、PXEブート+NFS、rsyncといった手法 複数OS、複数の役割を持つサーバが混在した環境では、一括管理が難しい サーバによって異なる部分をどう吸収するか? Apache の ServerName、MySQLの server-id など 22. リソースの定義 リソースタイプ リソースのタイトル リソースの属性 file { '/etc/hosts': owner => $default_owner, group => $default_group, mode => 644, source => 'puppet://server/module/hosts', } /etc/hosts を puppetサーバから取得し、オーナー、グループ、モードを適切に設定するためのリソース定義 これ全体が「リソース」 23. クラスでリソースをまとめる 「sudo」クラスを定義 class sudo{ package { ‘sudo’: ensure => latest, alias => sudo } file { ‘/etc/sudoers’: source => 'puppet://server/module/sudoers', mode => 440, owner => $default_owner, group => $default_group, alias => sudoers } } node ‘mail.hoge.com’ { include sudo } package リソース file リソース クラスをノードに適用 24. クラスを継承する base クラスを定義 class base { file { "/my/file": content => template("base.erb") } } class sub inherits base { # override the content File["/my/file"] { content => template("other.erb") } } base クラスを継承した sub クラスを定義 base クラスの /my/file リソースの属性を上書き 25. リソースの依存関係 file { '/etc/ssh': source => puppet://server/module/ssh, recurse => true, notify => Service[ssh] } service { 'ssh': name => sshd, ensure => running, subscribe => File[‘/etc/ssh’] } /etc/ssh以下のファイルに変更があれば、sshサービスリソースに再起動を促す /etc/sshリソースに変更があれば、サービスを再起動する notifyかsubscribeのどちらか一方だけ定義すればOK 32. マニフェスト適用(クライアント/サーバ版) サーバ起動 # /usr/sbin/puppetmasterd --verbose br /> --no-daemonize --nonodes info: Starting server for Puppet version 0.24.8 info: Listening on port 8140 notice: Starting Puppet server version 0.24.8 33. マニフェストを適用(クライアント/サーバ版) クライアントで適用 # /usr/sbin/puppetd --server puppet.hoge.com br />--no-daemonize --verbose --onetime info: No classes to store info: Caching catalog at /var/puppet/state/localconfig.yaml notice: Starting catalog run notice: //File[/etc/passwd]/mode: mode changed '777' to '644' notice: Finished catalog run in 0.03 seconds 42. Apacheマニフェスト package { ‘httpd’: ensure => installed } service { ‘httpd’: enable => true, ensure => running, require => Package[‘httpd’], } 43. Apacheマニフェスト(つづき) file { ‘/etc/httpd/conf.d/hoge.conf’: source => “puppet://$server/hoge.conf”, notify => Service[‘httpd’]; ‘/etc/httpd/conf.d/fuga.conf’: source => “puppet://$server/fuga.conf”, notify => Service[‘httpd’]; } 53. iptablesモジュールの利用例 include'iptables' file { '/etc/iptables.d/filter': content => template('filter'), notify => Exec["rebuild_iptables"]; '/etc/iptables.d/nat': content => template('nat'), notify => Exec["rebuild_iptables"]; } 63. LDAPによるノード情報管理 puppetrun –all とか –class オプションの利用には、LDAPでノード情報を管理する必要がある でも、あまりお勧めしない。めんどうだけどあまりメリットない。 puppetrun –all や –class 相当のことがしたければ、スクリプト組むのがよい 65. execを濫用したマニフェスト exec { 'sysctl add': command => 'echo "net.ipv4.netfilter.ip_conntrack_max = 131072" >> /etc/sysctl.conf br /> && /sbin/sysctl -p', onlyif => "test -f /etc/sysctl.conf", unless => "grep 'net.ipv4.netfilter.ip_conntrack_max' /etc/sysctl.conf 2>/dev/null" } 68. Facter変数 $ facter architecture => x86_64 domain => hoge.com facterversion => 1.5.7 fqdn => puppet.hoge.com hardwareisa => x86_64 hardwaremodel => x86_64 hostname => h026 id => miya interfaces => eth0,eth1,sit0 ipaddress => 192.168.10.26 ipaddress_eth0 => 192.168.10.26 ipaddress_eth1 => 192.168.122.106 is_virtual => false ... 75. 想定通りに動かない例 classbase_class { $myvar = 'bob' file {"/tmp/testvar": content => "$myvar", } } classchild_classinheritsbase_class { $myvar= 'fred' } 76. 想定通りにするには $myvar= ‘bob‘ classbase_class { file {"/tmp/testvar": content => "$myvar", } } classchild_class { $myvar= 'fred‘ includebase_class } ただし、$myvarがグローバルになる 77. 想定通りにするには(別パターン) classbase_class { $myvar = 'bob' file {"/tmp/testvar": content => "$myvar", } } classchild_classinheritsbase_class { $myvar= 'fred‘ File[‘/tmp/testvar’]{ content => "$myvar“ } } ただし、記述が冗長 79. 理想的な例 classfile { $var= ‘hoge’ file { ‘/tmp/file’: content => $var } } classfile_fugainherits file { $var= ‘fuga’ } 86. 内部DSL実装 マニフェストは外部DSL 内部DSL実装も実はある Ruby DSL http://reductivelabs.com/trac/puppet/wiki/RubyDSL あまり使われてないって書いてある ShadowPuppet http://reductivelabs.com/trac/puppet/wiki/ShadowPuppet 87. ShadowPuppet class ManifestExample< ShadowShadow::Manifest recipe :sample recipe :mysql, { :root_password=> 'OMGSEKRET' } defsample exec :foo, :command => '/bin/echo "foo" > /tmp/foo.txt' package :foo, :ensure => :installed file '/tmp/example.txt', :ensure => :present, :contents => Facter.to_hash_inspect end def mysql(options) ... end end 93. リソースタイプに微妙なものが リソースタイプには、file, user, group, package, service, cron といったものがある 上の例は、割りとOSに普遍的なものだけど、中にはnagios_command, nagios_contact, nagios_hostといった、Nagios固有のものがある。(Nagios固有のタイプで14もあり、リファレンスの中でも目立ってる) アプリケーション固有のものは、コアに入れないでモジュールにした方がいいのでは?