LinuxでPuppet環境を使用してエージェントを安全に更新する方法
目的
ライブプロダクションシステムを更新する前に、新しい構成をテストするために、 Puppet環境を作成し使用してください。
オペレーティングシステムとソフトウェアのバージョン
- オペレーティングシステム: 主要なLinuxディストリビューション(例:Ubuntu、Debian、CentOS)
- ソフトウェア: パペットとパペットマスター
要件
マスタサーバーとエージェントノードへの特権アクセス。
協定
- # – 指定されたLinuxコマンドは、rootユーザーとして直接実行するか、
sudoコマンドを使用して実行する必要があります。 - $- 一般的な権限のないユーザーとして実行されるLinuxコマンド
紹介
ほとんどのPuppetインストールは、単一のブランチを実行しているマスターサーバーとして始まります。マスターは、すべてのPuppetエージェントのためのすべてのマニフェストとその他の構成を含んでいます。これは始めるのに良い場所ですが、すぐに生産サーバーを壊す可能性のある更新をプッシュする必要がある時が訪れます。最良の結果を望むことは、最善の進め方ではありません。
Puppetは、構成の全体的な枝を分離するためのツールを提供します。これらは「環境」と呼ばれます。Puppet環境は、エージェントノードの孤立したグループに専用の構成を供給する方法です。各環境には、全体のPuppet構成ツリーが含まれており、別のPuppetマスターサーバーとして考えることができます。
Puppet環境はどのように使用されますか?
環境に関する典型的なシナリオ、そしてこのガイドで探求しているシナリオは、新しいPuppetの設定が作成される本番環境に加えて、テスト環境を作成することです。
テスト環境で新しい設定をテストする一つの方法は、VMスナップショットのような本番サーバーのコピーを更新することです。問題が生じた場合、テストマシンで観察され、その問題を修正するためにPuppetの設定が変更されます。ただし、テスト環境での変更を確認するためにテストサーバーを持つことが常に可能とは限りません。
ここで探求する別の方法は、プロダクションサーバーでPuppetエージェントを手動で実行することですが、いくつかのオプションを使用してPuppetエージェントがテスト環境に同期するようにし、実際の変更を加えることなく、何が起こるかを示すことです。これにより、実際にダウンタイムを引き起こすことなく、完全な更新で発生したであろうエラーが強調されます。
Puppet環境の作成
このガイドでは、PuppetマスターとPuppetエージェントノードを持つ非常にシンプルなPuppetインスタンスを作成します。Puppetマスターサーバーは、テスト環境と開発環境の2つの環境を持つように構成されます。
このガイドは、PuppetマスターサーバーとPuppetエージェントノードがPuppetマスターに接続できることを前提としています。
私たちはPuppetマスター上に2つの環境を作成し、これらの環境内でエージェントノードにテキストファイルを作成する非常にシンプルなPuppetマニフェストを作成します。
Puppetの設定のデフォルトの場所は、使用しているディストリビューションによって異なります。このガイドで使用されるUbuntu 18.04LTSでは、場所は/etc/puppetにあります。他のディストリビューション(および公式ドキュメント)では、/etc/puppetlabs/に置かれる場合があります。しかし、メインのPuppet設定ディレクトリに入ると、すべてのサブディレクトリはすべてのディストリビューションで同じです。
指示
環境ディレクトリを作成する
環境とその設定はすべて /etc/puppet/code/ ディレクトリの下に存在します。Ubuntu 18.04では、このディレクトリはインストール時に空なので、まず次の二つのコマンドで上位レベルの環境ディレクトリを作成する必要があります:
mkdir -p /etc/puppet/code/environments/testing
mkdir -p /etc/puppet/code/environments/development
新しいエージェントノードは、エージェントノードのpuppet.confファイルの[agent]セクションで環境変数が別のものに設定されていない限り、自動的にdevelopment環境に接続します。
2つのシンプルな site.pp マニフェストを作成する
このsite.ppファイルは、Puppetエージェントが望ましいマシン状態のカタログの構築を開始する主要なマニフェストです。私たちは、エージェントノード上に同じファイルを作成する2つの非常に簡単なsite.ppファイルを2つの環境に作成する予定です。唯一の違いは、ファイルに異なるテキストを挿入することです。
最初の site.pp ファイルは、以下の本番環境になります:
/etc/puppet/code/environments/development/manifests/site.pp
このファイルには次の内容が含まれている必要があります:
file {'/tmp/example.txt':
ensure => present,
mode => "0644",
content => "From The Development Environment \n",
}
お気に入りのテキストエディタを使って、このファイルを作成し、内容を入力してください。
このマニフェストは、ファイルが/tmp/example.txtに存在し、「From The Development Environment」というテキストが含まれていることを保証します(「“\n”」はファイルの最後に新しい行を追加し、存在しない場合にPuppetが警告メッセージを表示するのを防ぐ良い習慣です)。
2番目のマニフェストは、以下のテスト環境にあります:
/etc/puppet/code/environments/testing/manifests/site.pp
このファイルには以下が含まれています:
file {'/tmp/example.txt':
ensure => present,
mode => "0644",
content => "From The Testing Environment \n",
}
これは開発環境のファイルとほぼ同じですが、唯一の違いはファイルのテキストがテスト環境から来たことを示している点です。
テスト環境からの新しいPuppet設定の評価
エージェントノードはデフォルトで開発環境にのみ同期します。まず、Puppetエージェントに手動でPuppetマスターサーバーと同期するよう指示し、開発環境で作成したsite.ppを作成して適用します。
これは次のコマンドで実行されます。
puppet agent --environment=production --test
--testオプションは、Puppetエージェントがフォアグラウンドで詳細なログを記録しながらカタログ実行を行うようにします。ノードに対する更新や変更は適用されます。
--environment=productionオプションは、私たちが本番環境から同期していることを明確にするためにあります。通常、これはメインのPuppetエージェント設定で構成されており、コマンドに含める必要はありません。
上記のコマンドを実行すると、以下の出力が得られます。
Info: Using configured environment 'production'
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Retrieving locales
Info: Loading facts
Info: Caching catalog for digital-2.net
Info: Applying configuration version '1527680694'
Notice: /Stage[main]/Main/File[/tmp/example.txt]/ensure: defined content as '{md5}59f9ce1d4aad5fd155db7ccc2478a93b'
Notice: Applied catalog in 0.02 seconds
この出力は、ファイル /tmp/example.txt が存在しなかったため、Puppetエージェントがsite.pp マニフェストの指示に従って作成したことを示しています。以降の実行では、/tmp/example.txt ファイルが正しい内容で存在するため、Notice: 行は表示されなくなります。
エージェントノードの状態が開発環境のマニフェストと一致したので、テスト環境からの代替マニフェストを適用した場合に何が起こるかをテストできます。
新しい設定をコミットせずにテストするために、次のコマンドを実行する必要があります:
puppet agent --environment=testing --test --noop
ご覧のように、--environment オプションが testing に変更され、追加のオプション --noop が含まれています。このオプションはエージェントにドライランを実行させます。つまり、Puppet エージェントはエージェントノードに実際の変更を加えることはなく、そのように出力されるすべての結果を生成します。
これにより、新しい設定がサーバーに適用された場合に何が起こったかを評価できます。この場合、上記のコマンドの出力は次のようになります:
Info: Using configured environment 'testing'
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Retrieving locales
Info: Loading facts
Info: Applying configuration version '1527683748'
Notice: /Stage[main]/Main/File[/tmp/example.txt]/content:
--- /tmp/example.txt 2018-05-30 12:19:16.205774048 +0000
+++ /tmp/puppet-file20180530-21610-8ipzur 2018-05-30 12:35:48.740982652 +0000
@@ -1 +1 @@
-From The Development Environment
+From The Testing Environment
Notice: /Stage[main]/Main/File[/tmp/example.txt]/content: current_value '{md5}59f9ce1d4aad5fd155db7ccc2478a93b', should be '{md5}abbb8f68df144a5673d
62ae6c4a036ed' (noop)
Notice: Class[Main]: Would have triggered 'refresh' from 1 event
Notice: Stage[main]: Would have triggered 'refresh' from 1 event
Notice: Applied catalog in 0.04 seconds
ここで最も興味深い文は次のとおりです:
-From The Development Environment
+From The Testing Environment
これらは、マイナス記号 ( - ) で何が変更されるかを示し、プラス記号 ( + ) で何に変更されるかを示しています。この例では、ファイル内のテキストです。
これらの出力は、新しい設定が成功裏に適用され、/tmp/example.txtの内容が変更されることを示しています。これが本番サーバーの望ましい状態であれば、site.ppファイルへの変更は本番環境で安全に行うことができます。
エラーの特定
新しいPuppetの設定は、常にエラーなしで適用されるわけではないため、運用システムに適用する前に常にテストする必要があります。この状況では、テスト用のsite.ppファイルに故意に間違いを作ることでエラーを強制します。ファイルの権限を0944に設定しようとしますが、これは無効な権限であり、エラーを引き起こします。
さて、今私たちが実行するとき:
# puppet agent --environment=testing --test --noop
次の出力を見ます:
Info: Using configured environment 'testing'
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Retrieving locales
Info: Loading facts
Error: Failed to apply catalog: Parameter mode failed on File[/tmp/example.txt]: The file mode specification is invalid: "0944" (file: /etc/puppetcode/environments/testing/manifests/site.pp, line: 1)
次の画面キャプチャは、コマンドラインで表示される出力を示しています:
Puppetは、エラーを赤色で印刷して示します。
その色は、テスト環境から新しいPuppet設定を使用しようとした場合にエラーが発生することをすぐに知らせてくれました。しかし、--noopオプションを使用したため、プロダクションサーバーにはエラーは発生しませんでした。
結論
Puppetで管理されている運用システムを運用する際には、新しい構成が適用される前に必ずテストすることが重要です。Puppetが提供するツールを使用して、新しい構成を安全に作成し、運用システムと対照的に評価できる代替環境を作成することは、エラーを減らし、ダウンタイムを少なくすることにつながります。
