Puppetの基礎
Configuration Management Toolと言えばAnsibleが持て囃されている。
少し適用範囲が狭いことがネックだが実はPuppetも優れたツールだ。Ansibleよりも宣言的な使い方ができる点に特徴がある。宣言的なインフラ管理を志向する人、既にAnsibleを使っているが他ツールと対比してさらにAnsibleの理解を深めたいと思っている人はPuppetについて知っておいて損はない。
今回はPuppetについてみていこう。
管理対象装置
PuppetはUnixやWindowsなどのサーバの設定を管理するようにデザインされている。
Agent
Puppetは管理対象装置上で実行されるagentと各agentに指示するmasterで構成されている。
基本的にagentがインストールできない装置は管理できないが、proxy agentを通して管理することも可能だ。
Pullモデル
各agentはmasterから設定情報をPullして、変更が必要であれば適用する仕組みになっている。
agentはデフォルトでは30分ごとにPullを実行する。
任意のタイミングでOn demandにPullすることもできる(puppet agent -t)。
Declarative
Puppetは宣言型の構成管理ツールだ。
Manifestファイルにシステムの期待する状態を定義するとPuppetがシステムがその状態になるよう必要な変更を実施する。
Ansibleとの比較
agent vs agentless
Ansibleはagentlessであり、agentをインストールできないスイッチ等のネットワーク機器の管理を得意としている。
PuppetはProxy agentを利用すればスイッチ等の管理も可能だが向いているかと言われると疑問だ。ネットワークを管理するのであれば手軽さからAnsibleに軍配が上がるだろう。
Pullモデル vs Pullモデル
AnsibleはPushモデルだが、PullかPushかは2つのテクノロジーを選択する上でほとんど影響がないと考える。
宣言型 vs (半)手続き型
Ansibleは宣言型と手続き型の中間的な位置づけである。AnsibleのPlayは手続き的に記述するがModuleは冪等性を考慮して開発されているため宣言的な結果を得ることができる。一方で、作成したリソースを削除するにはPlaybookに削除手順を記述しなくてはならないため、完全に宣言型とは言えない。また冪等性の担保はModuleに依存するため、使用するModuleによっては宣言的な結果を得られないこともある。
Puppetは完全に宣言型であり、Manifestファイルからリソースの記述を削除すればシステム上のリソースを削除することができる。また手動で設定した値はPuppetによってManifestファイルに定義された状態に戻される。
純粋な宣言型と半手続き型のどちらを選択するかはリソースのライフサイクルをどう管理したいかに依存する。リソースの変更、削除の頻度が低く、Fire and ForgetでよいのならばAnsibleの方が構成がシンプルな上、管理できる装置の種類も多いので好ましいだろう。リソースの変更、削除が頻繁にあり、変更・削除も含めて宣言的に管理したいのであればPuppetが有力な候補となる。しかし構成が複雑になる点は留意する必要だ。
動き
- 運用者はManifestファイルにシステムの期待する状態を定義する
- agentはmasterに現在の状態(fact)を送る
- masterはManifestからCatalogを作成する
- agentは定期的にmasterからCatalogをPullする
- agentはCatalogの内容をシステムに適用して結果をmasterに返す
設定
ここからはPuppetによる構成管理の設定方法について見ていく。
Manifestファイル
Puppetによる構成管理の中心となるのがManifestファイルだ。
Manifestファイルは独自言語で記述する。
ManifestにはResourceという形で管理対象装置の期待する状態を記述する。Resourceを再利用可能な形にまとめるものとしてClassとModuleがある。
Manifestファイルは複数のファイルに分割することができる。分割されていても同じフォルダにあるものは1つのManifestと見なされる。複数あるファイルの中でメインとなるファイルにはsite.ppと命名するのが慣例となっている。
Resource
Resourceはシステムの期待する状態を定義する。以下に書式を示す。
<TYPE> { '<TITLE>': <ATTRIBUTE> => <VALUE>, }
リソースのTYPEの例を示す。
- file
- exec
- package
- service
- user
- group
- host
それぞれの内容はなんとなく想像がつくかと思う。Puppetがサーバの構成管理を念頭にデザインされていることがこのTYPEからも読み取れる。
以下は/etc/hostsファイルを作成するResourceの例である。
file { '/etc/hosts': owner => 'root', group => 'root', mode => 644, }
Class
Classは再利用可能な形でResourceを集めたものである。
定義したClassを使うにはincludeかresource-likeで呼び出す。
include呼び出し
Classに引数を渡さない場合はincludeで呼び出す。以下にClassの定義とincludeでClassを呼び出す例を示す。
class make_file { file { '/etc/hosts': owner => 'root', group => 'root', mode => 644, } } node 'server1' { include make_file }
resource-like呼び出し
Classに引数を渡して使いたい場合はresource-likeを使う。以下にClassの定義とresource-likeでClassを呼び出す例を示す。
class conf_if (String $ip_address) { file { 'if_config': path => '/etc/sysconfig/network-scripts/ifcfg-eth1', content => template("$settings::manifest/network-if.cfg"), ensure => present, } } node 'server1' { class { 'conf_if': ip_address => "192.168.1.1" } }
上記の例では別途用意したTemplateファイル network-if.cfgに192.168.1.1を埋め込んでifcfg-eth1ファイルを作成している。
Module
Moduleは特定機能の再利用を目的としたManifest, Templates等のファイルの集合である。
便利なResourceやClassが既に定義されており、インストールした後、classを呼び出せばすぐに使用できる。
インストール
NTP用のModuleをインストールする例を示す。
$ puppet module install puppetlabs-ntp
呼び出し
以下のようにクラスを呼び出せばすぐに使用できる。
node 'server1' { class { 'ntp': servers => ['192.168.1.250'] } }