ネットワーク上でのシステム管理を容易にするPuppet

  Puppet を利用すれば、システム管理コマンドを1台または複数のマシンに対して発行することができ、ディストリビューションによる環境の違いにも対応できる。たとえば、MySQLをインストールする場合にはこうした管理上の操作が重要になるが、インストール先マシンのディストリビューションがMaemoなのかUbuntuなのか、あるいはFedoraなのかを気にしなくても済むのだ。

 自宅にはデスクトップマシンと場合によってはサーバマシンもあり、それ以外に1、2台のノートPC、さらにLinuxベースの携帯電話やモバイルインターネット端末(MID:Mobile Internet Device)まで持っているLinuxユーザは少なくない。すべてのLinuxマシンに対して1つ変更を加えるだけでも、手作業で行うとそれなりの負担になる。この作業をいっそう面倒にしているのが、MIDとノートPCとの間のLinuxディストリビューションの違いだ。

 Puppetでは、実行したいシステム管理タスクを宣言型言語で記述することにより、システムのハードウェアアーキテクチャやLinuxディストリビューションの違い、あるいは特定のマシンのどこにApacheのDocumentRootがあるかといったことを考慮しなくても済む。Puppetはクラス(class)をはじめとする多くの機能を持ち、記述されたシステム管理タスクの実行時に環境ごとの細かな違いを吸収することができるのだ。

 Puppetの宣言型言語は、最大の強みであると同時に最大の弱みでもある。導入にあたっては新たな言語とやり方を覚えなければならず、その過程は学習曲線を描く。クラスとリソースが抽象化されていることもPuppetの習得を困難にしている。そもそも、大半のシステム管理者はbashスクリプトを利用してシステム管理を行うのに慣れている。無意識のうちにsshによるやり方が思い浮かぶようなタスクを実行するのに、わざわざ新しい言語を覚えなければならないことがPuppet導入の妨げとなる。

 システム管理タスク用にカスタマイズされた言語を使えば、タスクを安全に繰り返し実行可能なものにできる。多くのシステム管理用スクリプトは次の処理に進む前に確認のための入力を求めてくるが、Puppetはこうしたチェックも代わりにやってくれる。

 Puppetでは、クライアントサーバモデルが採用されている。puppetmasterdデーモンと呼ばれるサーバが、どのシステム管理タスクを実行すべきかをクライアント側に伝える役割を果たす。HardyのUniverseリポジトリには、Puppetのクライアントサーバが別々にパッケージ化されている。また、Fedora 9にはpuppetとpuppet-serverとして、openSuse 11にも1-Clickインストールに対応したクライアントとサーバの各パッケージが用意されている。以下では、64ビット版Fedora 9マシンを使い、FedoraのパッケージリポジトリからPuppetのバージョン0.24.4を入手してインストールを行う。

 Fedora用の各パッケージはpuppetクライアントとそのサーバデーモンをインストールしてくれるが、これらのサービスは自動的には起動されず、ブート時の起動もスケジューリングされていない。そこで、以下のコマンドにより、システムのブート時に自動で立ち上がるようにすると共にpuppetサービスの起動を行う。

# chkconfig --add puppetmaster
# chkconfig --add puppet
# service puppetmaster start
# service puppet start

 Puppetを利用する新しいクライアントマシンの最初のセットアップでは、サーバへの接続とSSL証明書への署名要求をクライアントに行わせる必要がある。クライアントでこの処理を実行した後、サーバ側でクライアントの証明書への署名を行う。これで、このクライアントでpuppetサービスが利用できるようになるはずだ。この手順の詳細はインストール作業の解説ページに記載されている。

 Puppetクライアントには、puppetmasterサーバがどこで稼働しているかを教えてやる必要がある。なお、今回はサーバとクライアントを同じマシン上で実行している。ここではサーバ名を直接指定したが、サーバ名を「puppet」のままにしておいてDNSのCNAMEを使ってクライアントが実行時にサーバのアドレスを解決できるようにする方法を勧めるPuppetユーザもいる。

vi /etc/sysconfig/puppet
...
PUPPET_SERVER=virtualfed9

Puppetの利用方法

 この記事向けのちょっとしたサンプルとして、設定ファイルの所有者、グループ、パーミッションを管理する、というタスクを取り上げる。まずは次のようにして、所有者、グループ、パーミッションが適切に設定されていないサンプルファイルを用意する。これがPuppetによってどのように修正されるかを確認するわけだ。

# touch /etc/puptest
# chown ben.ben /etc/puptest
# l /etc/puptest
-rw-r--r-- 1 ben ben 0 2008-07-17 20:01 /etc/puptest

 続いて「/etc/puppet/manifests」にマニフェスト(manifest)ファイルを作成して、Puppetに何を行わせるのかを記述する。通常は、クライアントのホスト名に応じてほかのマニフェストファイルをインポートする「site.pp」というマニフェストを用意する。クライアントごとに特定の設定を行うことも、多数のホストで使われる汎用のマニフェストをインポートすることもできる。「site.pp」によってインポートされるマニフェストファイルは普通「classes」サブディレクトリに置かれる。Puppetでは、システムをどのように設定したいのかを記述するのにクラスを用いる。また、クラスによって設定の論理的なグループ化が可能になる。

 以下に示す2つのサンプルマニフェストファイルは、Puppetのスタートガイドにあるものをベースにしている。「site.pp」マニフェストファイルは、「classes」サブディレクトリ内にあるその他すべてのマニフェストファイルをインポートするが、そのうちノード(node)エントリで明示的に使われているものだけが効力を持つ。この例では、接続しているすべてのPuppetクライアントに「puptest.pp」ファイルで指定されたパーミッションが適用される。puppetmasterdマシン上にある「site.pp」ファイルのノードエントリには、接続している各マシンに設定したい内容を定義する。たとえば「node "www.example.com"」というエントリは、このドメイン名から接続しているPuppetクライアントだけに適用される。通常、Puppetクライアントの名前はホスト名と同じである。ノード名の詳細については、ドキュメントの「node_name」の項を参照してほしい。

# mkdir -p /etc/puppet/manifests/classes
# cd /etc/puppet/manifests/classes
# vi puptest.pp
class puptest {
    file { "/etc/puptest":
        owner => "root",
        group => "root",
        mode  => 440,
    }
}

# cd /etc/puppet/manifests
# vi site.pp
import "classes/*"

node default {
    include puptest
}

 こうした設定のもとで「puppet」サービスを起動すると、「/etc/puptest」ファイルのパーミッションが変更される。

 Puppetクライアントはサービスとして動作するため、Puppetサーバは設定の変更内容をクライアントマシンにいつでもプッシュできる。また、クライアント側は通常、システムの設定が該当するマニフェストに記述された内容と一致しているかどうかを定期的にチェックしている。たとえば、上記のようにPuppetの起動によって「/etc/puptest」ファイルのパーミッションが変更されたあとで、このファイルの所有者を私の手で「ben」に変えても、この変更はPuppetによる次回のチェック時に、マニフェストに記述された設定に戻されることになる。デフォルトでは、こうした設定のチェックが30分ごとに行われる。この間隔は「/etc/puppet/puppet.conf」ファイルの「[main]」セクションにある「runinterval」の値を秒数で指定することで変更できる。

 Puppetは、必ずしもクライアントサーバモードで実行する必要はない。ホストがPuppetをサービスとして実行していなくても「puppet /etc/puppet/manifests/site.pp」のようなコマンドでPuppetクライアントを実行すれば、設定ファイルの内容を直接そのクライアントに適用できる。また、中央のサーバから各ホストに対してすべての設定ファイルを適用することもできる。あるいは、変数への代入操作やテンプレートファイルを利用して、パスやホスト名といった要素を設定ファイルに盛り込み、クライアントに適用することも可能だ。

 Puppetは、ディストリビューションによる設定の違いをサポートしている。言語に関するチュートリアルには、sshサービスの設定ファイルをオペレーティングシステム別に指定する例が載っている。これは、宣言型の言語を使ってマシン別の設定を行うための重要なポイントだ。

 マシンが2、3台あっても、Puppetサーバによってシステム設定の変更内容を各マシンにプッシュすれば、ソフトウェアのインストールや設定はそれほど大変ではなくなる。さらに、「/etc/puppet/manifests」ツリーをリビジョン管理システムで扱うようにすれば、ネットワーク上の全マシンの設定を正常に機能していた以前の状態にすばやく戻すことも可能だろう。

 最終的にPuppetが成功を収めるかどうかは、どれだけ多くのシステム管理者がPuppetの言語を覚え、優れたコーディングによる質の高いレシピ(recipe)の作成に貢献して、ほかのユーザが管理の省力化のためにPuppetを利用する際の障壁をどれだけ低くしてくれるかにかかっている。

Ben Martinは10年以上もファイルシステムに携わっている。博士号を持ち、現在はlibferris、各種ファイルシステム、検索ソリューションを中心としたコンサルティングサービスを提供している。

Linux.com 原文