VM インスタンスのネストされた仮想化の有効化

このドキュメントでは、Compute Engine VM インスタンスでネストされた仮想化のサポートを有効にする方法について説明します。また、ネストされた VM の起動と設定の基本的な手順についても説明します。

ネストされた仮想化は、Intel VT-x プロセッサの仮想化命令が Compute Engine VM でサポートされるようにします。ネストされた仮想化を使用すると、Compute Engine で通常のように VM インスタンスを起動してから、その VM インスタンスに KVM 互換のハイパーバイザをインストールし、そのハイパーバイザ上で別の VM インスタンスを実行できます。Hyper-V、ESX、Xen などの他のハイパーバイザは現在サポートされていません。Haswell または新しいプラットフォーム上で実行されている Linux VM インスタンスでは、ネストされた仮想化を使用できます。

ネストされた仮想化は、VM イメージを Compute Engine に変換またはインポートできないような、VM ベースのアプリケーションやワークロードに最適です。たとえば、ネストされた仮想化を使用すると、Compute Engine 上で動作する VM にシームレスにフェイルオーバーできるような KVM ベースの仮想マシン上で動作するオンプレミスのワークロード用の障害復旧ソリューションを、KVM ベースの VM をネイティブの Compute Engine イメージに変換するのに必要な余分な時間やオーケストレーションなしで構築できます。ネストされた仮想化に適した別のワークロードとしては、さまざまな KVM 互換 OS の多くのバージョンでソフトウェア パッケージの新しいバージョンをテストし検証する必要のあるソフトウェア検証フレームワークが挙げられます。ネストされた VM を実行すると、Compute Engine イメージの大規模なライブラリを変換して管理する必要がなくなります。

始める前に

ネストされた仮想化のしくみ

Compute Engine VM は、L0 環境と呼ばれる物理ハードウェア(ホストサーバー)の上で実行されます。ホストサーバー内には、プリインストールされたハイパーバイザがあり、Compute Engine 上で L1 またはネイティブ VM として参照される複数の Compute Engine VM を単一のサーバーがホストできます。ネストされた仮想化を使用する場合、L1 ゲスト OS の上に別のハイパーバイザをインストールし、L1 ハイパーバイザを使用して L2 VM と呼ばれるネストされた VM を作成します。ゲストのハイパーバイザとネストされた VM を実行している L1 またはネイティブの Compute Engine VM は、ホスト VM と呼ぶこともできます。

ネストされた仮想化の図

制限事項

  • ネストされた仮想化は、Haswell プロセッサ以降で動作する L1 VM に対してのみ有効にできます。ゾーンのデフォルト プロセッサが Sandy Bridge または Ivy Bridge の場合、最小 CPU の選択を使用し、特定のインスタンス向けに Haswell 以降を選択できます。リージョンとゾーンページを確認し、Haswell 以降のプロセッサをポートするゾーンを決定します。
  • ネストされた仮想化は、Linux インスタンスで実行されている KVM ベースのハイパーバイザでのみサポートされています。ESX ハイパーバイザと Xen ハイパーバイザはサポートされていません。
  • ネストされた仮想化は現在、Windows インスタンスをサポートしていません。

テスト済みの KVM バージョン

Google では、Compute Engine インスタンスで次の Linux ディストリビューションとカーネル /KVM バージョンを使用して、ネストされた仮想化の基本的な起動および統合テストを行います。

  • CentOS 7、カーネル バージョン 3.10
  • Debian 9、カーネル バージョン 4.9
  • Debian 8、カーネル バージョン 3.16
  • RHEL 7、カーネル バージョン 3.10
  • SLES 12.2、カーネル バージョン 4.4
  • SLES 12.1、カーネル バージョン 3.12
  • Ubuntu 16.04 LTS、カーネル バージョン 4.4
  • Ubuntu 14.04 LTS、カーネル バージョン 3.13

ここにリストされていないディストリビューションおよびカーネル /KVM バージョンでネストされた VM を実行する際に問題がある場合は、上記の環境のいずれかをホスト Compute Engine インスタンスでゲスト オペレーティング システムとして使用して問題を再現してから、問題をバグとして報告してください。

パフォーマンス

ハードウェア補助によるネストされた仮想化であっても、ネストされた VM 自体、およびそれらの内部で実行されているアプリケーションやワークロードには、パフォーマンス上のペナルティが発生します。特定のアプリケーションまたはワークロードの厳密なパフォーマンス低下を予測することは不可能ですが、CPU バウンドのワークロードには少なくとも 10% のペナルティが存在し、I/O バウンドのワークロードにはさらにペナルティが増える可能性があります。

VM 上でネストされた仮想化を有効にする

ネストされた仮想化を有効にするには、API または gcloud コンポーネントを使用します。ネストされた仮想化を有効にするには、L1 またはホスト VM インスタンスで VMX を有効にする特別なライセンスキーを使用してカスタム イメージを作成し、Haswell 以降をサポートするゾーンでそのイメージを使用して VM インスタンスを開始する必要があります。ライセンスキーには追加料金はかかりません。

  1. 仮想化に必要な特別ライセンスキーを使用してカスタム イメージを作成します。

    gcloud

    「gcloud」コマンドライン ツールを使用してイメージを作成する場合は、「--licenses」フラグを使用して次のライセンス URL を指定します。

    https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx
          

    たとえば、次のコマンドは、「disk1」という名前のサンプル ディスクから「nested-vm-image」という名前のイメージを作成します。

    gcloud compute images create nested-vm-image \
      --source-disk disk1 --source-disk-zone us-central1-a \
      --licenses "https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx"
          

    API

    API で、API リクエストにライセンス プロパティを含めます。

    POST https://www.googleapis.com/compute/v1/projects/myproject/global/images
    
    {
       "licenses": ["projects/vm-options/global/licenses/enable-vmx"],
       "name": "nested-vm-image",
       "sourceDisk": "zones/us-central1-a/disks/disk1"
    }
        
  2. カスタム イメージを使用して、Haswell 以降をサポートするゾーンに VM インスタンスを作成します。次に例を示します。
    gcloud compute instances create example-nested-vm --zone us-central1-b \
                  --image nested-vm-image
  3. ネストされた仮想化が VM で有効になっていることを確認します。
    1. VM インスタンスに接続します。次に例を示します。
      gcloud compute ssh example-nested-vm
    2. 次のコマンドを実行して、ネストされた仮想化が有効になっていることを確認します。ネストされた仮想化が有効であれば、ゼロ以外のレスポンスが返されます。
      grep -cw vmx /proc/cpuinfo

ネストされた VM の起動

ネストされた VM はさまざまな方法で起動できます。このセクションでは、Debian を実行している L1 VM 上で qemu-system-x86_64 を使用してネストされた VM を起動する例を示します。ここで文書化されたプロセス以外の方法を使用して、ネストされた VM を実行する際に問題がある場合は、このプロセスを使用して問題を再現してから、問題をバグとして報告してください。

  1. VM インスタンスに接続します。次に例を示します。

    gcloud compute ssh example-nested-vm
    
  2. VM インスタンスを更新し、必要なパッケージをいくつかインストールします。

    sudo apt-get update && sudo apt-get install qemu-kvm -y
    
  3. OS イメージをダウンロードします。

    wget https://people.debian.org/~aurel32/qemu/amd64/debian_squeeze_amd64_standard.qcow2
    
  4. screen を実行します。

    screen
    
  5. screen ウェルカム プロンプトで Enter キーを押します。

  6. ネストされた VM を起動します。プロンプトが表示されたら、user: rootpassword: root でログインします。

    sudo qemu-system-x86_64 -enable-kvm -hda debian_squeeze_amd64_standard.qcow2 -m 512 -curses
    
  7. VM が外部からアクセスできるかどうかテストします。

    user@nested-vm:~$ wget google.com && cat index.html

  8. 作業が終了したら、Ctrl + aCtrl + d キーを押してネストした VM を終了します。

ホストとネストされた VM 間のプライベート ブリッジの開始

ホストとネストされた VM 間の接続を有効にするには、プライベート ブリッジを作成します。このサンプル手順は、Debian を実行している L1 VM を対象としています。

  1. VM インスタンスに接続します。次に例を示します。

    gcloud compute ssh example-nested-vm
    
  2. VM インスタンスを更新し、必要なパッケージをいくつかインストールします。

    sudo apt-get update && sudo apt-get install uml-utilities qemu-kvm bridge-utils virtinst libvirt-bin -y
    
  3. libvirt パッケージに付属しているデフォルト ネットワークを起動します。

    sudo virsh net-start default
    
  4. virbr0 ブリッジがあることを確認します。

    sudo ifconfig -a
    
     eth0      Link encap:Ethernet  HWaddr 42:01:0a:80:00:02
               inet addr:10.128.0.2  Bcast:10.128.0.2  Mask:255.255.255.255
               UP BROADCAST RUNNING MULTICAST  MTU:1460  Metric:1
               RX packets:14799 errors:0 dropped:0 overruns:0 frame:0
               TX packets:9294 errors:0 dropped:0 overruns:0 carrier:0
               collisions:0 txqueuelen:1000
               RX bytes:97352041 (92.8 MiB)  TX bytes:1483175 (1.4 MiB)

    lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

    virbr0 Link encap:Ethernet HWaddr 5a:fa:7e:d2:8b:0d inet addr:192.168.122.1 Bcast:192.168.122.255 Mask:255.255.255.0 UP BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

  5. ダミー インターフェースを作成します。

    sudo modprobe dummy
    
  6. ブリッジにダミー インターフェースを追加します。

    sudo brctl addif virbr0 dummy0
    
  7. インターフェースが追加されたことを確認します。

    sudo brctl show
    
    bridge name    bridge id          STP enabled    interfaces
    virbr0         8000.6a20fa136bb6  yes            dummy0

  8. ホスト VM からネストされた VM に移動するための tun インターフェースを作成します。

    sudo tunctl -t tap0
    sudo ifconfig tap0 up
    
  9. tun インターフェースをブリッジ VM に接続します。

    sudo brctl addif virbr0 tap0
    
  10. ブリッジ ネットワークが正しく設定されていることを再度確認します。

    sudo brctl show
    
    bridge name     bridge id               STP enabled     interfaces
    virbr0          8000.5254005085fe       yes              dummy0
                                                             tap0
    1. OS イメージをダウンロードします。

    wget https://people.debian.org/~aurel32/qemu/amd64/debian_squeeze_amd64_standard.qcow2s
    
  11. screen を実行します。

    screen
    
  12. screen ウェルカム プロンプトで Enter キーを押します。

  13. ネストされた VM を起動します。プロンプトが表示されたら、user: rootpassword: root でログインします。

    sudo qemu-system-x86_64 -enable-kvm -hda debian_squeeze_amd64_standard.qcow2 -m 512 -net nic -net tap,ifname=tap0,script=no -curses
    
  14. ネストされた VM 上で、ifconfig を実行し、VM の virbr0 領域に 192.168.122.89 などのアドレスがあることを確認します。

    user@nested-vm:~$ ifconfig

  15. ポート 8000 でダミーのウェブサーバーを起動します。

    user@nested-vm:~$ python -m SimpleHTTPServer

  16. Ctrl + aCtrl + a ボタンを押して、ネストされた VM を終了します。

  17. ホスト VM がネストされた VM に対して ping を実行できるかどうかをテストします。

    curl 192.168.122.89:8000
    

    ネストされた VM は、次のような内容を返します。

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html>
    <title>Directory listing for /</title>
    <body>
    <h2>Directory listing for /</h2>
    <hr>
    <ol>
    <li><a href=".aptitude/">.aptitude/</a>
    <li><a href=".bashrc">.bashrc</a>
    <li><a href=".profile">.profile</a>
    </ol>
    <hr>
    </body>
    </html>
    

ネストされた VM をホスト VM の外部からアクセスできるように設定する

ホスト VM の外部にある VM が、ネストされた VM に対して ping を実行できるように、複数のネットワーク インターフェースでインスタンスを設定するか、エイリアス IP を使用してインスタンスを設定できます。

次のサンプル手順は、エイリアス IP を使用して同じネットワーク上の他の VM からネストされた VM にアクセスできるように、ホストとネストされた VM を設定します。この手順は、Debian を実行している L1 VM を対象としています。

  1. ネストされた仮想化が有効になった VM を作成しますが、必ずエイリアス IP 範囲と HTTP/HTTPS トラフィックのサポートが含まれるようにしてください。次に例を示します。

    gcloud compute instances create example-nested-vm --image nested-vm-image \
        --tags http-server,https-server --can-ip-forward \
        --network-interface subnet=subnet1,aliases=/30
    
  2. VM インスタンスに接続します。次に例を示します。

    gcloud compute ssh example-nested-vm
    
  3. VM インスタンスを更新し、必要なパッケージをいくつかインストールします。

    sudo apt-get update && sudo apt-get install uml-utilities qemu-kvm bridge-utils virtinst libvirt-bin -y
    
  4. libvirt パッケージに付属しているデフォルト ネットワークを起動します。

    sudo virsh net-start default
    
  5. virbr0 ブリッジがあることを確認します。

    sudo ifconfig -a
     
     eth0      Link encap:Ethernet  HWaddr 42:01:0a:80:00:02
               inet addr:10.128.0.2  Bcast:10.128.0.2  Mask:255.255.255.255
               UP BROADCAST RUNNING MULTICAST  MTU:1460  Metric:1
               RX packets:14799 errors:0 dropped:0 overruns:0 frame:0
               TX packets:9294 errors:0 dropped:0 overruns:0 carrier:0
               collisions:0 txqueuelen:1000
               RX bytes:97352041 (92.8 MiB)  TX bytes:1483175 (1.4 MiB)

    lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

    virbr0 Link encap:Ethernet HWaddr 5a:fa:7e:d2:8b:0d inet addr:192.168.122.1 Bcast:192.168.122.255 Mask:255.255.255.0 UP BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

  6. ダミー インターフェースを作成します。

    sudo modprobe dummy
    
  7. ブリッジにダミー インターフェースを追加します。

    sudo brctl addif virbr0 dummy0
    
  8. インターフェースが追加されたことを確認します。

    sudo brctl show
    bridge name    bridge id          STP enabled    interfaces
    virbr0         8000.6a20fa136bb6  yes            dummy0

  9. ホスト VM からネストされた VM に移動するための tun インターフェースを作成します。

    sudo tunctl -t tap0
    sudo ifconfig tap0 up
    
  10. tun インターフェースをブリッジ VM に接続します。

    sudo brctl addif virbr0 tap0
    
  11. ブリッジ ネットワークが正しく設定されていることを再度確認します。

    sudo brctl show
    
    bridge name     bridge id               STP enabled     interfaces
    virbr0          8000.5254005085fe       yes              dummy0
                                                             tap0
    1. OS イメージをダウンロードします。

    wget https://people.debian.org/~aurel32/qemu/amd64/debian_squeeze_amd64_standard.qcow2s
    
  12. screen を実行します。

    screen
    
  13. screen ウェルカム プロンプトで Enter キーを押します。

  14. ネストされた VM を起動します。プロンプトが表示されたら、user: rootpassword: root でログインします。

    sudo qemu-system-x86_64 -enable-kvm -hda debian_squeeze_amd64_standard.qcow2 -m 512 -net nic -net tap,ifname=tap0,script=no -curses
    
  15. ネストされた VM 上で、ifconfig を実行し、VM の virbr0 領域に 192.168.122.89 などのアドレスがあることを確認します。

    user@nested-vm:~$ ifconfig

  16. ポート 8000 でダミーのウェブサーバーを起動します。

    user@nested-vm:~$ python -m SimpleHTTPServer

  17. Ctrl + aCtrl + a ボタンを押して、ネストされた VM を終了します。

  18. ホスト VM がネストされた VM に対して ping を実行できるかどうかをテストします。

    curl 192.168.122.89:8000
    

    ネストされた VM は、次のような内容を返します。

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html>
    <title>Directory listing for /</title>
    <body>
    <h2>Directory listing for /</h2>
    <hr>
    <ol>
    <li><a href=".aptitude/">.aptitude/</a>
    <li><a href=".bashrc">.bashrc</a>
    <li><a href=".profile">.profile</a>
    </ol>
    <hr>
    </body>
    </html>
    
  19. ホスト VM 上で、iptables を設定し、ホスト VM からネストされた VM への転送を許可します。たとえば、192.168.122.89 ホスト VM にトラフィックを転送するためにエイリアス IP 10.128.0.13 を使用する場合は、次のようになります。

    echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
    sudo iptables -t nat -A PREROUTING -d 10.128.0.13 -j DNAT --to-destination 192.168.122.89
    sudo iptables -t nat -A POSTROUTING -d 192.168.122.89 -j MASQUERADE
    sudo iptables -A INPUT -p udp -j ACCEPT
    sudo iptables -A FORWARD -p tcp -j ACCEPT
    sudo iptables -A OUTPUT -p tcp -j ACCEPT
    sudo iptables -A OUTPUT -p udp -j ACCEPT
    

    注: この手順がうまくいかない場合、iptables をフラッシュする必要があります。

  20. 次に、ホストされている VM と同じネットワーク上にある別の VM にログインし、エイリアス IP に対して curl リクエストを実行します。次に例を示します。

    user@another-vm:~$ curl 10.128.0.13:8000

    ネストされた VM は、次のような内容を返します。

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html>
    <title>Directory listing for /</title>
    <body>
    <h2>Directory listing for /</h2>
    <hr>
    <ol>
    <li><a href=".aptitude/">.aptitude/</a>
    <li><a href=".bashrc">.bashrc</a>
    <li><a href=".profile">.profile</a>
    </ol>
    <hr>
    </body>
    </html>
    

トラブルシューティング

Google では、Compute Engine インスタンスで特定の Linux ディストリビューションとカーネル /KVM バージョンを使用して、ネストされた仮想化の基本的な起動および統合テストを行います。さらに、これらのテストでは特定のプロセスを使用します。問題をバグとして報告する前に、以下の項目を使用して問題を再現してください。

grep -c vmx /proc/cpuinfo を実行すると、0 が返され、VM でネストが有効になっていないと表示されます。

  1. Haswell 以上の CPU プラットフォームで VM を起動していることを確認してください。
  2. VM イメージで正しいライセンスを使用していることを確認してください。

自分のネストされた VM を終了できません。

それぞれのネストされた VM セッションの前に screen を実行しなかった場合、ネストされた VM から接続を解除することはできません。ネストされた VM を起動する前に、別の端末のホスト VM にログインしてプロセスを終了し、ホスト VM 上で screen を実行します。

iptables ルールが、ネストされた VM にトラフィックを転送していません。

  • iptables は、ルールを上から下に解決するので、ご使用のルールの優先順位が他のルールの優先順位よりも高いことを確認します。
  • パケットを妨害するような競合するルールがないことを確認します。
  • iptables をフラッシュすることを検討してください。

    1. まず、デフォルトのポリシーを設定します。

      sudo iptables -P INPUT ACCEPT
      sudo iptables -P FORWARD ACCEPT
      sudo iptables -P OUTPUT ACCEPT
      
    2. 次に、すべてのテーブルとチェーンをフラッシュし、デフォルト以外のチェーンを削除します。

      sudo iptables -t nat -F
      sudo iptables -t mangle -F
      sudo iptables -F
      sudo iptables -X
      
このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Compute Engine ドキュメント