📦

入れ子になった仮想マシンの構築

2024/01/26に公開

入れ子になった仮想マシンを手早く用意したい場面があったので、まとめておきます。

入れ子になった仮想マシンとは

入れ子になった仮想マシンとは、仮想マシンの中で仮想マシンを動作させるため、ハイパーバイザがインストールされた仮想マシンを指します。

参考; 入れ子になった仮想化の概要

なお、入れ子になった仮想マシンについては、テストや評価目的で利用することが推奨されています。

参考; Hyper-V VM 上の Hyper-V VM

方法1 az vm repair create コマンド

手軽に作る方法としては、仮想マシンの復旧を目的とした Azure CLI のコマンド az vm repair を使う方法があります。
このコマンドは、仮想マシンが何らかの要因で起動しなくなったシナリオにおいて、復旧用の仮想マシンに対象仮想マシンの OS ディスクをアタッチし復旧作業を行う (オフライン復旧) を簡素化するコマンドになります。

既に Azure CLI をインストールされていましたら、
以下にて vm-repair 拡張機能をインストールできます。

$ az extension add -n vm-repair

それでは、テスト用の仮想マシン作ってみます。

$ az group create -n labnestedvm -l japaneast
$ az vm create -g labnestedvm --name nestedvm --image Win2022Datacenter --admin-username azureuser --public-ip-address ""

その後、復旧用の仮想マシンを作ります。その際、--enable-nested を指定すると、
復旧用の仮想マシンに Hyper-V が有効化され、テスト用の仮想マシンがその仮想マシンの Hyper-V 上で稼働するようにできます。

$ az vm repair create -g labnestedvm -n nestedvm --repair-username azureuser --repair-password '<yourpassword>' --enable-nested --verbose
Does repair vm requires public ip? (y/n): y
Fetching architecture type of the source VM...
Fetching compatible Windows OS images from gallery...
Fetching available VM sizes for repair VM...
VM size 'Standard_D2s_v3' is available. Using it to create repair VM.

Checking for existing resource groups with identical name within subscription...
Pre-existing repair resource group with the same name is 'False'
Creating resource group for repair VM and its resources...
Source VM uses managed disks. Creating repair VM with managed disks.

Copying OS disk of source VM...
Creating repair VM with command: az vm create -g repair-nestedvm-20240122085949 -n repair-nestedv_ --tag repair_source=labnestedvm/nestedvm --image MicrosoftWindowsServer:WindowsServer:2016-Datacenter:2016.127.20190416 --admin-username azureuser --admin-password <yourpassword> --public-ip-address repair-nestedv_PublicIP --size Standard_D2s_v3
copy_disk_id: /subscriptions/<yoursubscription>/resourceGroups/labnestedvm/providers/Microsoft.Compute/disks/nestedvm-DiskCopy-20240122085949
repair_password: <yourpassword>
repair_username: azureuser
fix_uuid: False
Validating VM template before continuing...
Creating repair VM...
Running Script win-enable-nested-hyperv.ps1 to install HyperV
Restarting Repair VM
Running win-enable-nested-hyperv.ps1 again to create nested VM

Your repair VM 'repair-nestedv_' has been created in the resource group 'repair-nestedvm-20240122085949' with disk 'nestedvm-DiskCopy-20240122085949' attached as data disk. Please use this VM to troubleshoot and repair. Once the repairs are complete use the command 'az vm repair restore -n nestedvm -g labnestedvm --verbose' to restore disk to the source VM. Note that the copied disk is created within the original resource group 'labnestedvm'.

{
  "copied_disk_name": "nestedvm-DiskCopy-20240122085949",
  "copied_disk_uri": "/subscriptions/<yoursubscription>/resourceGroups/labnestedvm/providers/Microsoft.Compute/disks/nestedvm-DiskCopy-20240122085949",
  "created_resources": [
    "/subscriptions/<yoursubscription>/resourceGroups/repair-nestedvm-20240122085949/providers/Microsoft.Compute/virtualMachines/repair-nestedv_/extensions/MicrosoftMonitoringAgent",
    "/subscriptions/<yoursubscription>/resourceGroups/repair-nestedvm-20240122085949/providers/Microsoft.Network/networkInterfaces/repair-nestedv_VMNic",
    "/subscriptions/<yoursubscription>/resourceGroups/repair-nestedvm-20240122085949/providers/Microsoft.Compute/virtualMachines/repair-nestedv_/extensions/AzurePolicyforWindows",
    "/subscriptions/<yoursubscription>/resourceGroups/REPAIR-NESTEDVM-20240122085949/providers/Microsoft.Compute/disks/repair-nestedv__OsDisk_1_d08e2a3c2a6d4e6f887789de6e5bb989",
    "/subscriptions/<yoursubscription>/resourceGroups/repair-nestedvm-20240122085949/providers/Microsoft.Network/publicIPAddresses/repair-nestedv_PublicIP",
    "/subscriptions/<yoursubscription>/resourceGroups/repair-nestedvm-20240122085949/providers/Microsoft.Network/networkSecurityGroups/repair-nestedv_NSG",
    "/subscriptions/<yoursubscription>/resourceGroups/repair-nestedvm-20240122085949/providers/Microsoft.Network/virtualNetworks/repair-nestedv_VNET",
    "/subscriptions/<yoursubscription>/resourceGroups/repair-nestedvm-20240122085949/providers/Microsoft.Compute/virtualMachines/repair-nestedv_",
    "/subscriptions/<yoursubscription>/resourceGroups/labnestedvm/providers/Microsoft.Compute/disks/nestedvm-DiskCopy-20240122085949"
  ],
  "message": "Your repair VM 'repair-nestedv_' has been created in the resource group 'repair-nestedvm-20240122085949' with disk 'nestedvm-DiskCopy-20240122085949' attached as data disk. Please use this VM to troubleshoot and repair. Once the repairs are complete use the command 'az vm repair restore -n nestedvm -g labnestedvm --verbose' to restore disk to the source VM. Note that the copied disk is created within the original resource group 'labnestedvm'.",
  "repair_resource_group": "repair-nestedvm-20240122085949",
  "repair_vm_name": "repair-nestedv_",
  "resource_tag": "repair_source=labnestedvm/nestedvm",
  "status": "SUCCESS"
}
Command ran in 821.173 seconds (init: 0.088, invoke: 821.085)

入れ子になった仮想マシン

実行されている内容としては、"az vm repair run" コマンドを内部で2回実行されており、
間に Hyper-V の有効化に伴い復旧用の仮想マシンを再起動させています。

https://github.com/Azure/azure-cli-extensions/blob/f311e026ee86c8978bab7c2caa883dad26bbb89c/src/vm-repair/azext_vm_repair/custom.py#L222-L238

"az vm repair run" で実行されている PowerShell スクリプトは、こちらの win-enable-nested-hyperv.ps1 で、1周目は下記により Hyper-V 機能の有効化を実施しています。

https://github.com/Azure/azure-cli-extensions/blob/f311e026ee86c8978bab7c2caa883dad26bbb89c/src/vm-repair/azext_vm_repair/scripts/win-enable-nested-hyperv.ps1#L118-L132

2周目は、以下の点を実施しています。

  • 仮想スイッチの作成
  • ネットワークアダプターの作成
  • NAT ネットワークの作成
  • DHCP サーバ の構成 (168.63.129.16 を利用できるように構成)
  • Hyper-V 仮想マシンの作成
    • 4GB メモリの仮想マシンを作成
    • データディスク (復旧対象の仮想マシンの OS ディスク) をマウント
    • ブート順序として、マウントされたデータディスクよりブートするように指定
    • ネットワークアダプターを接続
    • 仮想マシンを起動
  • ログイン時に対象 Hyper-V 仮想マシンが開くようにスタートアップスクリプトの設定

https://github.com/Azure/azure-cli-extensions/blob/f311e026ee86c8978bab7c2caa883dad26bbb89c/src/vm-repair/azext_vm_repair/scripts/win-enable-nested-hyperv.ps1#L28-L116

Azure Quickstart Templates を利用

次に紹介する方法としては、Azure Quickstart Templates にある既存テンプレートを使います。
Azure Quickstart Templates には様々なユースケースに沿った ARM/Bicep テンプレートが含まれています。

入れ子になった仮想マシンの作成については、こちらのテンプレートです。

https://learn.microsoft.com/en-us/samples/azure/azure-quickstart-templates/nested-vms-in-virtual-network/

早速デプロイしてみます。
NIC が複数作成され、ユーザー定義ルート (UDR) が出来るなど、先に紹介した方法よりもう少し込み入っています。

yurio [ ~ ]$ az deployment group create -g labnestedvmarm -n nestedvmarm --template-uri https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/demos/nested-vms-in-virtual-network/azuredeploy.json
Please provide string value for 'HostAdminUsername' (? for help): azureuser
Please provide securestring value for 'HostAdminPassword' (? for help): 

...(省略)...

    "duration": "PT12M8.0821814S",
    "error": null,
    "mode": "Incremental",
    "onErrorDeployment": null,
    "outputResources": [
      {
        "id": "/subscriptions/<yoursubscription>/resourceGroups/labnestedvmarm/providers/Microsoft.Compute/virtualMachines/HVHOST",
        "resourceGroup": "labnestedvmarm"
      },
      {
        "id": "/subscriptions/<yoursubscription>/resourceGroups/labnestedvmarm/providers/Microsoft.Compute/virtualMachines/HVHOST/extensions/HVHOSTSetup",
        "resourceGroup": "labnestedvmarm"
      },
      {
        "id": "/subscriptions/<yoursubscription>/resourceGroups/labnestedvmarm/providers/Microsoft.Compute/virtualMachines/HVHOST/extensions/InstallWindowsFeatures",
        "resourceGroup": "labnestedvmarm"
      },
      {
        "id": "/subscriptions/<yoursubscription>/resourceGroups/labnestedvmarm/providers/Microsoft.Network/networkInterfaces/HVHOSTNIC1",
        "resourceGroup": "labnestedvmarm"
      },
      {
        "id": "/subscriptions/<yoursubscription>/resourceGroups/labnestedvmarm/providers/Microsoft.Network/networkInterfaces/HVHOSTNIC2",
        "resourceGroup": "labnestedvmarm"
      },
      {
        "id": "/subscriptions/<yoursubscription>/resourceGroups/labnestedvmarm/providers/Microsoft.Network/networkSecurityGroups/Azure-VMsNSG",
        "resourceGroup": "labnestedvmarm"
      },
      {
        "id": "/subscriptions/<yoursubscription>/resourceGroups/labnestedvmarm/providers/Microsoft.Network/networkSecurityGroups/GhostedNSG",
        "resourceGroup": "labnestedvmarm"
      },
      {
        "id": "/subscriptions/<yoursubscription>/resourceGroups/labnestedvmarm/providers/Microsoft.Network/networkSecurityGroups/Hyper-V-LANNSG",
        "resourceGroup": "labnestedvmarm"
      },
      {
        "id": "/subscriptions/<yoursubscription>/resourceGroups/labnestedvmarm/providers/Microsoft.Network/networkSecurityGroups/NATNSG",
        "resourceGroup": "labnestedvmarm"
      },
      {
        "id": "/subscriptions/<yoursubscription>/resourceGroups/labnestedvmarm/providers/Microsoft.Network/publicIPAddresses/HVHOSTPIP",
        "resourceGroup": "labnestedvmarm"
      },
      {
        "id": "/subscriptions/<yoursubscription>/resourceGroups/labnestedvmarm/providers/Microsoft.Network/routeTables/Azure-VMsUDR",
        "resourceGroup": "labnestedvmarm"
      },
      {
        "id": "/subscriptions/<yoursubscription>/resourceGroups/labnestedvmarm/providers/Microsoft.Network/virtualNetworks/VirtualNetwork",
        "resourceGroup": "labnestedvmarm"
      }
    ],
    ...(省略)...

実施している内容としては、Desired State Configuration (DSC) 拡張機能を使って、
以下の役割を有効化しています。

DSC 拡張機能は実行コマンド拡張機能や、カスタムコマンド拡張機能と異なり、スクリプト中に再起動を行うことがサポートされています。

  • Hyper-V
  • DHCP
  • RemoteAccess
  • Routing
  • RSAT-Hyper-V-Tools
  • RSAT-DHCP
  • RSAT-RemoteAccess

https://github.com/Azure/azure-quickstart-templates/blob/16698a1be9c801e7555baa855c53757e860574d1/demos/nested-vms-in-virtual-network/azuredeploy.json#L356-L378

次にカスタムスクリプト拡張機能にて、hvhostsetup.ps1 を実行し、ここ に記載のある設定を行っている模様。
Hyper-V ホストは2つの NIC を持ち、片方は NAT 用、もう片方は Hyper-V 仮想マシン側のサブネットに足を出しています。

https://github.com/Azure/azure-quickstart-templates/blob/16698a1be9c801e7555baa855c53757e860574d1/demos/nested-vms-in-virtual-network/azuredeploy.json#L379-L402

まとめ

以上2つ入れ子になった仮想マシン (正確には Hyper-V が有効な仮想マシン) を紹介しました。
1つ目の方法は飽くまでも復旧手段に用いる方法で az vm repair restore コマンドにより復旧用のリソースを削除し、復旧対象の仮想マシンの OS ディスクを入れ替える動作を行うため、その点留意いただければと思います。

GitHubで編集を提案
Microsoft (有志)

Discussion