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

第7回Puppet実践テクニック(その2)

前回に引き続き、Puppetを実践で利用するためのテクニックについて解説します。

puppetrunの使い方

Puppetのデフォルトの動作は、puppetdが30分に1回puppetmasterdにマニフェストを取得しに行き、自分自身へマニフェストを適用します。この場合、puppetdがpuppetmasterdにアクセスするタイミングを制御することが難しいため、次のような懸念があります。

  • Puppetクライアントが数百台あるいはそれ以上の規模になった場合に、Puppetサーバへのアクセスが同時間帯に集中する恐れがある
  • 新しいマニフェストをとりあえず1台だけに適用してテストしてみたい、といった場合でも、全サーバに勝手に適用されてしまう恐れがある

この問題に対処するためには、puppetrunを利用してPuppetを運用する必要があります。

puppetrunはPuppet付属のコマンドラインツールで、puppetdを始動する(マニフェストの取得と適用を促す)ことによって、任意のタイミングでPuppetクライアントにマニフェストの取得と適用を行わせることができます。

puppetrunを利用するためには、事前にいくつかの設定が必要です。

事前に必要な設定

Puppetサーバ側の設定
Puppetサーバ側では特に設定の必要はありません。
Puppetクライアント側の設定
Puppetクライアント側では、puppetrunを実行してpuppetdへ接続してくるホストに対し、以下のように/etc/puppet/namespaceauth.confで、アクセスの許可/拒否を設定します。
[puppetrunner]
    allow server.example.org
    allow *.example.com
    deny  *.example.net

puppetd/puppetmasterdの起動とpuppetrunの実行

puppetdの起動
Puppetクライアント側で以下のようにpuppetdを起動します。--listenオプションをつけることで、puppetrunからの接続を受け付けます。--no-clientオプションをつけることで、puppetrunから始動されない限り、puppetmasterdに接続しに行かなくなります。
$ sudo puppetd --verbose --server server.example.org --listen --no-client
puppetmasterdの起動
Puppetサーバ側でpuppetmasterdを起動します。特別なオプションは必要ありません。
$ sudo puppetmasterd --verbose
puppetrunの実行
Puppetサーバ側でpuppetrunを実行します。特にエラーがなければ、exit code 0と表示して終了します。
$ sudo puppetrun --host client.example.org
Triggering client.example.org
client.example.org finished with exit code 0
Finished

puppetrunのオプション

puppetrunの代表的なオプションは以下の通りです。

オプション名 説明利用例
host始動する対象となるホスト。複数指定可。--host a.example.org --host b.example.org
all管理対象のホストすべてを始動します。⁠LDAPでノード管理している場合のみ)--all
class特定のクラスをインクルードしているホストのみ始動します。⁠LDAPでノード管理している場合のみ)--class web
parallel同時に始動するホストの数。デフォルトは1。--parallel 5
tag特定のタグがついたリソースのみを適用する。--tag maintenance

テンプレート

前回解説したファイルサーバ機能では、どのPuppetクライアントにも同じ内容のファイルが配布されるのに対し、テンプレート機能では、Puppetクライアントの条件に応じて、内容が異なるファイルをクライアント毎に作成することができます。

テンプレートの利用例として、各PuppetクライアントにServerNameが異なるApacheのhttpd.confを作成することを考えてみましょう。

まず、以下のようなERBテンプレートファイルを作成します。ERBについての詳細はRubyist Magazine 0020号 標準添付ライブラリ紹介【第10回】ERBをご参照ください。テンプレートファイルは、/var/puppet/templatesの下に置きます。テンプレートを置くディレクトリは、設定で変更することも可能です。

# ServerName gives the name and port that the server uses to identify itself.
# This can often be determined automatically, but we recommend you specify
# it explicitly to prevent problems during startup.
#
# If your host doesn't have a registered DNS name, enter its IP address here.
#
ServerName <%= fqdn %>:80

ERBテンプレートファイルには、<%= var %>のような形で、マニフェストで定義された変数や、Facter変数を埋め込むことができます。上の例では、ServerNameにFacter変数$fqdnをセットしています。

テンプレートファイルが用意できたら、以下のようなマニフェストを記述します。template()関数の引数には、テンプレートファイルの/var/puppet/templatesからの相対パスか絶対パスを指定します。このようにtemplate()関数を実行することにより、contentパラメータにはテンプレート処理されたファイルの内容がセットされ、この内容を持つ/etc/httpd/conf/httpd.confがPuppetクライアント上に作成されます。

file { '/etc/httpd/conf/httpd.conf':
    content => template('etc/httpd/conf/httpd.conf'),
} 

タグ

リソースのメタパラメータであるtagを利用することにより、マニフェストの一部のみをシステムに適用することができます。

リソースにタグを指定するには、まずは以下のようにマニフェストを記述します。

file { '/etc/hosts':
    owner => 'root',
    group => 'root',
    mode  => 644,
    tag   => 'hosts',
}

file { '/etc/sudoers':
    owner => 'root',
    group => 'root',
    mode  => 440,
    tag   => 'sudoers',
}

そして、puppetdやpuppetrunの実行時に、オプションで以下のようにタグを指定します。puppetdとpuppetrunでは、微妙にオプションの名前や、複数タグの指定のしかたが異なるので、ご注意ください。

# puppetdでのタグの指定
$ sudo puppetd --tags hosts,sudoers
# puppetrunでのタグの指定 パターン1
$sudo puppetrun --tag hosts,sudoers
# puppetrunでのタグの指定 パターン2
$sudo puppetrun --tag hosts --tag sudoers

また、クラスや定義済みタイプ内のリソースには、自動でクラス名や定義済みタイプ名と同じタグがつけれます。したがって以下のマニフェストでは、明示的にタグは指定されていませんが、すべてのリソースにsshというタグがつけられています。

class ssh {
    package { 'sshd': ensure => present }
    service { 'sshd': ensure => running }
}

モジュール

モジュールとは、特定の目的を実現するためのマニフェスト、テンプレート、ファイルのセットを、再利用/再配布可能な形にまとめたものです。

モジュールのディレクトリ/ファイル構成は、以下のようになります。

MODULE_PATH/
   module_name/
      README
      manifests/
         init.pp
      templates/
      files/

MODULE_PATHはデフォルトでは/etc/puppet/modulesと/usr/share/puppet/modulesとなっており、どちらかのディレクトリの下に個別のモジュールを置きます。

マニフェストからモジュールを呼び出すには、以下のように記述します。

import 'autofs'               # MODULE_PATH/autofs/manifests/init.ppを呼び出す
import 'autofs/init.pp'       # 上と同じ
import 'autofs/util/stuff.pp' # MODULE_PATH/autofs/manifests/util/stuff.ppを呼び出す

Puppet本家WikiのPuppet Modulesでは、TracモジュールやXenモジュールなどといったモジュールが配布されていますので、ご参照下さい。

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

おすすめ記事

記事・ニュース一覧