Crie VMs aninhadas


A virtualização aninhada é permitida por predefinição. Por isso, a menos que alguém modifique a restrição para a virtualização aninhada, não precisa de fazer alterações antes de criar VMs aninhadas numa organização, numa pasta ou num projeto. Se o seu projeto não pertencer a uma organização, a virtualização aninhada é permitida por predefinição e não pode alterar a restrição. Para obter informações sobre como modificar a restrição que determina se pode criar VMs aninhadas, consulte o artigo Faça a gestão da restrição de virtualização aninhada.

Este documento descreve como criar vários tipos de instâncias de máquinas virtuais (VM) de nível 2 (L2). Antes de criar uma VM aninhada, tem de criar uma VM de nível 1 com a virtualização aninhada ativada. Para uma descrição das VMs de Nível 1 e Nível 2, consulte a vista geral da virtualização aninhada.

Depois de criar uma VM de nível 1 com a virtualização aninhada ativada, pode fazer qualquer uma das seguintes ações:

  • Crie uma VM de nível 2 com acesso à rede externa
  • Crie uma VM de nível 2 com uma ponte de rede privada para a VM de nível 1
  • Crie uma VM de nível 2 com acesso à rede a partir do exterior da VM de nível 1

Antes de começar

  • Se ainda não o tiver feito, configure a autenticação. A autenticação valida a sua identidade para aceder a Google Cloud serviços e APIs. Para executar código ou exemplos a partir de um ambiente de desenvolvimento local, pode autenticar-se no Compute Engine selecionando uma das seguintes opções:

    Select the tab for how you plan to use the samples on this page:

    gcloud

    1. Instale a CLI Google Cloud. Após a instalação, inicialize a CLI gcloud executando o seguinte comando:

      gcloud init

      Se estiver a usar um fornecedor de identidade (IdP) externo, primeiro tem de iniciar sessão na CLI gcloud com a sua identidade federada.

    2. Set a default region and zone.

    REST

    Para usar os exemplos da API REST nesta página num ambiente de desenvolvimento local, usa as credenciais que fornece à CLI gcloud.

      Instale a CLI Google Cloud. Após a instalação, inicialize a CLI gcloud executando o seguinte comando:

      gcloud init

      Se estiver a usar um fornecedor de identidade (IdP) externo, primeiro tem de iniciar sessão na CLI gcloud com a sua identidade federada.

    Para mais informações, consulte o artigo Autenticar para usar REST na Google Cloud documentação de autenticação.

Criar uma VM de nível 2 com acesso à rede externa

Crie uma VM de nível 2 com acesso à rede externa através do seguinte procedimento. Este procedimento usa o comando qemu-system-x86_64 para iniciar a VM de nível 2. Se estiver a usar outro procedimento para criar uma VM de nível 2 e estiver a ter problemas, reproduza o problema através deste procedimento antes de contactar o apoio técnico.

  1. Crie uma VM de nível 1 com a virtualização aninhada ativada.

  2. Use o comando gcloud compute ssh para estabelecer ligação à VM:

    gcloud compute ssh VM_NAME
    

    Substitua VM_NAME pelo nome da VM à qual se quer ligar.

  3. Instale o pacote qemu-kvm mais recente:

    sudo apt update && sudo apt install qemu-kvm -y
    
  4. Transfira uma imagem do SO compatível com QEMU para usar na VM de nível 2.

  5. Use o seguinte comando para iniciar a VM de nível 2. Quando lhe for pedido, inicie sessão 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 a usar para a VM de nível 2.

  6. Teste se a VM de nível 2 tem acesso externo:

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

Criar uma VM de nível 2 com uma ponte de rede privada para a VM de nível 1

Crie uma VM de nível 2 com uma ponte de rede privada para a VM de nível 1 criada anteriormente através do seguinte procedimento. Para obter informações sobre como alterar a unidade de transmissão máxima (MTU) predefinida para a sua rede VPC, consulte a vista geral da unidade de transmissão máxima.

  1. Crie uma VM de nível 1 com a virtualização aninhada ativada.

  2. Use o comando gcloud compute ssh para estabelecer ligação à VM:

    gcloud compute ssh VM_NAME
    

    Substitua VM_NAME pelo nome da VM à qual se quer ligar.

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

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

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

    ip addr
    
  6. O resultado é semelhante ao seguinte:

    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 passar da VM L1 para a VM L2:

    sudo tunctl -t tap0
    sudo ifconfig tap0 up
    
  8. Associe a interface tap à ponte privada:

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

    sudo brctl show
    
  10. O resultado é semelhante ao seguinte:

    bridge name     bridge id               STP enabled     interfaces
    virbr0          8000.5254008ca6a1       yes             tap0
                                                            virbr0-nic
    
  11. Transfira uma imagem do SO compatível com QEMU para usar na VM de nível 2.

  12. Execute screen e prima Enter no comando de boas-vindas:

    screen
    
  13. Use o seguinte comando para iniciar a VM de nível 2. Quando lhe for pedido, inicie sessão 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 a usar para a VM de nível 2.

  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 Web de marcador de posição na porta 8000:

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

  17. Teste se a VM L1 consegue enviar um ping para a VM L2, substituindo o seguinte endereço IP pelo endereço IP da VM L2:

    curl 192.168.122.89:8000
    
  18. O resultado é semelhante ao seguinte:

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

Criar uma VM de nível 2 com acesso à rede a partir de fora da VM de nível 1

Pode configurar uma VM de nível 2 com um IP de alias para que as VMs fora da VM de nível 1 possam aceder à VM de nível 2. Use o procedimento seguinte para criar uma VM de nível 2 com acesso à rede através de um IP de alias a partir do exterior da VM de nível 1 criada anteriormente. Para informações sobre a criação de endereços IP de alias, consulte o artigo Configure intervalos de IP de alias.

O procedimento seguinte pressupõe uma sub-rede criada anteriormente denominada subnet1. Se já tiver uma sub-rede com um nome diferente, substitua subnet1 pelo nome da sub-rede ou crie uma nova sub-rede com o nome subnet1.

  1. Crie uma VM de nível 1 com a virtualização aninhada ativada e inclua um intervalo de IPs de alias e suporte para 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 de nível 1.

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

    Substitua o seguinte:

    • PROJECT_ID: o ID do projeto

    • ZONE: a zona na qual criar a VM

    • VM_NAME: o nome da VM

  2. Use o comando gcloud compute ssh para estabelecer ligação à VM. Se tiver problemas ao estabelecer ligação à VM, experimente repor a VM ou modificar as regras da firewall.

    gcloud compute ssh VM_NAME
    

    Substitua VM_NAME pelo nome da VM à qual se quer ligar.

  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 predefinida fornecida com o pacote libvirt:

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

    user@nested-vm:~$ ip addr
    
  6. Verifique se a saída é semelhante à seguinte:

    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 passar da VM L1 para a VM L2:

    sudo tunctl -t tap0
    sudo ifconfig tap0 up
    
  8. Associe a interface tap à ponte privada:

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

    sudo brctl show
    
  10. Verifique se a saída é semelhante à seguinte:

    bridge name     bridge id               STP enabled     interfaces
    virbr0          8000.5254008ca6a1       yes             tap0
                                                            virbr0-nic
    
  11. Transfira uma imagem do SO compatível com QEMU para usar na VM de nível 2.

  12. Execute screen e prima Enter no comando de boas-vindas:

    screen
    
  13. Use o seguinte comando para iniciar a VM aninhada. Quando lhe for pedido, inicie sessão 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 a usar para a VM de nível 2.

  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 Web de marcador de posição na porta 8000:

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

  17. Teste se a VM de nível 1 consegue enviar um ping para a VM de nível 2. Substitua o endereço IP abaixo pelo endereço IP da VM de nível 2:

    curl 192.168.122.89:8000
    
  18. Verifique se a resposta da VM de nível 2 é semelhante à seguinte:

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

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

    ip route show table local
    
  21. Verifique se o resultado é semelhante ao seguinte. Para este exemplo, existem dois endereços IP associados ao dispositivo Ethernet da VM L2.eth0 O primeiro, 10.128.0.2, é o endereço IP principal da VM de nível 2, que é devolvido por sudo ifconfig -a. O segundo, 10.128.0.13, é o endereço IP alias da VM de nível 2.

    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 seguintes comandos para encaminhar o tráfego do IP do alias de exemplo 10.128.0.13 para o IP de exemplo 192.168.122.89 da VM de nível 2:

    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
    

    Para obter informações sobre a resolução de problemas de iptables, consulte o artigo iptables não encaminha tráfego.

  23. Verifique o acesso à VM L2 a partir do exterior da VM L1 iniciando sessão noutra VM que esteja na mesma rede que a VM L1 e fazendo um pedido curl ao IP do alias, substituindo o endereço IP abaixo pelo IP do alias da VM L2:

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

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

O que se segue?