ネストされた仮想化はデフォルトで許可されます。そのため、ネストされた仮想化の制約が変更されない限り、組織、フォルダ、プロジェクトにネストされた VM を作成する前に、変更を行う必要はありません。プロジェクトが組織に属していない場合、ネストされた仮想化はデフォルトで許可されます。この制約は変更できません。ネストされた VM を作成できるかどうかを決定する制約を変更する方法については、ネストされた仮想化の制約を管理するをご覧ください。
このドキュメントでは、さまざまなタイプのレベル 2(L2)仮想マシン(VM)インスタンスを作成する方法について説明します。ネストされた VM を作成する前に、ネストされた仮想化を有効にした L1 VM を作成する必要があります。L1 と L2 VM の詳細については、ネストされた仮想化の概要をご覧ください。
ネストされた仮想化が有効になった L1 VM を作成すると、次のことが可能になります。
- 外部ネットワークにアクセス可能な L2 VM の作成
- プライベート ネットワーク経由で L1 VM とブリッジする L2 VM の作成
- L1 VM の外部からのネットワーク アクセス可能な L2 VM の作成
準備
-
まだ設定していない場合は、認証を設定します。認証とは、Google Cloud サービスと API にアクセスするために ID を確認するプロセスです。ローカル開発環境からコードまたはサンプルを実行するには、次のように Compute Engine に対する認証を行います。
このページのサンプルをどのように使うかに応じて、タブを選択してください。
gcloud
-
Install the Google Cloud CLI, then initialize it by running the following command:
gcloud init
- デフォルトのリージョンとゾーンを設定します。
REST
このページの REST API サンプルをローカル開発環境で使用するには、gcloud CLI に指定した認証情報を使用します。
Install the Google Cloud CLI, then initialize it by running the following command:
gcloud init
-
外部ネットワークにアクセス可能な L2 VM の作成
外部ネットワークにアクセス可能な L2 VM を作成するには、次の操作を行います。この手順では、qemu-system-x86_64
を使用して L2 VM を起動します。別の手順で L2 VM を作成して問題が発生した場合は、サポートに問い合わせる前に、この手順を行い、同じ問題が発生するかどうか確認してください。
gcloud compute ssh
コマンドを使用して VM に接続します。gcloud compute ssh VM_NAME
VM_NAME
は、接続する VM の名前に置き換えます。最新の
qemu-kvm
パッケージをインストールします。sudo apt update && sudo apt install qemu-kvm -y
L2 VM に使用する QEMU 互換 OS イメージをダウンロードします。
次のコマンドを使用して L2 VM を起動します。プロンプトが表示されたら、
user: root
、password: root
でログインします。sudo qemu-system-x86_64 -enable-kvm -hda IMAGE_NAME -m 512 -curses
IMAGE_NAME
は、L2 VM に使用する QEMU 互換 OS イメージの名前に置き換えます。L2 VM が外部からアクセスできるかどうかテストします。
user@nested-vm:~$ host google.com
プライベート ネットワーク経由で L1 VM とブリッジする L2 VM の作成
以前に作成した L1 VM をプライベート ネットワーク経由でブリッジする L2 VM を作成するには、次の操作を行います。VPC ネットワークのデフォルトの最大送信単位(MTU)を変更する方法については、最大伝送単位の概要をご覧ください。
gcloud compute ssh
コマンドを使用して VM に接続します。gcloud compute ssh VM_NAME
VM_NAME
は、接続する VM の名前に置き換えます。プライベート ブリッジの作成に必要なパッケージをインストールします。
sudo apt update && sudo apt install uml-utilities qemu-kvm bridge-utils virtinst libvirt-daemon-system libvirt-clients -y
libvirt
パッケージに付属しているデフォルト ネットワークを起動します。sudo virsh net-start default
次のコマンドを実行して、
virbr0
ブリッジがあることを確認します。ip addr
出力は次のようになります。
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1460 qdisc pfifo_fast state UP group default qlen 1000 link/ether 42:01:0a:80:00:15 brd ff:ff:ff:ff:ff:ff inet 10.128.0.21/32 brd 10.128.0.21 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::4001:aff:fe80:15/64 scope link valid_lft forever preferred_lft forever 3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000 link/ether 52:54:00:8c:a6:a1 brd ff:ff:ff:ff:ff:ff inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0 valid_lft forever preferred_lft forever 4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000 link/ether 52:54:00:8c:a6:a1 brd ff:ff:ff:ff:ff:ff
L1 VM から L2 VM に接続する
tap
インターフェースを作成します。sudo tunctl -t tap0 sudo ifconfig tap0 up
tap
インターフェースをプライベート ブリッジにボンドします。sudo brctl addif virbr0 tap0
次のコマンドを実行して、ブリッジ ネットワークの設定を確認します。
sudo brctl show
出力は次のようになります。
bridge name bridge id STP enabled interfaces virbr0 8000.5254008ca6a1 yes tap0 virbr0-nic
L2 VM に使用する QEMU 互換 OS イメージをダウンロードします。
screen
を実行します。ウェルカム プロンプトで Enter キーを押します。screen
次のコマンドを使用して L2 VM を起動します。プロンプトが表示されたら、
user: root
、password: root
でログインします。sudo qemu-system-x86_64 -enable-kvm -hda IMAGE_NAME -m 512 -net nic -net tap,ifname=tap0,script=no -curses
IMAGE_NAME
は、L2 VM に使用する QEMU 互換 OS イメージの名前に置き換えます。L2 VM で
ip addr show
を実行して、VM のアドレスがvirbr0
領域(192.168.122.89
など)にあることを確認します。user@nested-vm:~$ ip addr
ポート
8000
でプレースホルダ ウェブサーバーを起動します。user@nested-vm:~$ python -m http.server
Ctrl+A
、Ctrl+D
でscreen
セッションから切断します。L1 VM から L2 VM に ping を実行します。次の IP アドレスは L2 VM の IP アドレスに置き換えます。
curl 192.168.122.89:8000
出力は次のようになります。
<!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>
L1 VM の外部からのネットワーク アクセスが可能な L2 VM の作成
L1 VM の外部の VM が L2 VM にアクセスできるように、エイリアス IP を使用して L2 VM を設定できます。以前に作成した L1 VM の外部からエイリアス IP を使用してアクセス可能な L2 VM を作成するには、次の操作を行います。エイリアス IP アドレスの作成方法については、エイリアス IP 範囲を構成するをご覧ください。
次の手順では、subnet1
というサブネットが作成されていることを前提としています。別の名前のサブネットが存在する場合は、subnet1
をそのサブネット名で置き換えるか、subnet1
という名前で新しいサブネットを作成します。
ネストされた仮想化を有効にした L1 VM を作成し、エイリアス IP 範囲と HTTP / HTTPS トラフィックのサポートを追加します。
gcloud
gcloud compute instances create VM_NAME --enable-nested-virtualization \ --tags http-server,https-server --can-ip-forward \ --min-cpu-platform "Intel Haswell" \ --network-interface subnet=subnet1,aliases=/30
VM_NAME
は、L1 VM の名前に置き換えます。REST
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances { ... "name": VM_NAME, "tags": { "items": [ http-server,https-server ], }, "canIpForward": true, "networkInterfaces": [ { "subnetwork": "subnet1", "aliasIpRanges": [ { "ipCidrRange": "/30" } ], } ], "minCpuPlatform": "Intel Haswell", "advancedMachineFeatures": { "enableNestedVirtualization": true }, ... }
次のように置き換えます。
PROJECT_ID
: プロジェクト IDZONE
: VM を作成するゾーンVM_NAME
: VM の名前
gcloud compute ssh
コマンドを使用して VM に接続します。VM への接続に問題がある場合は、VM のリセットまたはファイアウォール ルールの変更を試します。gcloud compute ssh VM_NAME
VM_NAME
は、接続する VM の名前に置き換えます。VM を更新し、必要なパッケージをインストールします。
sudo apt update && sudo apt install uml-utilities qemu-kvm bridge-utils virtinst libvirt-daemon-system libvirt-clients -y
libvirt
パッケージに付属しているデフォルト ネットワークを起動します。sudo virsh net-start default
次のコマンドを実行して、
virbr0
ブリッジがあることを確認します。user@nested-vm:~$ ip addr
次のような内容が出力されていることを確認します。
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1460 qdisc pfifo_fast state UP group default qlen 1000 link/ether 42:01:0a:80:00:15 brd ff:ff:ff:ff:ff:ff inet 10.128.0.21/32 brd 10.128.0.21 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::4001:aff:fe80:15/64 scope link valid_lft forever preferred_lft forever 3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000 link/ether 52:54:00:8c:a6:a1 brd ff:ff:ff:ff:ff:ff inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0 valid_lft forever preferred_lft forever 4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000 link/ether 52:54:00:8c:a6:a1 brd ff:ff:ff:ff:ff:ff
L1 VM から L2 VM に接続する
tap
インターフェースを作成します。sudo tunctl -t tap0 sudo ifconfig tap0 up
tap
インターフェースをプライベート ブリッジにボンドします。sudo brctl addif virbr0 tap0
次のコマンドを実行して、ブリッジ ネットワークの設定を確認します。
sudo brctl show
次のような内容が出力されていることを確認します。
bridge name bridge id STP enabled interfaces virbr0 8000.5254008ca6a1 yes tap0 virbr0-nic
L2 VM に使用する QEMU 互換 OS イメージをダウンロードします。
screen
を実行します。ウェルカム プロンプトで Enter キーを押します。screen
次のコマンドを使用して、ネストされた VM を起動します。プロンプトが表示されたら、
user: root
、password: root
でログインします。sudo qemu-system-x86_64 -enable-kvm -hda IMAGE_NAME -m 512 -net nic -net tap,ifname=tap0,script=no -curses
IMAGE_NAME
は、L2 VM に使用する QEMU 互換 OS イメージの名前に置き換えます。L2 VM で
ip addr
を実行して、L2 VM のアドレスが virbr0 領域(192.168.122.89
など)にあることを確認します。user@nested-vm:~$ ip addr
ポート
8000
でプレースホルダ ウェブサーバーを起動します。user@nested-vm:~$ python -m http.server
Ctrl+A
、Ctrl+D
でscreen
セッションから切断します。L1 VM から L2 VM に ping を実行します。次の IP アドレスは L2 VM の IP アドレスに置き換えます。
curl 192.168.122.89:8000
L2 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>
L1 VM で、L1 VM から L2 VM への転送を許可するように
iptables
を設定します。この手順で使用する L2 OS イメージで、IP テーブルを更新する必要があります。sudo iptables -F
L1 VM のエイリアス IP を確認します。
ip route show table local
次のような内容が出力されていることを確認します。この例では、L2 VM の
eth0
イーサネット デバイスに 2 つの IP アドレスが関連付けられています。1 つ目の10.128.0.2
は、sudo ifconfig -a
によって返される L2 VM のプライマリ IP アドレスです。2 つ目の10.128.0.13
は L2 VM のエイリアス IP アドレスです。local 10.128.0.2 dev eth0 proto kernel scope host src 10.128.0.2 broadcast 10.128.0.2 dev eth0 proto kernel scope link src 10.128.0.2 local 10.128.0.13/30 dev eth0 proto 66 scope host broadcast 127.0.0.0 dev lo proto kernel scope link src 127.0.0.1 local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1 local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1 broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1 broadcast 192.168.122.0 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown local 192.168.122.1 dev virbr0 proto kernel scope host src 192.168.122.1 broadcast 192.168.122.255 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown
次のコマンドを実行して、サンプル エイリアス IP(
10.128.0.13
)から L2 VM のサンプル IP(192.168.122.89
)にトラフィックを転送します。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 -s 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
のトラブルシューティングについては、iptables
がトラフィックを転送しないをご覧ください。L1 VM と同じネットワークにある別の VM にログインし、エイリアス IP に
curl
リクエストを送信して、L1 VM 外部から L2 VM へのアクセスを確認します。以下の IP アドレスは、L2 VM のエイリアス IP に置き換えます。user@another-vm:~$ curl 10.128.0.13:8000
curl
から次のようなレスポンスが返されているかどうか確認します。<!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>