皆様こんにちは、Ansibleのシニアテクニカルサポートエンジニアの八木澤(@hiyoko_taisa)です。日々Ansible Engine / Towerの問題と戦いながら、世界の平和を守っています。
適切にサービスを提供するためには、サービスが想定どおり動作しているか監視する必要があります。Ansible Towerを導入した場合も例外ではありません。 そこで今回は、Ansible Towerを監視する際のポイントについて、従来の監視手法の問題点とともに整理してみましょう。
1. 監視とは何か
まず最初に、ここでとりあげる「監視」という言葉の定義について考えましょう。監視とは、「サービスおよびシステムが正常に動作しているかを確認し、異常が発生した際にいち早く検知し対応する」ための手段です。
エンタープライズのシステムと監視は切っても切り離せない関係にあります。常に使えることが前提とされるシステムで「気がついたら使えなくなっていた」という状況は避けたいものです。適切な対応を取るために、問題が発生していることをいち早く検知する必要があります。
巷にはさまざまな監視のソリューションやプロダクトが存在していますが、本記事では個別のソリューションについては取り上げません。そのような監視プロダクトなどを使ってAnsible Towerの監視を設計する場合の考え方についてフォーカスします。
2. どうやってAnsible Towerを監視するか
従来多くの組織で行われてきた監視手法は、サーバーのログファイル出力 と、プロセスの状態 をモニタリングするという方法です。
具体的には、サービスが出力するログファイルの特定メッセージの出力とプロセスの死活監視を定期的に行い、プロセスが停止していたり指定した重要度のエラーメッセージが出力されたらアラートを発報する、というやり方です。
しかし、現代のITシステムにおいて、この監視手法は有効なアプローチではありません。特にAnsible Towerにおいては、上記のような監視設計は問題が発生するケースが多く起こりえます。
ログ出力を網羅できない
「問題のあるログメッセージさえ網羅できればうまく動く」といっても、そのようなログメッセージの一覧は多くのプロダクトで提供されていません。そのため、OSSの場合はコードを直接確認したり、検証環境にて起こり得るメッセージを確認するしかありませんが、プロダクトのバージョンや関連するコンポーネントのバージョンの差異によってこのようなログメッセージは変更される可能性があります。
たとえば、Ansible Tower 3.6まではRabbitMQを利用していたため、クラスタに問題が発生した場合は「/var/log/rabbitmq/」配下のログを確認する必要がありました。しかしながら、Ansible Tower 3.7以降ではRabbitMQクラスタは廃止されたため、監視するべきログを変更する必要が出てきます。
このように、アップグレードに伴う変更によって使用されるコンポーネントが変化したり、ログメッセージの扱いが変化する可能性は大いにあります。そのたびに出力されうるログをすべてリストアップし、監視すべきメッセージを決定するというのは非現実的です。
特定のログやプロセスを監視するだけでは不十分
Ansible Towerは、supervisord、nginxやrabbitmqなど、複数の関連サービスが密接に連携しながらサービスを提供しています。コンポーネント単体では意味がなく、それぞれが正しく動作してはじめて正常にサービスを提供できます。そのためあるプロセスでエラーメッセージが出力されていても、状況によってそのメッセージが出力される原因や及ぼす影響は異なります。
また、supervisordの管理下にあるプロセスは、仮に停止していた場合でも自動的にsupervisord側で復旧を試みます。これらの関連プロセスを人間が手動で死活監視することは現実的ではありません。
正確に問題を調査するためには、発生している問題を特定し、関連すると思われるログを全て調査する必要があります。ですので、「このメッセージが出力されたらこの復旧操作をする」という紐づけをすることは事実上不可能です。ですので、「supervisordの特定のプロセスを確認する」「ログファイルのエラーメッセージのリストを作り、問題のあるメッセージを検知する」というような従来の監視スタイルは、あまり効果的ではありません。
3. どのような監視を検討するべきか
より実際のサービスの提供に即した監視手法を検討する
真に監視するべきは「プロセスの起動有無」ではなく、「サービスが正常に提供できているかどうか」です。そのためには、Ansible Towerが正しくジョブを実行できるかどうか、実際の利用に即した形で確認するのがよいでしょう。以下は、Ansible Towerの監視で実際に用いられるケースが多い手法です。
- /api/v2/ping/の出力を確認する Ansible TowerのAPIには、各クラスタノードの状態を確認できる以下のAPIエンドポイントが存在します。
この出力の「Capacity」の値や「Heartbeat」の更新有無を確認することで、ジョブが実行できなくなっているノードを見つけ出すことができます。
{ "ha": true, "version": "3.8.2", "active_node": "tower1", "install_uuid": "05176067-ce0a-42fb-900c-10572f3c53b4", "instances": [ { "node": "tower1", "uuid": "966df87e-531c-4b97-b862-17411b6d34bd", "heartbeat": "2021-04-21T00:49:38.065421Z", "capacity": 16, "version": "3.8.2" }, { "node": "tower2", "uuid": "619b4639-445d-40b8-8b20-adc400744a4d", "heartbeat": "2021-04-09T08:10:23.000914Z", "capacity": 0, "version": "3.8.2" }, { "node": "tower3", "uuid": "ffbdbe85-27d8-41ff-966a-db4f52e1c280", "heartbeat": "2021-04-09T08:10:20.774458Z", "capacity": 0, "version": "3.8.2" } ], "instance_groups": [ { "name": "tower", "capacity": 16, "instances": [ "tower1", "tower2", "tower3" ] } ] }
上記は、実際の検証環境の出力です。これを確認すると、「tower2」「tower3」はCapacityが0になっており、Heartbeatの値から4月9日から動作していないことが読み取れます。
このように、Ansible Tower側で用意しているAPI出力から、各ノードがサービスを提供できる状況にあるか確認するのもひとつの方法です。
テスト用のプレイブックを定期的に実行する
また、実際の処理に影響がない範囲で、テスト用のジョブを実行するという手もあります。こちらはより実態に即した監視手法となります。
テスト用のプレイブックは、軽量で副作用が少ないシンプルなものがよいでしょう。実行頻度を増やしすぎると負荷が増大しますので、環境に応じて適切な頻度を検討しましょう。
一口に監視と言っても、環境によって求められる要件は千差万別です。実際の環境や要件にしたがってどのような監視を行なえばよいか検討してみましょう。