お金をかけずにサーバーの勉強をしよう

SNMPを使ってサーバーの状態を監視する

2022年6月14日

メニューへ戻る

Windows Server 2022の状態を SNMPを使って監視する。

サーバーやネットワーク機器の状態監視の手法として古から現代に至るまで生き残っている SNMPですが、実運用ではミドルウェアを使用するケースが多く、SNMPを余り意識していない管理者が多かろうと思います。

ここでは Windowsサーバーを監視対象 Ubuntuサーバーを監視者として環境を構築し、その中で何が起こっているのか見てみます。

SNMP自体についてはインターネット上にも書籍にもいくらでも説明を見つけることができますのでそちらを参照して頂くとして、それでも何だか良く分からないというのが実態だと思います。

私が SNMPのお勉強をした時も同じで、私の場合は以下 2つが理解を妨げていたように思います。

  1. SNMPの「マネージャー」と「エージェント」の言葉のイメージが、サーバープログラムとクライアントプログラムの関係と逆だった。
  2. 監視ミドルウェアでは SNMPの動きを意識しなくても良いように作られていて、「SNMPでの監視」と「SNMPトラップ」(という方法がある)が別物であると分かってなかった。

ネットワーク通信を行うプログラムは、常駐(動きっぱなし)して情報を提供する「サーバープログラム」、サーバープログラムに問い合わせをして情報を得る「クライアントプログラム」のセットで構成されます。

言葉的にマネージャーが偉くてエージェントが偉くないというイメージがあったため、「SNMPエージェント」がサーバーで「SNMPマネージャー」がクライアントであるという実態と繋がりませんでした。

両方とも SNMPで定義されていますが、これらの通信方向は逆だし、使っているポートも別です。


ここで実験するものでは「SNMPでの監視」と「SNMPトラップ」でプログラムも別となっているので、それぞれ別物であることの理解が進んだのは確かでした。
これが基礎を味わってみることの意義です。


まずよく見かける SNMPの構成図を日本語的にもう一段階簡単にすると、こんな感じの図になるかと思います。
SNMP図 1

SNMPのお勉強の最初にやるのは誰もが赤枠の方です。
エージェントが常駐しているサーバープログラムで、マネージャーが都度実行されるクライアントプログラムです。
エージェントは [161/udp] で待ち受けていて、マネージャーが情報を「取りに行く」(これを「ポーリング」という)イメージで、今風だと「プル型」と言ったりします。
SNMP図 2
インターネット上の SNMPの説明は概ねこちらを扱っているものばかりですし、説明のボリュームの関係もあり、ここで取り上げるのはこちらだけにします。

ここから以下のような環境を作っていきます。
Windows Server 2022を監視対象とし、Ubuntu Server 22.04を監視者とします。
SNMP図 3


Ubuntu Server 22.04の方から作っていきます。

Ubuntuサーバーはインストールしたままの状態だと SNMPマネージャーに相当するプログラムが入っていないので Net-SNMP というパッケージをインストールします。

subro@UbuntuServer2204:~$ sudo apt install snmp
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています... 完了
状態情報を読み取っています... 完了
以下の追加パッケージがインストールされます:
  libsensors-config libsensors5 libsnmp-base libsnmp40
提案パッケージ:
  lm-sensors snmp-mibs-downloader
以下のパッケージが新たにインストールされます:
  libsensors-config libsensors5 libsnmp-base libsnmp40 snmp
アップグレード: 0 個、新規インストール: 5 個、削除: 0 個、保留: 0 個。
1,478 kB のアーカイブを取得する必要があります。
この操作後に追加で 5,428 kB のディスク容量が消費されます。
続行しますか? [Y/n] Y
取得:1 http://jp.archive.ubuntu.com/ubuntu jammy/main amd64 libsensors-config all 1:3.6.0-7ubuntu1 [5,274 B]
取得:2 http://jp.archive.ubuntu.com/ubuntu jammy/main amd64 libsensors5 amd64 1:3.6.0-7ubuntu1 [26.3 kB]
取得:3 http://jp.archive.ubuntu.com/ubuntu jammy-updates/main amd64 libsnmp-base all 5.9.1+dfsg-1ubuntu2.1 [201 kB]
取得:4 http://jp.archive.ubuntu.com/ubuntu jammy-updates/main amd64 libsnmp40 amd64 5.9.1+dfsg-1ubuntu2.1 [1,069 kB]
取得:5 http://jp.archive.ubuntu.com/ubuntu jammy-updates/main amd64 snmp amd64 5.9.1+dfsg-1ubuntu2.1 [176 kB]
1,478 kB を 1秒 で取得しました (1,448 kB/s)
以前に未選択のパッケージ libsensors-config を選択しています。
(データベースを読み込んでいます ... 現在 115390 個のファイルとディレクトリがインストールされています。)
.../libsensors-config_1%3a3.6.0-7ubuntu1_all.deb を展開する準備をしています ...
libsensors-config (1:3.6.0-7ubuntu1) を展開しています...
以前に未選択のパッケージ libsensors5:amd64 を選択しています。
.../libsensors5_1%3a3.6.0-7ubuntu1_amd64.deb を展開する準備をしています ...
libsensors5:amd64 (1:3.6.0-7ubuntu1) を展開しています...
以前に未選択のパッケージ libsnmp-base を選択しています。
.../libsnmp-base_5.9.1+dfsg-1ubuntu2.1_all.deb を展開する準備をしています ...
libsnmp-base (5.9.1+dfsg-1ubuntu2.1) を展開しています...
以前に未選択のパッケージ libsnmp40:amd64 を選択しています。
.../libsnmp40_5.9.1+dfsg-1ubuntu2.1_amd64.deb を展開する準備をしています ...
libsnmp40:amd64 (5.9.1+dfsg-1ubuntu2.1) を展開しています...
以前に未選択のパッケージ snmp を選択しています。
.../snmp_5.9.1+dfsg-1ubuntu2.1_amd64.deb を展開する準備をしています ...
snmp (5.9.1+dfsg-1ubuntu2.1) を展開しています...
libsnmp-base (5.9.1+dfsg-1ubuntu2.1) を設定しています ...
libsensors-config (1:3.6.0-7ubuntu1) を設定しています ...
libsensors5:amd64 (1:3.6.0-7ubuntu1) を設定しています ...
libsnmp40:amd64 (5.9.1+dfsg-1ubuntu2.1) を設定しています ...
snmp (5.9.1+dfsg-1ubuntu2.1) を設定しています ...
libc-bin (2.35-0ubuntu3) のトリガを処理しています ...
man-db (2.10.2-1) のトリガを処理しています ...
Scanning processes...
Scanning candidates...
Scanning linux images...

Running kernel seems to be up-to-date.

Restarting services...
 systemctl restart cron.service

No containers need to be restarted.

No user sessions are running outdated binaries.

No VM guests are running outdated hypervisor (qemu) binaries on this host.

インストールできました。
Ubuntuサーバーはこれで OKです。


Windows Server 2022の環境を作りましょう。

Windows Server OSは SNMPエージェントの機能を持っていますがデフォルトでは有効になっていないので、これを有効化します。

サーバーマネージャで [②役割と機能の追加] をクリックします。
Windows SNMPサービス有効化 1

次へを押します。
Windows SNMPサービス有効化 2

[役割ベースまたは機能ベースのインストール] を選択して次へを押します。
Windows SNMPサービス有効化 3

自分のマシン名が出ていると思いますので、そのまま次へを押します。
Windows SNMPサービス有効化 4

何もせず次へを押します。
Windows SNMPサービス有効化 5

[SNMPサービス] のチェックを入れます、
Windows SNMPサービス有効化 6

このダイアログが出るので機能の追加を押します。
Windows SNMPサービス有効化 7

次へを押します。
Windows SNMPサービス有効化 8

インストールを押します。
Windows SNMPサービス有効化 9

閉じるを押します。
Windows SNMPサービス有効化 10

この作業により Windows Server 2022のサービスに

が追加されているはずです。

この実験で対象にしているのは [SNMPサービス] の方で、インストールされた素の状態ではマネージャーが情報を取得できませんので設定変更をします。

スタートメニューから [Windows管理ツール] - [サービス] と選択します。

[SNMPサービス] をダブルクリックします。
Windows SNMPサービス有効化 11

[セキュリティ] タブの [受け付けるコミュニティ名] の追加を押します。
Windows SNMPサービス有効化 12

[コミュニティ名] は任意のもので良いので、とりあえず [public] にします。
※セキュリティ的には分かり辛いものの方が良いです。
追加を押します。
Windows SNMPサービス有効化 13

下の段で [すべてのホストからSNMPパケットを受け取る] を選択します。
※セキュリティ的にはマネージャの IPアドレスに限定するべきです。
OKを押します。
Windows SNMPサービス有効化 14

これで Windowsサーバーも OKです。


いよいよ SNMPを使って、Windowsサーバーの情報を取得しますが、ここで出てくるのが MIBツリーという概念です。

SNMPで得られる情報は全て MIBツリーで管理されていて、得たい情報が MIBツリーのどの枝にあるのかを予め知っておかねばなりません。

MIBツリーには標準部分(どのメーカーでも同じ)と拡張(各メーカーで枝の一部に追加してくる)があります。
MIBツリーのイメージは、どこの国の人のものか分かりませんが、PDFがありましたので勝手に以下をリンクします。

An Introduction to the SNMP Protocol: The MIB Tree

ここに書かれている通り、得たい情報の枝は Object ID(OID)で表す事ができて「1.1.2.34」みたいな感じで表現します。
木の根(root)から枝(数字で表す)の階層をドットで区切っています。

標準部分はどこでも同じ(と言われている)で、拡張部分はメーカーが拡張情報のツリーの OIDを顧客にくれるはずです。
Windows Server 2022の拡張部分、というかマイクロソフト製品の拡張部分は以下に説明がありました。

MIB 名ツリー

OIDは「1.3.6.1.4.1.311」以下らしいですが、具体的なツリーの情報や図はないようです。
どんな値が取れるのか、後でやってみることにします。


では、実際にMIBツリーの情報を取得してみます。

Ubuntu Server 22.04で SNMPマネージャーである snmpwalkコマンドを実行します。

-vSNMPバージョン
「2c」がデファクトスタンダード
-cコミュニティ名
Windows 2022で「public」と設定したもの
19.168.1.104Windows 2022の IPアドレス
1MIBツリーの「1」以下全部
subro@UbuntuServer2204:~$ snmpwalk -v 2c -c public 192.168.1.104 1
iso.3.6.1.2.1.1.1.0 = STRING: "Hardware: Intel64 Family 6 Model 42 Stepping 7 AT/AT COMPATIBLE - Software: Windows Version 6.3 (Build 20348 Multiprocessor Free)"
iso.3.6.1.2.1.1.2.0 = OID: iso.3.6.1.4.1.311.1.1.3.1.2
iso.3.6.1.2.1.1.3.0 = Timeticks: (720735) 2:00:07.35
iso.3.6.1.2.1.1.4.0 = ""
iso.3.6.1.2.1.1.5.0 = STRING: "Win2022"
iso.3.6.1.2.1.1.6.0 = ""
iso.3.6.1.2.1.1.7.0 = INTEGER: 76
iso.3.6.1.2.1.2.1.0 = INTEGER: 9
iso.3.6.1.2.1.2.2.1.1.1 = INTEGER: 1
iso.3.6.1.2.1.2.2.1.1.2 = INTEGER: 2

〜〜〜 省略 〜〜〜

iso.3.6.1.2.1.55.1.12.1.6.6.16.255.2.0.0.0.0.0.0.0.0.0.1.255.143.56.85 = INTEGER: 1
iso.3.6.1.2.1.55.1.12.1.6.6.16.255.2.0.0.0.0.0.0.0.0.0.1.255.219.68.233 = INTEGER: 1
iso.3.6.1.2.1.55.1.12.1.6.6.16.255.2.0.0.0.0.0.0.0.0.0.1.255.249.245.237 = INTEGER: 1
iso.3.6.1.4.1.77.1.1.1.0 = STRING: "10"
iso.3.6.1.4.1.77.1.1.2.0 = STRING: "0"
iso.3.6.1.4.1.77.1.1.3.0 = Hex-STRING: 07 00 00 00

ズラズラと大量に出てきます。
各行が MIBツリーの末端にある情報そのものです。

行頭の [iso] が MIBツリーの [.1](root直下の1) を意味しています。
MIBツリーの枝の番号はこのように分かりやすく英単語を割り当てられてはいるのですが、実体は数字で管理されているので数字のまま表現していきます。

Windows Server 2022では途中で「値が取れない」というエラーになってしまい、上に示したところまでしか表示されませんでしたが、もっと後ろにある値も個別指定すれば取得可能と思います。


Windowsサーバーの情報が取れるようになりましたので、何か実際に役に立つ事をやってみます。
CPUの使用率でも取ってみましょう。

MIBツリーの中で、ハードウェアリソース情報(CPUとかメモリとかの使用状況)が取れる OIDは、Ubuntu Server 22.04にインストールした Net-SNMPのドキュメントに書いてありました。
Windows Server OSが Net-SNMPと同じ実装をしているかは分かりませんが、この OIDは標準部分なので Linuxでも Windowsでも多分同じでしょう。

HOST-RESOURCES-MIB

しかしどうにも分かり辛い資料で難儀します。

この中の hrProcessorTable(.1.3.6.1.2.1.25.3.3) という箇所に過去 1分間の CPU平均使用率を %で取れる OIDがあります。
それでは [.1.3.6.1.2.1.25.3.3] の値を取得してみます。

subro@UbuntuServer2204:~$ snmpwalk -v 2c -c public 192.168.1.104 .1.3.6.1.2.1.25.3.3
iso.3.6.1.2.1.25.3.3.1.1.3 = OID: ccitt.0
iso.3.6.1.2.1.25.3.3.1.1.4 = OID: ccitt.0
iso.3.6.1.2.1.25.3.3.1.1.5 = OID: ccitt.0
iso.3.6.1.2.1.25.3.3.1.1.6 = OID: ccitt.0
iso.3.6.1.2.1.25.3.3.1.2.3 = INTEGER: 0
iso.3.6.1.2.1.25.3.3.1.2.4 = INTEGER: 1
iso.3.6.1.2.1.25.3.3.1.2.5 = INTEGER: 1
iso.3.6.1.2.1.25.3.3.1.2.6 = INTEGER: 1

いらない値も含まれてしまっていますね。
下の4行が Windows Server 2022の仮想マシンが持つ CPU(4CPUある)の各CPUの使用率(過去1分平均)のようです。

一つ下の枝の [hrDeviceIndex(.1.3.6.1.2.1.25.3.3.1)] で取ってみます。

subro@UbuntuServer2204:~$ snmpwalk -v 2c -c public 192.168.1.104 .1.3.6.1.2.1.25.3.3.1
iso.3.6.1.2.1.25.3.3.1.1.3 = OID: ccitt.0
iso.3.6.1.2.1.25.3.3.1.1.4 = OID: ccitt.0
iso.3.6.1.2.1.25.3.3.1.1.5 = OID: ccitt.0
iso.3.6.1.2.1.25.3.3.1.1.6 = OID: ccitt.0
iso.3.6.1.2.1.25.3.3.1.2.3 = INTEGER: 0
iso.3.6.1.2.1.25.3.3.1.2.4 = INTEGER: 1
iso.3.6.1.2.1.25.3.3.1.2.5 = INTEGER: 1
iso.3.6.1.2.1.25.3.3.1.2.6 = INTEGER: 1

変わりませんでしたので、もう1つ 下の枝の [hrProcessorFrwID(.1.3.6.1.2.1.25.3.3.1.1)] で。

subro@UbuntuServer2204:~$ snmpwalk -v 2c -c public 192.168.1.104 .1.3.6.1.2.1.25.3.3.1.1
iso.3.6.1.2.1.25.3.3.1.1.3 = OID: ccitt.0
iso.3.6.1.2.1.25.3.3.1.1.4 = OID: ccitt.0
iso.3.6.1.2.1.25.3.3.1.1.5 = OID: ccitt.0
iso.3.6.1.2.1.25.3.3.1.1.6 = OID: ccitt.0

いらん方が取れているので、隣の枝 [hrProcessorLoad(.1.3.6.1.2.1.25.3.3.1.2)] へ。

subro@UbuntuServer2204:~$ snmpwalk -v 2c -c public 192.168.1.104 .1.3.6.1.2.1.25.3.3.1.2
iso.3.6.1.2.1.25.3.3.1.2.3 = INTEGER: 0
iso.3.6.1.2.1.25.3.3.1.2.4 = INTEGER: 1
iso.3.6.1.2.1.25.3.3.1.2.5 = INTEGER: 1
iso.3.6.1.2.1.25.3.3.1.2.6 = INTEGER: 1

目的のものが取れました。


シェルスクリプトにして、4つの CPUの平均値を出すようにしました。
/home/subro/bin/cpu_load.sh

#!/usr/bin/bash

for load in `snmpwalk -v 2c -c public -O v 192.168.1.104 .1.3.6.1.2.1.25.3.3.1.2 | cut -f 2 -d ' '`
do

    load_addup=`expr $load_average + $load`

done

echo `hostname`,`date +"%Y%m%d,%H%M"`,`expr $load_addup / 4` >> /home/subro/cpu_load.csv

これを cronで毎分動かします。

* * * * * /home/subro/bin/cpu_load.sh 2>&1 > /dev/null

こんな結果が CSVファイルに残りますので、後は Excelでグラフ化するなどできますね。

subro@UbuntuServer2204:~$ tail -f cpu_load.csv
UbuntuServer2204,20220614,1232,0
UbuntuServer2204,20220614,1235,0
UbuntuServer2204,20220614,1236,3
UbuntuServer2204,20220614,1237,0
UbuntuServer2204,20220614,1238,6
UbuntuServer2204,20220614,1239,7
UbuntuServer2204,20220614,1240,10
UbuntuServer2204,20220614,1241,9
UbuntuServer2204,20220614,1242,0
UbuntuServer2204,20220614,1243,0


実際の運用では SNMPマネージャーとなれる監視専用のミドルウェアを導入することになると思いますが、全くお金がかけられないとか、簡単な監視ができれば良いという場合には、ここで扱った仕組みからメールでの通知に繋げることもできます。

サーバー監視の方法は SNMPだけではありませんが、候補としては今でも一番先に出てくるものです。

どのような値が取得できるかなど、こうやって調べていくと理解が進むと思います。

SNMPは現役ですが枯れた技術ではあるので久しく新しい本が出ていませんね。

入門SNMP [ ダグラス・R.マウロ ]

価格:3,740円
(2022/6/14 12:52時点)
感想(0件)