仮想化マシン上のゲストOS(Linux)のCPU使用率を求める

 

今回は仮想化マシン上のゲストOS(Linux)のCPU使用率net-snmpで求める際の注意点について
のお話です。

 

(参考)net-snmpCPU使用率取得に関連のあるOIDは以下のとおりです。
OID OID(英語名) 説明
.1.3.6.1.4.1.2021.11.50.0 ssCpuRawUser.0 ユーザCPUタイム
.1.3.6.1.4.1.2021.11.51.0 ssCpuRawNice.0 nice CPUタイム
.1.3.6.1.4.1.2021.11.52.0 ssCpuRawSystem.0 システムCPUタイム
.1.3.6.1.4.1.2021.11.53.0 ssCpuRawIdle.0 アイドルCPUタイム
.1.3.6.1.4.1.2021.11.54.0 ssCpuRawWait.0 ウェイトCPUタイム
.1.3.6.1.4.1.2021.11.55.0 ssCpuRawKernel.0 カーネルCPUタイム
.1.3.6.1.4.1.2021.11.56.0 ssCpuRawInterrupt.0 割り込みCPUタイム
.1.3.6.1.2.1.1.3.0 sysUpTimeInstance.0 snmpが初期化されてからの経過時間
.1.3.6.1.2.1.25.1.1.0 hrSystemUptime.0 ホストが初期化されてからの経過時間
.1.3.6.1.4.1.2021.10.1.5.1 laLoadInt.1 1分間の平均のLoad Average
.1.3.6.1.4.1.2021.10.1.5.2 laLoadInt.2 5分間の平均のLoad Average

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

以前はssCpuRawSystemは"system + iowait + interrupts + softirq"の合計値でしたが、
Net-SNMP 5.4以降ssCpuRawSystemsystemの値となり、sCpuRawKernelは常に
"0"を戻すようになっているようです。
 
まず、物理マシン上でCPU使用率を求める方法を2つご説明します。
 
ひとつ目は、ssCpuRawUser.0ssCpuRawSystem.0hrSystemUptime.0snmpwalk
利用して取得し、CPU使用率を求めることができます。
※sysUpTimeInstance.0SIGHUP等がsnmpdに送られるとそこで経過時間がリセットされる
ため、hrSystemUptime.0を利用する。
 
# snmpwalk -v 2c -c private localhost .1.3.6.1.4.1.2021.11.50.0
# snmpwalk -v 2c -c private localhost .1.3.6.1.4.1.2021.11.52.0
# snmpwalk -v 2c -c private localhost .1.3.6.1.2.1.25.1.1.0
 
計算式は次のようになり、差分(ssCpuRawxxxOld:前回の計測値)を計算して求めることができます。
 
((ssCpuRawUser – ssCpuRawUserOld) + (ssCpuRawSystem – ssCpuRawSystemOld)) / 
(hrSystemUptime – hrSystemUptimeOld)
 
 

もうひとつは、laLoadInt.1もしくはlaLoadInt.2snmpwalkを利用して取得し、ロードアベレージ
を求めることができます。
 
# snmpwalk -v 2c -c private localhost .1.3.6.1.4.1.2021.10.1.5.1
# snmpwalk -v 2c -c private localhost .1.3.6.1.4.1.2021.10.1.5.2
 
 

さて、ここからが本題になります。

仮想化マシン上のゲストOSで、vmstatコマンドを実行するとlinux kernel 2.6.11以降のOS
(ディストリビューションによって異なります)では、cpuのステータスのst(steal値)項目に"0"
以外の値が出力されることがあります。
(ホストOSによってゲストOSのCPU割り当てを制限していると簡単に確認することができる
でしょう)
 
procs ———–memory———- —swap– —–io—- –system– —–cpu—–
r b swpd free buff cache si so bi bo in cs us sy id wa st
1001 0 0 1352360 11456 67480 0 0 0 1 520 275 52 0 0 0 48
 
この状態で上記の方法でCPU使用率を求めると正しい値を取得することはできません。
たとえゲストOSにCPU100%の負荷を掛けても、これらの方法では100%に近い値を取得
することはできません。
実は、分母になっている経過時間にはsteal値として使用されたカウントが含まれていますが、
steal値はゲストOSに割り当てられた値ではありません。
このsteal値が何を示しているかというとゲストOSがホストOSによって待たされている時間に
なります。
net-snmpではssCpuRawStealにあたり、snmpwalkで取得するには以下のようにします。
 
# snmpwalk -v 2c -c private localhost .1.3.6.1.4.1.2021.11.64.0
 
ただし、steal値net-snmp5.4以降からのサポートになります。
 
というわけで、仮想化マシン上のゲストOSでゲストOS自身のCPU使用率を求めるには次の
ような計算式に変更する必要があります。
 
((ssCpuRawUser – ssCpuRawUserOld) + (ssCpuRawSystem – ssCpuRawSystem)) / 
((ssCpuRawUser – ssCpuRawUserOld) + (ssCpuRawSystem – ssCpuRawSystemOld) + 
 (ssCpuRawNice – ssCpuRawNiceOld) + (ssCpuRawIdle – ssCpuRawIdleOld) + 
 (ssCpuRawWait – ssCpuRawWaitOld))