Crear máquinas virtuales anidadas


La virtualización anidada está permitida de forma predeterminada, por lo que, a menos que alguien modifique la restricción de la virtualización anidada, no es necesario realizar ningún cambio antes de crear máquinas virtuales anidadas en una organización, carpeta o proyecto. Si su proyecto no pertenece a una organización, la virtualización anidada está permitida de forma predeterminada y no puede cambiar la restricción. Para obtener información sobre cómo modificar la restricción que determina si puede crear máquinas virtuales anidadas, consulte Administrar la restricción de virtualización anidada .

Este documento describe cómo crear varios tipos de instancias de máquina virtual (VM) de nivel 2 (L2). Antes de crear una máquina virtual anidada, debe crear una máquina virtual L1 que tenga habilitada la virtualización anidada . Para obtener una descripción de las máquinas virtuales L1 y L2, consulte la descripción general de la virtualización anidada .

Después de crear una máquina virtual L1 que tenga habilitada la virtualización anidada, puede realizar cualquiera de las siguientes acciones:

  • Cree una máquina virtual L2 con acceso a la red externa
  • Cree una VM L2 con un puente de red privado a la VM L1
  • Cree una VM L2 con acceso a la red desde fuera de la VM L1

Antes de comenzar

  • Si aún no lo has hecho, configura la autenticación. La autenticación es el proceso mediante el cual se verifica su identidad para acceder a Google Cloud servicios y API. Para ejecutar código o muestras desde un entorno de desarrollo local, puedes autenticarte en Compute Engine seleccionando una de las siguientes opciones:

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

    gcloud

    1. After installing the Google Cloud CLI, initialize it by running the following command:

      gcloud init

      If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

    2. Set a default region and zone.
    3. REST

      Para usar las muestras de la API de REST en esta página en un entorno de desarrollo local, debes usar las credenciales que proporcionas a la CLI de gcloud.

        After installing the Google Cloud CLI, initialize it by running the following command:

        gcloud init

        If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

      Para obtener más información, consulta Autentica para usar REST en la documentación de autenticación de Google Cloud .

Crear una VM L2 con acceso a la red externa

Cree una máquina virtual L2 con acceso a la red externa mediante el siguiente procedimiento. Este procedimiento utiliza qemu-system-x86_64 para iniciar la VM L2. Si está utilizando otro procedimiento para crear una VM L2 y tiene problemas, reproduzca el problema usando este procedimiento antes de comunicarse con el soporte .

  1. Cree una máquina virtual L1 que tenga habilitada la virtualización anidada .

  2. Usa el comando gcloud compute ssh para conectarte a la VM:

    gcloud compute ssh VM_NAME
    

    Reemplace VM_NAME con el nombre de la VM a la que conectarse.

  3. Instale el último paquete qemu-kvm :

    sudo apt update && sudo apt install qemu-kvm -y
    
  4. Descargue una imagen del sistema operativo compatible con QEMU para usarla en la VM L2.

  5. Utilice el siguiente comando para iniciar la VM L2. Cuando se le solicite, inicie sesión con user: root , password: root .

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

    Reemplace IMAGE_NAME con el nombre de la imagen del sistema operativo compatible con QEMU que se usará para la VM L2.

  6. Pruebe que su VM L2 tenga acceso externo:

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

Crear una VM L2 con un puente de red privado a la VM L1

Cree una máquina virtual de capa 2 con un puente de red privado a la máquina virtual de capa 1 creada previamente mediante el siguiente procedimiento. Para obtener información sobre cómo cambiar la unidad de transmisión máxima (MTU) predeterminada para su red VPC, consulte la descripción general de la unidad de transmisión máxima .

  1. Cree una máquina virtual L1 que tenga habilitada la virtualización anidada .

  2. Usa el comando gcloud compute ssh para conectarte a la VM:

    gcloud compute ssh VM_NAME
    

    Reemplace VM_NAME con el nombre de la VM a la que conectarse.

  3. Instale los paquetes necesarios para crear el puente privado:

    sudo apt update && sudo apt install uml-utilities qemu-kvm bridge-utils virtinst libvirt-daemon-system libvirt-clients -y
    
  4. Inicie la red predeterminada que viene con el paquete libvirt :

    sudo virsh net-start default
    
  5. Ejecute el siguiente comando para comprobar que tiene el puente virbr0 :

    ip addr
    
  6. El resultado es similar al siguiente:

    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. Cree una interfaz tap para pasar de la VM L1 a la VM L2:

    sudo tunctl -t tap0
    sudo ifconfig tap0 up
    
  8. Conecte la interfaz tap al puente privado:

    sudo brctl addif virbr0 tap0
    
  9. Ejecute el siguiente comando para verificar la configuración de la red puente:

    sudo brctl show
    
  10. El resultado es similar al siguiente:

    bridge name     bridge id               STP enabled     interfaces
    virbr0          8000.5254008ca6a1       yes             tap0
                                                            virbr0-nic
    
  11. Descargue una imagen del sistema operativo compatible con QEMU para usarla en la VM L2.

  12. Ejecute screen y presione Entrar en el mensaje de bienvenida:

    screen
    
  13. Utilice el siguiente comando para iniciar la VM L2. Cuando se le solicite, inicie sesión con 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
    

    Reemplace IMAGE_NAME con el nombre de la imagen del sistema operativo compatible con QEMU que se usará para la VM L2.

  14. En la VM L2, ejecute ip addr show para confirmar que la VM tiene una dirección en el espacio virbr0 , por ejemplo, 192.168.122.89 :

    user@nested-vm:~$ ip addr
    
  15. Inicie un servidor web de marcador de posición en el puerto 8000 :

    user@nested-vm:~$ python -m http.server
    
  16. Separe de la sesión screen con Ctrl+A , Ctrl+D .

  17. Pruebe que su VM L1 pueda hacer ping a la VM L2, reemplazando la siguiente dirección IP con la dirección IP de la VM L2:

    curl 192.168.122.89:8000
    
  18. El resultado es similar al siguiente:

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

Crear una VM L2 con acceso a la red desde fuera de la VM L1

Puede configurar una VM L2 con un alias IP para que las VM fuera de la VM L1 puedan acceder a la VM L2. Utilice el siguiente procedimiento para crear una VM L2 con acceso a la red mediante un alias IP desde fuera de la VM L1 creada previamente. Para obtener información sobre cómo crear direcciones IP de alias, consulte Configurar rangos de IP de alias .

El siguiente procedimiento supone una subred creada previamente llamada subnet1 . Si ya tiene una subred con un nombre diferente, reemplace subnet1 con el nombre de su subred o cree una nueva subred llamada subnet1 .

  1. Cree una máquina virtual L1 con la virtualización anidada habilitada e incluya un rango de IP de alias y compatibilidad con el tráfico HTTP/HTTPS:

    nube de 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
    

    Reemplace VM_NAME con el nombre de la VM L1.

    DESCANSAR

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

    Reemplace lo siguiente:

    • PROJECT_ID : el ID del proyecto

    • ZONE : la zona para crear la VM en

    • VM_NAME : el nombre de la VM

  2. Usa el comando gcloud compute ssh para conectarte a la VM. Si tiene problemas para conectarse a la VM, intente restablecerla o modificar las reglas del firewall.

    gcloud compute ssh VM_NAME
    

    Reemplace VM_NAME con el nombre de la VM a la que conectarse.

  3. Actualice la VM e instale los paquetes necesarios:

    sudo apt update && sudo apt install uml-utilities qemu-kvm bridge-utils virtinst libvirt-daemon-system libvirt-clients -y
    
  4. Inicie la red predeterminada que viene con el paquete libvirt :

    sudo virsh net-start default
    
  5. Ejecute el siguiente comando para comprobar que tiene el puente virbr0 :

    user@nested-vm:~$ ip addr
    
  6. Verifique un resultado similar al siguiente:

    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. Cree una interfaz tap para pasar de la VM L1 a la VM L2:

    sudo tunctl -t tap0
    sudo ifconfig tap0 up
    
  8. Conecte la interfaz tap al puente privado:

    sudo brctl addif virbr0 tap0
    
  9. Ejecute el siguiente comando para verificar la configuración de la red puente:

    sudo brctl show
    
  10. Verifique un resultado similar al siguiente:

    bridge name     bridge id               STP enabled     interfaces
    virbr0          8000.5254008ca6a1       yes             tap0
                                                            virbr0-nic
    
  11. Descargue una imagen del sistema operativo compatible con QEMU para usarla en la VM L2.

  12. Ejecute screen y presione Entrar en el mensaje de bienvenida:

    screen
    
  13. Utilice el siguiente comando para iniciar la VM anidada. Cuando se le solicite, inicie sesión con 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
    

    Reemplace IMAGE_NAME con el nombre de la imagen del sistema operativo compatible con QEMU que se usará para la VM L2.

  14. En la VM L2, ejecute ip addr para confirmar que la VM L2 tiene una dirección en el espacio virbr0, como 192.168.122.89 :

    user@nested-vm:~$ ip addr
    
  15. Inicie un servidor web de marcador de posición en el puerto 8000 :

    user@nested-vm:~$ python -m http.server
    
  16. Separe de la sesión screen con Ctrl+A , Ctrl+D .

  17. Pruebe que su VM L1 pueda hacer ping a la VM L2, reemplace la dirección IP a continuación con la dirección IP de la VM L2:

    curl 192.168.122.89:8000
    
  18. Verifique que la respuesta de la VM L2 sea similar a la siguiente:

    <!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. En la VM L1, configure iptables para permitir el reenvío desde la VM L1 a la VM L2. Para la imagen del sistema operativo L2 utilizada en estas instrucciones, debe vaciar las tablas de IP:

    sudo iptables -F
    
  20. Determine el alias IP de la VM L1:

    ip route show table local
    
  21. Verifique que el resultado sea similar al siguiente. Para este ejemplo, hay dos direcciones IP asociadas con el dispositivo Ethernet eth0 de la VM L2. La primera, 10.128.0.2 , es la dirección IP principal de la VM L2, que devuelve sudo ifconfig -a . El segundo, 10.128.0.13 , es la dirección IP alias de la 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. Ejecute los siguientes comandos para reenviar el tráfico desde la IP de alias de ejemplo 10.128.0.13 a la IP de ejemplo 192.168.122.89 para la VM L2:

    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 obtener información sobre la solución de problemas iptables , consulte iptables no reenvía tráfico .

  23. Verifique el acceso a la VM L2 desde fuera de la VM L1 iniciando sesión en otra VM que esté en la misma red que la VM L1 y realizando una solicitud curl al alias IP, reemplazando la dirección IP siguiente con el alias IP de la VM L2:

    user@another-vm:~$ curl 10.128.0.13:8000
    
  24. Verifique que la respuesta curl sea similar a la siguiente:

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

¿Qué sigue?