resources

Puppet Wiki
http://www.reductivelabs.com/trac/puppet/wiki
Installation Guid
http://www.reductivelabs.com/trac/puppet/wiki/InstallationGuide
OSCON Presentation
http://www.reductivelabs.com/downloads/puppet/OSCON.pdf
Transitioning From Cfengine
http://www.reductivelabs.com/trac/puppet/wiki/TransitioningFromCfengine
Type Reference (必読)
http://www.reductivelabs.com/projects/puppet/reference/typedocs.html

Puppet って?

http://www.reductivelabs.com/trac/puppet/wiki/DocumentationStart

Puppet is a declarative language for expressing system configuration, a client and server for distributing it, and a library for realizing the configuration.

Puppet とは...

  1. システムの状態を表現するための宣言型の言語
  2. 設定を配布するためのクライアント、サーバプログラム
  3. 設定を実現するためのライブラリ

である。Puppet はすべて Ruby で実装されている。そのため、拡張が容易である。同種のソフトウェアに cfengine があるが、 C で書かれているため拡張が容易ではなかった。

Directory

/etc/puppet:

puppetd.conf など、各デーモンの設定ファイル。全ホスト共通。ただし、ほとんどの場合 puppet をパッケージシステム経由でインストールするときに用意されるし、更新したければ puppet を使えばよい。

/etc/puppet/manifests:

site.pp, functions.pp など。puppetmasterd が動いているホストのみ。

/var/lib/puppet:

puppetd が生成するファイルなどが置かれる。template もここ。puppetd が動いているマシンが主に使用する。

設定ファイルはいずれ subversion で管理する。cfengine とちがって、 設定ファイルは各ホストへ配布する必要はない。puppetd が接続時に puppetmasterd へ問い合わせ、自動的にアップデートされる。そのとき、ローカルキャッシュを /var/lib/puppet 以下へ保存する。cfengine ではこの動作も記述する必要があった。

つまり、 puppetmasterd のみ /etc/puppet/manifests 以下を保持する必要がある。よって、クライアント側に最低限必要なものは puppetmasterd が動いているホスト名のみとなる。この点は cfengine が最初に update.conf を必要とするところに比べて優れていると思う。

CfEngine との違い

1. How do all of these variables, like operatingsystem, get set?

http://www.reductivelabs.com/trac/puppet/wiki/FrequentlyAskedQuestions#id42

cfengine では、システムの状態に合せてハードクラスが自動的に設定された。puppetでそれに対応するのは facter が収集した情報ということのようだ。たとえば…

 # facter
architecture => i386
domain => osaka.tknetworks.org
facterversion => 1.3.5
fqdn => natsu.osaka.tknetworks.org
hardwareisa => Intel(R) Pentium(R) 4 CPU 1.60GHz
hardwaremodel => i686
hostname => natsu
id => nabeken
ipaddress => 10.0.5.12
kernel => Linux
kernelrelease => 2.6.18-gentoo-r4
macaddress => 00:90:FE:22:B0:89 EA:FE:EB:B8:9C:96 B6:99:DC:B0:FB:94
memoryfree => 458.47 MB
memorysize => 1010.11 MB
operatingsystem => Gentoo
operatingsystemrelease => 2.6.18-gentoo-r4
processor0 => Intel(R) Pentium(R) 4 CPU 1.60GHz
processorcount => 1
ps => ps -ef
puppetversion => 0.22.1
rubysitedir => /usr/lib/ruby/site_ruby/1.8
rubyversion => 1.8.5
swapfree => 499.82 MB
swapsize => 499.99 MB
uniqueid => 007f0100


となり、この対が puppet で使用できるデフォルトの変数となる。

puppetd vs cfexecd

puppetd はデフォルトでは 30 分毎に puppetmasterd へ問い合わせる。この数値は設定可能である。http://reductivelabs.com/projects/puppet/reference/configref.html

puppetd の引数に -o をつけると cfagent と同じ動作になる。

How to manage your home directory with Puppet

puppet の習得がてら自分のホームディレクトリの管理に使用してみます。いくつかリモートのシェル環境がある場合は環境を統一できます。私の場合、私物のマシンで4台、仕事でも数台シェル環境があります。それぞれ .zshrc などを手でちまちまコピーしているのですが、常にどこかで更新していて、正直もうどこが最新なのかよくわかりません。危ない兆候です。

puppet はシステム全体だけでなく、それよりも小さな領域、今回なら自分のホームディレクトリもマネージメントできます。それは信頼できるマシン上の自分の権限で puppetmasterd を動かすことに他なりません。subversion と組合せればなかなか強力な環境ができそうです。リモートでは puppetd を動かすか、定期的に puppetd -o を回すことになります。puppetでなくても、 svn co を適当に全マシンで回しても似たようなことができますが、それでは細かな制御ができません。Linuxでのものを BSD へそのまま持っていけるかどうかを考えてみてください。

…Ruby が入っているのが最低条件です。最近なら言えば入れてくれるのではないでしょうか。

puppetmasterd

まずは自分のホームディレクトリ上に puppetmasterd 用のディレクトリを作成します。

 $ mkdir .puppetmasterd
 $ cd .puppetmasterd
 $ cp /etc/puppet/puppet* .
 $ cat puppetmasterd.conf
[puppet]
    # Where Puppet stores dynamic and growing data.
    # The default value is '/var/puppet'.
    vardir = /home/nabeken/.puppetmasterd/var

    # The Puppet log directory.
    # The default value is '$vardir/log'.
    logdir = $vardir/log

    # Where SSL certificates are kept.
    # The default value is '$confdir/ssl'.
    ssldir = $vardir/ssl

[puppetd]
    # The file in which puppetd stores a list of the classes
    # associated with the retrieved configuratiion.  Can be loaded in
    # the separate ``puppet`` executable using the ``--loadclasses``
    # option.
    # The default value is '$confdir/classes.txt'.
    classfile = $vardir/classes.txt

    # Where puppetd caches the local configuration.  An
    # extension indicating the cache format is added automatically.
    # The default value is '$confdir/localconfig'.
    localconfig = $vardir/localconfig


[puppetmasterd]

    masterport = 9999
 $ cat .puppetmasterd/fileserver.conf
 This file consists of arbitrarily named sections/modules
# defining where files are served from and to whom

# Define a section 'files'
# Adapt the allow/deny settings to your needs. Order
# for allow/deny does not matter, allow always takes precedence
# over deny
[home]
  path /home/nabeken/.puppetmasterd/dist
  allow 10.3.0.0/16
  allow 10.0.0.0/24
  allow 2001:3e0:4dd::/42
  allow 2001:380:e03:61::/64
  allow 127.0.0.1/32


とりあえず、簡単な例として、 zsh, bash にしてみた。たぶん、もっと賢く書けば短かくなるんだと思うけど…。.puppetmasterd/dist は適当なリポジトリの working copy としておく。

 $ cat .puppetmasterd/manifests/site.pp                                                                      ~

class zsh {
        file { "/home/$id/.zshrc":
                owner  => $id,
                group  => users,
                mode   => 0600,
                source => "puppet://risa.osaka.tknetworks.org:9999/home/.zshrc",
                require => Exec["update"]
        }

        file { "/home/$id/.zshenv":
                owner  => $id,
                group  => users,
                mode   => 0600,
                source => "puppet://risa.osaka.tknetworks.org:9999/home/.zshenv",
                require => Exec["update"]
        }

        file { "/home/$id/.zsh-hosts":
                owner  => $id,
                group  => users,
                mode   => 0600,
                source => "puppet://risa.osaka.tknetworks.org:9999/home/.zsh-hosts",
                require => Exec["update"]
        }
}

class bash {
        file { "/home/$id/.bashrc":
                owner  => $id,
                group  => users,
                mode   => 0600,
                source => "puppet://risa.osaka.tknetworks.org:9999/home/.bashrc",
                require => Exec["update"]
        }

        file { "/home/$id/.bash_profile":
                owner  => $id,
                group  => users,
                mode   => 0600,
                source => "puppet://risa.osaka.tknetworks.org:9999/home/.bash_profile",
                require => Exec["update"]
        }
}

node default {
        include zsh
        include bash
}

node risa inherits default {
        exec { "update":
                command => "svn update",
                cwd => "/home/$id/.puppetmasterd/dist/",
                path => "/usr/bin"
        }
}