オープンソースなシステム自動管理ツール Puppet

第6回Puppet実践テクニック(その1)

前回までの内容で、Puppetでのシステム管理の肝となるマニフェストについて一通り解説しました。今回から、Puppetを実践で利用するために必要となる、様々なテクニックについて解説していきます。

Puppetの設定

Puppetは特に設定をしなくても、最低限マニフェストさえあれば動作するため、今まで特に設定についての解説はしてきませんでしたが、実践で利用するためには何らかの設定が必要となりますので、Puppetの設定方法について解説します。

コマンドオプションでの設定

設定パラメータをコマンドオプションで指定するには、以下のように実行します。

$ sudo puppetmasterd --confdir=/private/puppet

利用可能なパラメータとそのデフォルト値は、以下のようにコマンドオプションに--genconfigを指定することで確認することができます。

$ puppetd --genconfig | less

--genconfigの出力は以下のようになります(一部のみ抜粋⁠⁠。

[puppetd]
    # Where Puppet stores dynamic and growing data.  The default for this parameter is calculated specially, like `confdir`_.
    # The default value is '/var/puppet'.
    # vardir = /var/puppet

設定ファイルでの設定

設定ファイルは0.23.xでは/etc/puppet/puppet.confというファイルであり、[main]、[puppetd]、[puppetmasterd]といったセクションに分かれています。

[main]
    confdir = /etc/puppet

[puppetd]
    usecacheonfailure = true

[puppetmasterd]
    manifestdir = $confdir/manifests         
    manifest    = $manifestdir/site.pp

[main]セクションにあるパラメータはすべてのコマンドに共通のパラメータを指定します。その他のセクションは、各コマンド特有のパラメータを指定します。例えば、[puppetd]セクションはpuppetd コマンド特有のパラメータ、[puppetmasterd]セクションはpuppetmasterdコマンド特有のパラメータを指定します。また、 [fileserver]など、コマンドではなく機能別のセクションもあります。

上の例の通り、$confdir、$manifestdirといった形で、設定ファイル中で定義されたパラメータを、別な箇所で参照することが可能です。

0.22.x以前では、設定ファイルはコマンド毎に異なり、puppetdの場合は/etc/puppet/puppetd.confを、 puppetmasterdの場合は/etc/puppet/puppetmasterd.confをデフォルトで参照します。 puppetmasterd.confは以下のようになり、セクションはありません。

confdir     = /etc/puppet  
manifestdir = $confdir/manifests         
manifest    = $manifestdir/site.pp

0.23以降でも、0.22.x以前と同様コマンド毎に異なる設定ファイルを持つこともできますが、推奨されていません。

Puppetへのアクセスコントロール

puppetdやpuppetmasterdへのアクセスをコントロールするためには、namespaceauth.confという設定ファイルを利用します。以下はpuppetdからpuppetmasterdへのアクセスをコントロールするための設定例です。

# puppetdからのマニフェスト取得アクセスのコントロール
[puppetmaster]
    allow *.example.org
    deny  deny.example.org

# puppetdからのレポート通知アクセスのコントロール
[puppetreports]
    allow *.example.org
    deny  deny.example.org

# puppetdからのファイルサーバ機能へのアクセスコントロール
[fileserver]
    allow *.example.org
    deny  deny.example.org

このファイルが存在しない場合、デフォルトですべてアクセス許可となるのですが、このファイルが存在する場合には、たとえファイル内に何も記述されていなくても、デフォルトですべてのアクセスが拒否されます。このように、ファイルが存在しない場合と、ファイルが存在するが空の場合とで、 Puppetの挙動が異なるのでご注意ください。

自動署名

第2回でも解説したように、通常、Puppetクライアントの証明書に対する署名は、Puppetサーバ側で手動で行いますが、 /etc/puppet/autosign.conf というファイルに、以下のように自動署名の対象となるホスト名を列挙することで、該当するホストからの署名リクエストに対して自動で署名することができます。

client.example.org
*.example.com

プロバイダ

Puppetのリソース抽象化レイヤで中心的な役割を担っているのがプロバイダと呼ばれるものです。

リソース抽象化レイヤでは、管理対象となるリソースを具体的な実装から分離しているわけですが、その具体的な実装部分を裏側で処理しているのが、プロバイダと呼ばれるRubyのクラスやモジュールです。

プロバイダはリソースタイプごとに決まっており、通常はシステムに適したものが自動的に選択されます。たとえば、packageリソースタイプの場合、 apt、gem、portage、ports、up2date、yumなど、様々なプロバイダがありますが、Debian/GNU Linuxがインストールされたシステムであればaptが自動で選択されます。

ですがPuppetも完璧ではないため、適切なプロバイダが自動で選択できない状況というのも発生します。そういった場合、以下のようにマニフェストで明示的にプロバイダを指定する必要があります。

package { 'ntp':
    provider => 'yum',
    ensure   => 'present',
}

また、リソースタイプごとにデフォルトのプロバイダを指定しておけば、個別のリソースでプロバイダを指定する手間が省けます。

# packageリソースタイプのデフォルトプロバイダを指定
Package { provider => 'yum' }

# 以下のpackageリソースではプロバイダにyumが利用される
package {
    'ntp':
        ensure => 'present';
    'sudo':
        ensure => 'present';
}

execリソースタイプ

execリソースタイプはその名の通り、何らかのコマンドを実行するためのリソースを宣言する場合に利用します。

しかし、マニフェストは実行するものではなく適用するものであり、アクションを記述するものではなく状態を記述するもの、というのが、Puppet におけるシステム管理の哲学だと筆者は考えていますので、execリソースタイプはどうしても他のリソースタイプでは要件に合わない、という場合にのみ利用するべきです。また、実行するコマンドも、何らかのアクションを行うためではなく、システムを何らかの状態に導くために実行するものである、という視点でリソースを宣言するのがPuppetでシステム管理を行うための重要なポイントです。

以下のマニフェストは、mysql-serverパッケージをインストールし、パスワードがセットされた状態にするためのマニフェストです。⁠パスワードをセットする」のも「パスワードがセットされた状態にする」のも、結果としては同じことを実行していますが、アクションではなく状態という視点を持つことが、Puppetでのシステム管理では重要です。

class mysql-server {
    $password = 'password'
    package { 'mysql-server': ensure => installed }

    service { 'mysqld':
        ensure    => running,
        subscribe => Package['mysql-server'],
    }
 
    exec { 'Set MySQL server root password':
        subscribe   => Package['mysql-server'],
        require     => Service['mysqld'],
        refreshonly => true,
        unless      => "mysqladmin -uroot -p$password status",
        path        => '/bin:/usr/bin',
        command     => "mysqladmin -uroot password $password",
    }
}

ファイルサーバ

puppetmasterdが持っているファイルサーバ機能を利用して、Puppetクライアントへファイルを配布することができます。

ファイルを配布するためのマニフェストは以下のようになり、Puppetサーバ上のファイルが置かれているパスを、puppet://...といったURLでsourceパラメータにセットします。

file { '/etc/sudoers':
    mode   => 440,
    owner  => 'root',
    group  => 'root',
    source => 'puppet://server.example.org/dist/etc/sudoers',
}

Puppetサーバ側では以下のように、/etc/puppet/fileserver.confを設定する必要があります。この例では、puppet: //server.example.org/distというURLを/var/puppet/distディレクトリにマップしています。したがって、 puppet://server.example.org/dist/etc/sudoersで /var/puppet/dist/etc/sudoersを取得できるようになります。

[dist]
    path /var/puppet/dist
    allow client.example.com

単一のファイルではなく、特定のディレクトリ以下のファイルを再帰的に配布したい場合には、以下のようにrecurseパラメータにtrueを指定します。

file { '/etc/httpd/conf.d':
  source  => 'puppet://server.example.org/dist/etc/httpd/conf.d
  recurse => true,
}

実践テクニックは更に次回に続きます。

おすすめ記事

記事・ニュース一覧