Como criar VMs aninhadas


A virtualização aninhada é permitida por padrão. Portanto, a menos que alguém modifique a restrição da virtualização aninhada, você não precisará fazer alterações antes de criar VMs aninhadas em uma organização, pasta ou projeto. Se o projeto não pertencer a uma organização, a virtualização aninhada será permitida por padrão e não será possível alterar a restrição. Para informações sobre como modificar a restrição que determina se é possível criar VMs aninhadas, consulte Como gerenciar a restrição de virtualização aninhada.

Neste documento, descrevemos como criar vários tipos de instâncias de máquina virtual (VM) de nível 2 (L2). Antes de criar uma VM aninhada, crie uma VM L1 com a virtualização aninhada ativada. Para uma descrição de VMs L1 e L2, consulte a Visão geral da virtualização aninhada.

Depois de criar uma VM L1 com a virtualização aninhada ativada, será possível fazer o seguinte:

  • Criar uma VM L2 com acesso de rede externo
  • Criar uma VM L2 com uma ponte de rede privada para a VM L1
  • Criar uma VM L2 com acesso de rede de fora da VM L1

Como criar uma VM L2 com acesso de rede externa

Crie uma VM L2 com acesso de rede externa usando o procedimento a seguir. Este procedimento usa qemu-system-x86_64 (em inglês) para iniciar a VM L2. Se você estiver usando outro procedimento para criar uma VM L2 e tiver problemas, reproduza o problema usando este procedimento antes de entrar em contato com o suporte.

  1. Crie uma VM L1 que tenha a virtualização aninhada ativada.

  2. Use o comando gcloud compute ssh para conectar-se à VM:

    gcloud compute ssh VM_NAME
    

    Substitua VM_NAME pelo nome da VM à qual se conectar.

  3. Instale o pacote qemu-kvm mais recente:

    sudo apt update && sudo apt install qemu-kvm -y
    
  4. Faça o download de uma imagem do SO compatível com QEMU para usar na VM L2. Para informações sobre os sistemas operacionais testados para uso com a virtualização aninhada, consulte Visão geral da virtualização aninhada.

  5. Use o seguinte comando para iniciar a VM L2: Quando solicitado, faça login com user: root, password: root.

    sudo qemu-system-x86_64 -enable-kvm -hda IMAGE_NAME -m 512 -curses
    

    Substitua IMAGE_NAME pelo nome da imagem do SO compatível com QEMU para usar na VM L2.

  6. Verifique se a VM L2 tem acesso externo:

    user@nested-vm:~$ host google.com
    

Como criar uma VM L2 com uma ponte de rede privada para a VM L1

Use o procedimento a seguir para criar uma VM L2 com uma ponte de rede particular em uma VM L1 criada anteriormente. Saiba mais sobre como alterar a unidade padrão de transmissão máxima (MTU) para sua rede VPC em uma visão geral da unidade de transmissão máxima.

  1. Crie uma VM L1 com a virtualização aninhada ativada.

  2. Use o comando gcloud compute ssh para conectar-se à VM:

    gcloud compute ssh VM_NAME
    

    Substitua VM_NAME pelo nome da VM à qual se conectar.

  3. Instale os pacotes necessários para criar a ponte particular:

    sudo apt update && sudo apt install uml-utilities qemu-kvm bridge-utils virtinst libvirt-daemon-system libvirt-clients -y
    
  4. Inicie a rede padrão que vem com o pacote libvirt:

    sudo virsh net-start default
    
  5. Execute o seguinte comando para verificar se você tem a ponte virbr0:

    ip addr
    
  6. A resposta será semelhante a:

    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
    
  7. Crie uma interface tap para ir da VM L1 para a VM L2:

    sudo tunctl -t tap0
    sudo ifconfig tap0 up
    
  8. Vincule a interface tap à ponte particular:

    sudo brctl addif virbr0 tap0
    
  9. Execute o seguinte comando para verificar a configuração da rede de ponte:

    sudo brctl show
    
  10. A resposta será semelhante a:

    bridge name     bridge id               STP enabled     interfaces
    virbr0          8000.5254008ca6a1       yes             tap0
                                                            virbr0-nic
    
  11. Faça o download de uma imagem do SO compatível com QEMU para usar na VM L2. Para informações sobre os sistemas operacionais testados para uso com a virtualização aninhada, consulte Visão geral da virtualização aninhada.

  12. Execute screen e pressione Enter no prompt de boas-vindas:

    screen
    
  13. Use o seguinte comando para iniciar a VM L2: Quando solicitado, faça login com 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
    

    Substitua IMAGE_NAME pelo nome da imagem do SO compatível com QEMU para usar na VM L2.

  14. Na VM L2, execute ip addr show para confirmar que a VM tem um endereço no espaço virbr0, por exemplo, 192.168.122.89:

    user@nested-vm:~$ ip addr
    
  15. Inicie um servidor da Web de marcador na porta 8000:

    user@nested-vm:~$ python -m http.server
    
  16. Desconecte-se da sessão screen com Ctrl+A, Ctrl+D.

  17. Teste se a VM L1 pode dar um ping na VM L2, substituindo o endereço IP a seguir pelo endereço IP da VM L2:

    curl 192.168.122.89:8000
    
  18. A resposta será semelhante a:

    <!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>
    

Como criar uma VM L2 com acesso de rede de fora da VM L1

É possível configurar uma VM L2 com um IP de alias para que as VMs fora da VM L1 possam acessar a VM L2. Use o procedimento a seguir para criar uma VM L2 com acesso à rede por meio de um IP de alias de fora da VM L1 criada anteriormente. Para informações sobre como criar endereços IP de alias, consulte Como configurar intervalos de IP de alias.

O procedimento a seguir pressupõe uma sub-rede criada anteriormente chamada subnet1. Se você já tiver uma sub-rede com um nome diferente, substitua subnet1 pelo nome da sub-rede ou crie uma nova sub-rede chamada subnet1.

  1. Crie uma VM L1 com virtualização aninhada ativa e inclua um intervalo de IP do alias e compatibilidade com o tráfego 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
    

    Substitua VM_NAME pelo nome da VM L1.

    API

    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
      },
      ...
    }
    

    Substitua:

    • PROJECT_ID: o ID do projeto;

    • ZONE: a zona em que a VM será criada

    • VM_NAME: O nome da VM.

  2. Use o comando gcloud compute ssh para se conectar à VM. Se tiver problemas para se conectar à VM, tente redefini-la ou modificar as regras de firewall.

    gcloud compute ssh VM_NAME
    

    Substitua VM_NAME pelo nome da VM à qual se conectar.

  3. Atualize a VM e instale os pacotes necessários:

    sudo apt update && sudo apt install uml-utilities qemu-kvm bridge-utils virtinst libvirt-daemon-system libvirt-clients -y
    
  4. Inicie a rede padrão que vem com o pacote libvirt:

    sudo virsh net-start default
    
  5. Execute o seguinte comando para verificar se você tem a ponte virbr0:

    user@nested-vm:~$ ip addr
    
  6. Verifique um resultado semelhante a este:

    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
    
  7. Crie uma interface tap para ir da VM L1 para a VM L2:

    sudo tunctl -t tap0
    sudo ifconfig tap0 up
    
  8. Vincule a interface tap à ponte particular:

    sudo brctl addif virbr0 tap0
    
  9. Execute o seguinte comando para verificar a configuração da rede de ponte:

    sudo brctl show
    
  10. Verifique um resultado semelhante a este:

    bridge name     bridge id               STP enabled     interfaces
    virbr0          8000.5254008ca6a1       yes             tap0
                                                            virbr0-nic
    
  11. Faça o download de uma imagem do SO compatível com QEMU para usar na VM L2. Para informações sobre os sistemas operacionais testados para uso com a virtualização aninhada, consulte Visão geral da virtualização aninhada.

  12. Execute screen e pressione Enter no prompt de boas-vindas:

    screen
    
  13. Use o seguinte comando para iniciar a VM aninhada: Quando solicitado, faça login com 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
    

    Substitua IMAGE_NAME pelo nome da imagem do SO compatível com QEMU para usar na VM L2.

  14. Na VM L2, execute ip addr para confirmar que a VM L2 tem um endereço no espaço virbr0, como 192.168.122.89:

    user@nested-vm:~$ ip addr
    
  15. Inicie um servidor da Web de marcador na porta 8000:

    user@nested-vm:~$ python -m http.server
    
  16. Desconecte-se da sessão screen com Ctrl+A, Ctrl+D.

  17. Teste se a VM L1 pode dar um ping na VM L2. Substitua o endereço IP abaixo pelo endereço IP da VM L2:

    curl 192.168.122.89:8000
    
  18. Verifique se a resposta da VM L2 é semelhante a esta:

    <!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. Na VM L1, configure iptables para permitir o encaminhamento da VM L1 para a VM L2. Para a imagem do SO L2 usada nestas instruções, limpe as tabelas IP:

    sudo iptables -F
    
  20. Determine o IP de alias da VM L2:

    ip route show table local
    
  21. Verifique se a saída é semelhante a esta. Neste exemplo, há dois endereços IP associados ao dispositivo Ethernet eth0 da VM L2: O primeiro, 10.128.0.2, é o endereço IP principal da VM L2, que é retornado por sudo ifconfig -a. O segundo, 10.128.0.13, é o endereço IP de alias da VM L2.

    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
    
  22. Execute os comandos a seguir para encaminhar o tráfego do IP de alias de exemplo 10.128.0.13 para o IP de exemplo 192.168.122.89 da VM L2. Para obter informações sobre a solução de problemas de iptables, consulte iptables sem tráfego de encaminhamento:

    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
    
  23. Verifique o acesso da VM L2 de fora da VM L1. Para isso, faça login em outra VM que esteja na mesma rede que a VM L1 e faça uma solicitação curl ao IP de alias, substituindo o endereço IP abaixo pelo IP de alias da VM L2:

    user@another-vm:~$ curl 10.128.0.13:8000
    
  24. Verifique se a resposta de curl é semelhante a esta:

    <!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>
    

A seguir