【PowerShell】仮想マシンのリソース使用量を計測する

※この投稿は、PowerShell Adcent Calender 2012 に参加しています!

Hyper-V 上の仮想マシンが使用しているリソースを計測するにはパフォーマンスモニターを使用することができました。

Measuring Performance on Hyper-V
https://technet.microsoft.com/ja-jp/library/cc768535(v=bts.10).aspx

しかし、パフォーマンスモニターの利用になれた方であればまだしも、通常は使用するカウンターの選定など、ちょっと面倒な面も否めません。

そこで、Windows Server 2012、Windows 8 に実装されている Hyper-V では、ゲスト OS のリソース使用量を容易に計測できる Windows PowerShell コマンドレットが用意されました。Measure-VM です。

パフォーマンスモニターが仮想マシンの正常性を計測することを主目的としていたのに対し、このコマンドレットの主な目的は「課金」です。例えば、ホスティングを担当する企業による利用を想定しています。

Measure-VM コマンドレットを使用すると以下の数値を取得することができます。

  • CPUの平均使用量(MHz)
  • メモリの平均使用量(MB)
  • メモリの最大使用量(MB)
  • メモリの最少使用量(MB)
  • ネットワーク(送信)の総使用量(MB)
  • ネットワーク(受信)の総使用量(MB)
  • ディスクの使用量(MB)

ここで、CPUの「使用率」ではなく「使用量」であることに注意してください。先にも書いた通り、Mesure-VM の主目的は「課金」です。よって、CPU の使用では意味がありません。なぜならば、使用している物理マシンによって使用率が変わる可能性が大きいからです。よって、Mesure-VM は使用率ではなく実際にゲスト OS が使用した CPU の使用量を MHz で出力するように設計されています。

ネットワークについても同様です。帯域の使用率ではなく、実際に送受信したデータ量を算出してることに注意してください。

いずれも、計測を開始してから Measure-VM コマンドレットを実行した瞬間までを計測します。

では使ってみましょう。

<計測開始>

計測を開始するには、ゲストOS のメータリング機能を有効にする必要があります。以下はゲストOS Server1 に対してメータリングを有効にしています。

Get-VM -Name Server1 | Enable-VMResourceMetering

または

Enable-VMResourceMetering –Name Server1

<使用量の出力>

Enable-VMResourceMetering を実行してからの使用率が出力するには Measure-VM コマンドレットを使用します。以下はその出力例です。

PS C:\windows\system32> Measure-VM -Name server1

VMName AvgCPU(MHz) AvgRAM(M) MaxRAM(M) MinRAM(M) TotalDisk(M) NetworkInbound(M) NetworkOutbound(M) ------ ----------- --------- --------- --------- ------------ ----------------- ------------------ Server1 3 1000 1000 1000 130048 178 112              

<使用量のリセット>

特定の時間間隔の使用量を出力するには、いったん前回までの使用量をリセットする必要があります。そのために Reset-VMResourceMetering コマンドレットが用意されています。以下のように入力することで、ゲストOS Server1 の使用量がいったんリセットされ、0から再計測が始まります。

Reset-VMResourceMetering –Name Serevr1

では、これらを使用して実際にゲストOSのコストを計測するにはどうしたらよいでしょう?

例えば、以下のようなスクリプトを作成します。

$VMName = "Server1" Calculate-VMCost($VMName)

function Calculate-VMCost($VMName) {

    #ベースコストを設定     $BaseCost = 50

    #各要素の単位コストを設定(例)     $MemoryCostPerGB = 20     $ProcessosCostPerGHz = 30     $IncomingNetworkCostPerGB = 10      $OutgoingNetworkCostPerGB = 30

    # 前回の取得から現時点までののリソース使用量を取得     $ChargebackData = Measure-VM $VMName

    #ここまでの計測をリセット     Get-VM $VMName | Reset-VMResourceMetering

    #ベースコスト     $VMCost = $BaseCost

    #コストにメモリ使用コストを加える     $VMCost += $ChargebackData.AverageMemoryUsage * $MemoryCostPerGB / 1024

    #コストにCPU使用量を加える     $VMCost += $ChargebackData.AverageProcessorUsage * $ProcessosCostPerGHz / 1024

    #ネットワーク受信量を算出     $IncomingExternalTraffic = $data.NetworkMeteredTrafficReport | `         ? { ($_.Direction -eq "Inbound" ) -and ($_.RemoteAddress -eq "*.*")}

    #ネットワーク送信量を算出     $OutgoingExternalTraffic = $data.NetworkMeteredTrafficReport | `         ? { ($_.Direction -eq "Outbound") -and ($_.RemoteAddress -eq "*.*")}

    #コストにネットワークこすとを加える     $VMCost += $IncomingExternalTraffic.TotalTraffic * $IncomingNetworkCostPerGB / 1024     $VMCost += $OutgoingExternalTraffic.TotalTraffic * $OutgoingNetworkCostPerGB / 1024

    $VMCost }

こうしたスクリプトを使用することで、ゲストOSのコストを総合的に判断し課金額の算出に利用することができます。

(参考)

Hyper-V リソース メータリングに関するテクニカル プレビュー
https://technet.microsoft.com/ja-jp/library/hh831661.aspx

Enable-VMResourceMetering
https://technet.microsoft.com/ja-jp/library/hh848481.aspx

Introduction to Resource Metering
https://blogs.technet.com/b/virtualization/archive/2012/08/16/introduction-to-resource-metering.aspx