Azure でプロセス監視
システム監視やサービス監視をAzureプラットフォーム上で構築する、といった話はどの案件であっても必ず存在しますよね。ただ、監視といっても様々な機能要件があり、単純な稼働監視だけでなく、CPU使用率やメモリ消費率、ディスクの空き容量やプロセス監視、ポート監視など、細かい要件が存在します。
もちろんAzure VMにZabbixをインストールして監視システムを組み立てることもできますが、可能な限りサーバー管理を必要としないAzureの機能だけを使って組み立てたい、といったニーズも少なくありません。
ここでは、Azureでは対応しているの?していないの?っと特に疑問に思われてきたプロセス監視について触れたいと思います。
まず、結論から言うとAzure VMのOS内で起動しているプロセスが起動しているかどうかのプロセス監視は、Azure Monitorを使って実現することができます。
先にそのやり方を記載すると、Log Analyticsで以下のクエリ検索を実施することで、特定のプロセス名が対象VMにて起動しているかどうかを定点観測することができます。
let ApacheProcessId = toscalar (
VMProcess
| where Computer startswith "u003"
| where ExecutablePath contains "apache2"
| top 1 by TimeGenerated
| project Process
);
InsightsMetrics
| where Name == "Heartbeat" and Origin == "vm.azm.ms/map"
| where Computer startswith "u003"
| where isnotempty(ApacheProcessId) and Tags contains ApacheProcessId
| where TimeGenerated > ago(5m)
上記クエリのサンプル結果が以下です。
※事前にVM Insightsを適用しておく必要があります。
Azure portal で 1 つの仮想マシンまたは仮想マシン スケール セットで Azure Monitor を有効にする - Azure Monitor | Microsoft Docs
クエリ内容の"u003"と記載したVM名と、"apache2"と記載したプロセス名を任意な値に変更することで汎用的に利用できるようにしてあります。また、出力結果がわかりやすいようにクエリを実行した時間から5分前までのプロセス起動状態を出力してありますので、このクエリの結果をそのままアラートルールへ関連付けさせ、条件やアクションからアラートグループの中でメール通知を行う、といったことができます。
クエリについて少し補足するとこんな感じです。
1番ややこしい部分は、InsightsMetricsというテーブルでは、確かに起動しているプロセス状態を定期的(1分ここでいう間隔)にデータ投入されているのですが、肝心のプロセス名(ここでいうapache2)が、どのレコードにも記載されていません。そのためInsightsMetricsテーブルだけで操作しようとしても無理だという点です。InsightsMetricsテーブルでは、p-xxxxxといった一意な識別子が入っており、この識別子がいわゆる各プロセスを表すコードになっているため、apache2のプロセスがp-xxxというどの識別子に置き換えられたかの情報が必要になってきます。
そこで、プロセス情報のマスターテーブルのような位置づけとなっているVMProcessというテーブルから、apache2という名前のプロセスが、p-xxxxxというどんな識別子に解釈されているのかを引っ張ってこないといけないわけです。
クエリ上位にある「let」から「);」までは変数の格納を表す関数のため、VMProcessテーブルで該当の識別子のみを「ApacheProcessId」という独自でつけた変数名に代入している処理を行っています。そしてInsightsMetricsにて、「where Tags contains ApacheProcessId」とすることで、Tagsレコード内にapache2として識別されたp-xxxが部分一致するかどうかを判定しています。
ここまで来てお気づきの方もいますが、「いや、プロセスが起動していることはわかるんだけど、ポートがListenしているかも合わせてみたいんだよね」という話もあります。
ポートはVMBoundPortというテーブルに定期的にデータが入ってきます。
VMBoundPort
| where Computer == "u003" and Port == "80"
| where TimeGenerated > ago(5m)
出力結果サンプルは以下です。
なるほど、っと思われる方も多いと思いますが、もう少しいろいろとこだわってみましょう。
確かにプロセスの起動ステータスやポートの受付状態などは監視することができますが、プロセスの起動本数を監視したい、ポートに対して正常に通信が確立するかを監視したい、といった要件もあります。
残念ながらプロセス起動本数の監視は現時点でのAzure Monitorの機能だけでは厳しい状況かと思います。ただ、できないわけではありません。以下のようなスクリプトを用意し、判定された際にloggerコマンドでログ出力させれば、そのログが定期的にLog Analytics WSへ反映されます。
#!/bin/sh
HTTPCOUNT=`ps -ef | grep -i apache2 | grep -vc grep`
if [ ${HTTPCOUNT} -lt 3 ]
then
logger -p local0.crit "apache2 process down! please check"
fi
つまりLog Analytics側では「"apache2 process down! please check"」というメッセージがsyslogへ出力されたレコードを定期的にチェックしておき、HITしたらアラートルールや通知を呼び出す、といった連携方法になります。
次にポートがListenしているだけではなく、定期的にポート通信が確立しているかの監視については、Network Watcherの接続モニターで可能です。
接続モニターを作成する - Azure portal - Azure Network Watcher | Microsoft Docs
要点だけ記載すると、ソースとなるVM(特定のポートを発信する側)を選択し、そのVMにNetwork Watcher Agentをインストールします。そして対象とするVMを選択します。(Private IP address指定可)最後にシナリオを組み立てます。シナリオでは、何番のポートでエラー率や頻度などを組み立てます。ですので、どのVMであってもZabbixサーバーのように監視システムとして機能させることができるよ、というものです。
今日はこのへんで。