仮想マシンのリソース コントロール

適用対象: Windows Server 2022、Windows Server 2016、Microsoft Hyper-V Server 2016、Windows Server 2019、Microsoft Hyper-V Server 2019

この記事では、仮想マシンの Hyper-V リソースおよび分離のコントロールについて説明します。 これらの機能は、仮想マシンの CPU グループ、または単に "CPU グループ" と呼ばれ、Windows Server 2016 で導入されました。 CPU グループを使用すると、Hyper-V 管理者はホストの CPU リソースをゲスト仮想マシン間でより適切に管理し、割り当てることができます。 Hyper-V 管理者は、CPU グループを使用して次のことができます。

  • 仮想マシンのグループを作成します。各グループには、グループ全体で共有されている仮想化ホストの合計 CPU リソースが、さまざまに割り当てられています。 これにより、ホスト管理者は、さまざまな種類の VM に対してサービスのクラスを実装できます。

  • 特定のグループに CPU リソースの制限を設定します。 この "グループ上限" により、グループ全体で消費する可能性があるホスト CPU リソースの上限を設定し、そのグループに必要なサービス クラスを効果的に適用します。

  • ホスト システムの特定セットのプロセッサでのみ動作するように CPU グループを制約します。 これは、異なる CPU グループに属する VM を互いに分離するために使用できます。

CPU グループの管理

CPU グループは、Hyper-V ホスト コンピューティング サービス (HCS) を介して管理されます。 HCS の概要、開発の経緯、HCS API へのリンクなどについては、Microsoft 仮想化チームのブログ記事「ホスト コンピューティング サービス (HCS) の概要」を参照してください。

注意

CPU グループの作成と管理には HCS のみを使用できます。Hyper-V マネージャー アプレット、WMI、PowerShell 管理インターフェイスでは、CPU グループはサポートされていません。

Microsoft では、HCS インターフェイスを使用して CPU グループを管理するコマンド ライン ユーティリティ cpugroups.exe を Microsoft ダウンロード センターで提供しています。 このユーティリティでホストの CPU トポロジを表示することもできます。

CPU グループのしくみ

CPU グループ間でのホスト コンピューティング リソースの割り当ては、計算された CPU グループの上限を使用して、Hyper-V ハイパーバイザーによって適用されます。 CPU グループの上限は、CPU グループの合計 CPU 容量に対する割合です。 グループの上限値は、グループのクラスまたは割り当てられた優先順位によって異なります。 計算されたグループの上限は、"CPU 時間に相当する LP の数" と考えることができます。 このグループ バジェットは共有されます。そのため、1 つの VM だけがアクティブだった場合は、それ単独でグループ全体の CPU 割り当てを使用できます。

CPU グループの上限は G = n x C として計算されます。ここで、

  • G は、グループに割り当てるホスト LP の容量です
  • n は、グループ内の論理プロセッサ (LP) の総数です
  • C は最大 CPU 割り当て、つまりグループに必要なサービスのクラスを、システムの合計コンピューティング容量に対する割合として表したものです

たとえば、4 つの論理プロセッサ (LP) を使用して構成された、上限 50% の CPU グループについて考えてみましょう。

  • G = n * C
  • G = 4 * 50%
  • G = グループ全体で 2 LP 相当の CPU 時間

この例では、2 LP に相当する CPU 時間が CPU グループ G に割り当てられます。

グループの上限は、グループにバインドされている仮想マシンまたは仮想プロセッサの数に関係なく、また、CPU グループに割り当てられている仮想マシンの状態 (シャットダウンや起動済みなど) に関係なく適用されます。 したがって、同じ CPU グループにバインドされている各 VM は、グループの合計 CPU 割り当ての一部を受け取り、これは CPU グループにバインドされている VM の数によって変化します。 そのため、VM がバインドされるか、CPU グループから VM がバインド解除されたら、CPU グループ全体の上限を再調整し、必要な VM あたりの上限が維持される結果になるように設定する必要があります。 VM ホスト管理者または仮想化管理ソフトウェア レイヤーは、目的とする VM ごとの CPU リソース割り当てを実現するために、必要に応じてグループの上限を管理する役割を担います。

サービス クラスの例

簡単な例を見てみましょう。 まず、Hyper-V ホスト管理者がゲスト VM に対して 2 つのサービス レベルをサポートすることを考えているとします。

  1. 低レベルである "C" レベル。 このレベルには、ホストのコンピューティング リソース全体の 10% を割り当てます。

  2. 中レベルである "B" レベル。 このレベルには、ホストのコンピューティング リソース全体の 50% を割り当てます。

この例のこの時点で、個々の VM の上限、重み、予約など、他の CPU リソース コントロールが使用されていないと想定します。 ただし、少し後で説明しますが、個々の VM の上限は重要です。

わかりやすくするために、各 VM に 1 つの VP が含まれ、ホストに 8 つの LP があるとします。 空のホストから始めます。

"B" レベルを作成するために、ホスト管理者はグループの上限を 50% に設定します。

  • G = n * C
  • G = 8 * 50%
  • G = グループ全体で 4 LP 相当の CPU 時間

ホスト管理者は、"B" レベルの VM を 1 つ追加します。 この時点で、"B" レベルの VM では、ホストの CPU の最大 50% またはサンプル システムの 4 LP 相当分を使用できます。

ここで、管理者は 2 つ目の "レベル B" の VM を追加します。 CPU グループの割り当ては、すべての VM 間で等しく分配されます。 グループ B には合計 2 つの VM が追加されています。そのため、各 VM は、グループ B の合計である 50% の半分としてそれぞれ 25%、または 2 LP 相当のコンピューティング時間を取得します。

個々の VM での CPU 上限の設定

グループの上限に加えて、各 VM に個別の "VM 上限" を設定できます。 CPU の上限、重み、予約など、VM ごとの CPU リソース コントロールは、その導入以降、Hyper-V の一部になっていました。 グループの上限と組み合わせると、グループに使用可能な CPU リソースがある場合でも、VM の上限によって、各 VP が取得できる CPU の最大量が指定されます。

たとえば、ホスト管理者は、"C" の VM に 10% の VM 上限を設定できます。 そうすることで、ほとんどの "C" VP がアイドル状態でも、各 VP は 10% より多く取得することはできません。 VM の上限がない場合、"C" の VM は、そのレベルで許可されているレベルを超えるパフォーマンスを臨機応変に達成できます。

VM グループを特定のホスト プロセッサに分離する

Hyper-V ホスト管理者は、コンピューティング リソースをいずれかの VM 専用にする機能が必要な場合もあります。 たとえば、管理者が、クラスの上限が 100% の Premium "A" VM を提供したいと考えたとします。 これらの Premium VM では、スケジューリングの遅延とジッターを可能な限り少なくする必要もあります。つまり、他の VM によってスケジュールから削除されないようにする必要があります。 この分離を実現するために、CPU グループに特定の LP アフィニティ マッピングを構成できます。

たとえば、この例ではホスト上の "A" VM に適合するように、管理者は新しい CPU グループを作成し、グループのプロセッサ アフィニティをホストの LP のサブセットに設定します。 グループ B と C は、残りの LP に関連付けられます。 管理者はグループ A に 1 つの VM を作成します。これはグループ A のすべての LP に排他的にアクセスできます。一方、下位レベルと推定されるグループ B と C は残りの LP を共有します。

ゲスト VM からのルート VM の分離

Hyper-V の既定では、基になる各物理 LP 上にルート VP が作成されます。 これらのルート VM は、システムの LP に厳密に 1 対 1 でマップされ、移行されません。つまり、各ルート VP は常に同じ物理 LP で実行されます。 ゲスト VM は、任意の使用可能な LP で実行できます。また、ルート VM と実行を共有します。

ただし、ルート VP アクティビティをゲスト VM から完全に分離することが望ましい場合があります。 Premium "A" レベルの VM を実装している上記の例を考えてみます。 "A" VM の VP については、遅延と "ジッター" またはスケジューリング変動の可能性を最小にするために、専用の LP セットで実行し、ルートがこれらの LP で実行されないようにする必要があります。

これは、"minroot" 構成の組み合わせを使用して実現できます。これにより、ホスト OS パーティションは、1 つ以上の関連付けられた CPU グループとともに、システム論理プロセッサ全体のサブセットで実行されるように制限されます。

仮想化ホストは、ホスト パーティションを特定の LP に制限するように構成できます。残りの LP に 1 つ以上の CPU グループが関連付けられます。 この方法では、ルートとゲストのパーティションを専用の CPU リソースで実行し、CPU 共有を行わず完全に分離することができます。

"minroot" 構成の詳細については、「Hyper-V ホストの CPU リソース管理」を参照してください。

CpuGroups ツールの使用

CpuGroups ツールの使い方の例を見てみましょう。

注意

CpuGroups ツールのコマンド ライン パラメーターは、区切り記号としてスペースのみを使用して渡します。 目的のコマンド ライン スイッチの前に '/' または '-' 文字を付けないでください。

CPU トポロジの検出

GetCpuTopology を使用して CpuGroup を実行すると、次に示すように、LP インデックス、LP が属する NUMA ノード、パッケージとコアの ID、ROOT VP インデックスなど、現在のシステムに関する情報が返されます。

次の例は、2 つの CPU ソケットと NUMA ノード、合計 32 個の LP があり、マルチスレッドが有効になっているシステムを示しています。各 NUMA ノードから 4 つずつ、8 つの ルート VP を持つ Minroot を有効にするように構成されています。 ルート VM を持つ LP は RootVpIndex >= 0 です。RootVpIndex が -1 の LP はルート パーティションでは使用できませんが、ハイパーバイザーによって管理され、他の構成設定で許可されているゲスト VM を実行します。

C:\vm\tools>CpuGroups.exe GetCpuTopology

LpIndex NodeNumber PackageId CoreId RootVpIndex
------- ---------- --------- ------ -----------
      0          0         0      0           0
      1          0         0      0           1
      2          0         0      1           2
      3          0         0      1           3
      4          0         0      2          -1
      5          0         0      2          -1
      6          0         0      3          -1
      7          0         0      3          -1
      8          0         0      4          -1
      9          0         0      4          -1
     10          0         0      5          -1
     11          0         0      5          -1
     12          0         0      6          -1
     13          0         0      6          -1
     14          0         0      7          -1
     15          0         0      7          -1
     16          1         1     16           4
     17          1         1     16           5
     18          1         1     17           6
     19          1         1     17           7
     20          1         1     18          -1
     21          1         1     18          -1
     22          1         1     19          -1
     23          1         1     19          -1
     24          1         1     20          -1
     25          1         1     20          -1
     26          1         1     21          -1
     27          1         1     21          -1
     28          1         1     22          -1
     29          1         1     22          -1
     30          1         1     23          -1
     31          1         1     23          -1

例 2 – ホスト上のすべての CPU グループを出力する

ここでは、現在のホスト上のすべての CPU グループ、その GroupId、グループの CPU 上限、そのグループに割り当てられている LP のインデックスを一覧表示します。

有効な CPU 上限値は [0, 65536] の範囲であり、これらの値はグループの上限をパーセントで表します (例: 32768 = 50%)。

C:\vm\tools>CpuGroups.exe GetGroups

CpuGroupId                          CpuCap  LpIndexes
------------------------------------ ------ --------
36AB08CB-3A76-4B38-992E-000000000002 32768  4,5,6,7,8,9,10,11,20,21,22,23
36AB08CB-3A76-4B38-992E-000000000003 65536  12,13,14,15
36AB08CB-3A76-4B38-992E-000000000004 65536  24,25,26,27,28,29,30,31

例 3 – 1 つの CPU グループを出力する

この例では、GroupId をフィルターとして使用し、単一の CPU グループに対するクエリを実行します。

C:\vm\tools>CpuGroups.exe GetGroups /GroupId:36AB08CB-3A76-4B38-992E-000000000003
CpuGroupId                          CpuCap   LpIndexes
------------------------------------ ------ ----------
36AB08CB-3A76-4B38-992E-000000000003 65536  12,13,14,15

例 4 – 新しい CPU グループを作成する

ここでは、グループ ID とグループに割り当てる一連の LP を指定して、新しい CPU グループを作成します。

C:\vm\tools>CpuGroups.exe CreateGroup /GroupId:36AB08CB-3A76-4B38-992E-000000000001 /GroupAffinity:0,1,16,17

次に、新しく追加したグループを表示します。

C:\vm\tools>CpuGroups.exe GetGroups
CpuGroupId                          CpuCap LpIndexes
------------------------------------ ------ ---------
36AB08CB-3A76-4B38-992E-000000000001 65536 0,1,16,17
36AB08CB-3A76-4B38-992E-000000000002 32768 4,5,6,7,8,9,10,11,20,21,22,23
36AB08CB-3A76-4B38-992E-000000000003 65536 12,13,14,15
36AB08CB-3A76-4B38-992E-000000000004 65536 24,25,26,27,28,29,30,31

例 5 – CPU グループの上限を 50% に設定する

ここでは、CPU グループの上限を 50% に設定します。

C:\vm\tools>CpuGroups.exe SetGroupProperty /GroupId:36AB08CB-3A76-4B38-992E-000000000001 /CpuCap:32768

次に、更新したばかりのグループを表示して設定を確認しましょう。

C:\vm\tools>CpuGroups.exe GetGroups /GroupId:36AB08CB-3A76-4B38-992E-000000000001

CpuGroupId                          CpuCap LpIndexes
------------------------------------ ------ ---------
36AB08CB-3A76-4B38-992E-000000000001 32768 0,1,16,17

例 6 – ホスト上のすべての VM の CPU グループ ID を出力する

C:\vm\tools>CpuGroups.exe GetVmGroup

VmName                                 VmId                           CpuGroupId
------ ------------------------------------ ------------------------------------
    G2 4ABCFC2F-6C22-498C-BB38-7151CE678758 36ab08cb-3a76-4b38-992e-000000000002
    P1 973B9426-0711-4742-AD3B-D8C39D6A0DEC 36ab08cb-3a76-4b38-992e-000000000003
    P2 A593D93A-3A5F-48AB-8862-A4350E3459E8 36ab08cb-3a76-4b38-992e-000000000004
    G3 B0F3FCD5-FECF-4A21-A4A2-DE4102787200 36ab08cb-3a76-4b38-992e-000000000002
    G1 F699B50F-86F2-4E48-8BA5-EB06883C1FDC 36ab08cb-3a76-4b38-992e-000000000002

例 7 – CPU グループから VM のバインドを解除する

CPU グループから VM を削除するには、VM の CpuGroupId に NULL GUID を設定します。 これにより、CPU グループから VM のバインドが解除されます。

C:\vm\tools>CpuGroups.exe SetVmGroup /VmName:g1 /GroupId:00000000-0000-0000-0000-000000000000

C:\vm\tools>CpuGroups.exe GetVmGroup
VmName                                 VmId                           CpuGroupId
------ ------------------------------------ ------------------------------------
    G2 4ABCFC2F-6C22-498C-BB38-7151CE678758 36ab08cb-3a76-4b38-992e-000000000002
    P1 973B9426-0711-4742-AD3B-D8C39D6A0DEC 36ab08cb-3a76-4b38-992e-000000000003
    P2 A593D93A-3A5F-48AB-8862-A4350E3459E8 36ab08cb-3a76-4b38-992e-000000000004
    G3 B0F3FCD5-FECF-4A21-A4A2-DE4102787200 36ab08cb-3a76-4b38-992e-000000000002
    G1 F699B50F-86F2-4E48-8BA5-EB06883C1FDC 00000000-0000-0000-0000-000000000000

例 8 – VM を既存の CPU グループにバインドする

ここでは、既存の CPU グループに VM を追加します。 VM を既存の CPU グループにバインドしないようにする必要があります。そうしないと、CPU グループ ID の設定は失敗します。

C:\vm\tools>CpuGroups.exe SetVmGroup /VmName:g1 /GroupId:36AB08CB-3A76-4B38-992E-000000000001

次に、VM G1 が目的の CPU グループ内にあることを確認します。

C:\vm\tools>CpuGroups.exe GetVmGroup
VmName                                 VmId                           CpuGroupId
------ ------------------------------------ ------------------------------------
    G2 4ABCFC2F-6C22-498C-BB38-7151CE678758 36ab08cb-3a76-4b38-992e-000000000002
    P1 973B9426-0711-4742-AD3B-D8C39D6A0DEC 36ab08cb-3a76-4b38-992e-000000000003
    P2 A593D93A-3A5F-48AB-8862-A4350E3459E8 36ab08cb-3a76-4b38-992e-000000000004
    G3 B0F3FCD5-FECF-4A21-A4A2-DE4102787200 36ab08cb-3a76-4b38-992e-000000000002
    G1 F699B50F-86F2-4E48-8BA5-EB06883C1FDC 36AB08CB-3A76-4B38-992E-000000000001

例 9 – CPU グループ ID でグループ化されたすべての VM を出力する

C:\vm\tools>CpuGroups.exe GetGroupVms
CpuGroupId                           VmName                                 VmId
------------------------------------ ------ ------------------------------------
36AB08CB-3A76-4B38-992E-000000000001     G1 F699B50F-86F2-4E48-8BA5-EB06883C1FDC
36ab08cb-3a76-4b38-992e-000000000002     G2 4ABCFC2F-6C22-498C-BB38-7151CE678758
36ab08cb-3a76-4b38-992e-000000000002     G3 B0F3FCD5-FECF-4A21-A4A2-DE4102787200
36ab08cb-3a76-4b38-992e-000000000003     P1 973B9426-0711-4742-AD3B-D8C39D6A0DEC
36ab08cb-3a76-4b38-992e-000000000004     P2 A593D93A-3A5F-48AB-8862-A4350E3459E8

例 10 – 1 つの CPU グループのすべての VM を出力する

C:\vm\tools>CpuGroups.exe GetGroupVms /GroupId:36ab08cb-3a76-4b38-992e-000000000002

CpuGroupId                           VmName                                VmId
------------------------------------ ------ ------------------------------------
36ab08cb-3a76-4b38-992e-000000000002     G2 4ABCFC2F-6C22-498C-BB38-7151CE678758
36ab08cb-3a76-4b38-992e-000000000002     G3 B0F3FCD5-FECF-4A21-A4A2-DE4102787200

例 11 – 空でない CPU グループの削除を試みる

空の CPU グループ (つまり、バインドされた VM がない CPU グループ) のみを削除できます。 空でない CPU グループを削除しようとすると失敗します。

C:\vm\tools>CpuGroups.exe DeleteGroup /GroupId:36ab08cb-3a76-4b38-992e-000000000001
(null)
Failed with error 0xc0350070

例 12 – CPU グループから唯一の VM のバインドを解除し、グループを削除する

この例では、いくつかのコマンドを使用して CPU グループを調べ、そのグループに属する単一の VM を削除してから、グループを削除します。

まず、グループ内の VM を列挙しましょう。

C:\vm\tools>CpuGroups.exe GetGroupVms /GroupId:36AB08CB-3A76-4B38-992E-000000000001
CpuGroupId                           VmName                                VmId
------------------------------------ ------ ------------------------------------
36AB08CB-3A76-4B38-992E-000000000001     G1 F699B50F-86F2-4E48-8BA5-EB06883C1FDC

G1 という名前の単一の VM だけがこのグループに属していることがわかります。 G1 VM のグループ ID を NULL に設定して、グループからこの VM を削除しましょう。

C:\vm\tools>CpuGroups.exe SetVmGroup /VmName:g1 /GroupId:00000000-0000-0000-0000-000000000000

その後、変更を確認します。

C:\vm\tools>CpuGroups.exe GetVmGroup /VmName:g1
VmName                                 VmId                           CpuGroupId
------ ------------------------------------ ------------------------------------
    G1 F699B50F-86F2-4E48-8BA5-EB06883C1FDC 00000000-0000-0000-0000-000000000000

グループが空になったので、安全に削除できます。

C:\vm\tools>CpuGroups.exe DeleteGroup /GroupId:36ab08cb-3a76-4b38-992e-000000000001

グループがなくなったのを確認します。

C:\vm\tools>CpuGroups.exe GetGroups
CpuGroupId                          CpuCap                     LpIndexes
------------------------------------ ------ -----------------------------
36AB08CB-3A76-4B38-992E-000000000002 32768  4,5,6,7,8,9,10,11,20,21,22,23
36AB08CB-3A76-4B38-992E-000000000003 65536  12,13,14,15
36AB08CB-3A76-4B38-992E-000000000004 65536 24,25,26,27,28,29,30,31

例 13 – VM を元の CPU グループにバインドし戻す

C:\vm\tools>CpuGroups.exe SetVmGroup /VmName:g1 /GroupId:36AB08CB-3A76-4B38-992E-000000000002

C:\vm\tools>CpuGroups.exe GetGroupVms
CpuGroupId VmName VmId
------------------------------------ -------------------------------- ------------------------------------
36ab08cb-3a76-4b38-992e-000000000002 G2 4ABCFC2F-6C22-498C-BB38-7151CE678758
36ab08cb-3a76-4b38-992e-000000000002 G3 B0F3FCD5-FECF-4A21-A4A2-DE4102787200
36AB08CB-3A76-4B38-992E-000000000002 G1 F699B50F-86F2-4E48-8BA5-EB06883C1FDC
36ab08cb-3a76-4b38-992e-000000000003 P1 973B9426-0711-4742-AD3B-D8C39D6A0DEC
36ab08cb-3a76-4b38-992e-000000000004 P2 A593D93A-3A5F-48AB-8862-A4350E3459E8