Créer des VM imbriquées


La virtualisation imbriquée est autorisée par défaut. Par conséquent, vous n'avez pas besoin d'apporter de modification avant de créer des VM imbriquées dans une organisation, un dossier ou un projet, sauf si quelqu'un modifie la contrainte de virtualisation imbriquée. Si votre projet n'appartient pas à une organisation, la virtualisation imbriquée est autorisée par défaut, et vous ne pouvez pas modifier la contrainte. Pour savoir comment modifier la contrainte qui détermine si vous pouvez créer des VM imbriquées, consultez la page Gérer la contrainte de virtualisation imbriquée.

Ce document explique comment créer différents types d'instances de machines virtuelles (VM) de niveau 2 (L2). Avant de créer une VM imbriquée, vous devez créer une VM L1 pour laquelle la virtualisation imbriquée est activée. Pour obtenir une description des VM L1 et L2, consultez la page Présentation de la virtualisation imbriquée.

Après avoir créé une VM L1 sur laquelle la virtualisation imbriquée est activée, vous pouvez effectuer l'une des opérations suivantes :

  • Créer une VM L2 avec un accès réseau externe
  • Créer une VM L2 avec une passerelle réseau privée vers la VM L1
  • Créer une VM L2 avec un accès réseau externe à la VM L1

Avant de commencer

  • Si ce n'est pas déjà fait, configurez l'authentification. L'authentification est le processus permettant de valider votre identité pour accéder aux services et aux API Google Cloud. Pour exécuter du code ou des exemples depuis un environnement de développement local, vous pouvez vous authentifier auprès de Compute Engine comme suit :

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

    gcloud

    1. Install the Google Cloud CLI, then initialize it by running the following command:

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

      Pour utiliser les exemples d'API REST de cette page dans un environnement de développement local, vous devez utiliser les identifiants que vous fournissez à gcloud CLI.

        Install the Google Cloud CLI, then initialize it by running the following command:

        gcloud init

      Pour en savoir plus, consultez la section S'authentifier pour utiliser REST dans la documentation sur l'authentification Google Cloud.

Créer une VM L2 avec un accès réseau externe

Créez une VM L2 avec un accès réseau externe en suivant la procédure ci-dessous. Cette procédure utilise qemu-system-x86_64 pour démarrer la VM L2. Si vous utilisez une autre procédure pour créer une VM L2 et que vous rencontrez des problèmes, reproduisez le problème à l'aide de cette procédure avant de contacter l'assistance.

  1. Créez une VM L1 sur laquelle la virtualisation imbriquée est activée.

  2. Exécutez la commande gcloud compute ssh pour vous connecter à la VM :

    gcloud compute ssh VM_NAME
    

    Remplacez VM_NAME par le nom de la VM à laquelle se connecter.

  3. Installez la dernière version du package qemu-kvm :

    sudo apt update && sudo apt install qemu-kvm -y
    
  4. Téléchargez une image de l'OS compatible avec QEMU à utiliser pour la VM L2.

  5. Exécutez la commande suivante pour démarrer la VM L2. Lorsque vous y êtes invité, connectez-vous avec les identifiants user: root et password: root.

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

    Remplacez IMAGE_NAME par le nom de l'image d'OS compatible avec QEMU à utiliser pour la VM L2.

  6. Vérifiez que votre VM L2 dispose d'un accès externe :

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

Créer une VM L2 avec une passerelle réseau privée vers la VM L1

Créez une VM L2 avec un pont réseau privé vers la VM L1 créée précédemment en suivant la procédure ci-dessous. Pour en savoir plus sur la modification de l'unité de transmission maximale (MTU) par défaut de votre réseau VPC, consultez la présentation de l'unité de transmission maximale.

  1. Créez une VM L1 sur laquelle la virtualisation imbriquée est activée.

  2. Exécutez la commande gcloud compute ssh pour vous connecter à la VM :

    gcloud compute ssh VM_NAME
    

    Remplacez VM_NAME par le nom de la VM à laquelle se connecter.

  3. Installez les packages nécessaires à la création de la passerelle privée :

    sudo apt update && sudo apt install uml-utilities qemu-kvm bridge-utils virtinst libvirt-daemon-system libvirt-clients -y
    
  4. Démarrez le réseau par défaut associé au package libvirt :

    sudo virsh net-start default
    
  5. Exécutez la commande suivante pour vérifier que vous disposez de la passerelle virbr0 :

    ip addr
    
  6. Le résultat ressemble à ce qui suit :

    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. Créez une interface tap pour passer de la VM L1 à la VM L2 :

    sudo tunctl -t tap0
    sudo ifconfig tap0 up
    
  8. Reliez l'interface tap à la passerelle privée :

    sudo brctl addif virbr0 tap0
    
  9. Exécutez la commande suivante pour vérifier la configuration du réseau de la passerelle :

    sudo brctl show
    
  10. Le résultat ressemble à ce qui suit :

    bridge name     bridge id               STP enabled     interfaces
    virbr0          8000.5254008ca6a1       yes             tap0
                                                            virbr0-nic
    
  11. Téléchargez une image de l'OS compatible avec QEMU à utiliser pour la VM L2.

  12. Exécutez la commande screen et appuyez sur Entrée lorsque l'invite de bienvenue s'affiche :

    screen
    
  13. Exécutez la commande suivante pour démarrer la VM L2. Lorsque vous y êtes invité, connectez-vous avec les identifiants user: root et password: root.

    sudo qemu-system-x86_64 -enable-kvm -hda IMAGE_NAME -m 512 -net nic -net tap,ifname=tap0,script=no -curses
    

    Remplacez IMAGE_NAME par le nom de l'image d'OS compatible avec QEMU à utiliser pour la VM L2.

  14. Sur la VM L2, exécutez ip addr show pour vérifier que la VM dispose d'une adresse dans l'espace virbr0, par exemple 192.168.122.89 :

    user@nested-vm:~$ ip addr
    
  15. Démarrez un serveur Web d'espace réservé sur le port 8000 :

    user@nested-vm:~$ python -m http.server
    
  16. Quittez la session screen en utilisant Ctrl+A, Ctrl+D.

  17. Vérifiez que votre VM L1 peut pinguer la VM L2. Pour cela, remplacez l'adresse IP suivante par l'adresse IP de la VM L2 :

    curl 192.168.122.89:8000
    
  18. Le résultat ressemble à ce qui suit :

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

Créer une VM L2 avec un accès réseau externe à la VM L1

Vous pouvez configurer une VM L2 avec une adresse IP d'alias afin que les VM extérieures à la VM L1 puissent y accéder. Procédez comme suit pour créer une VM L2 avec un accès réseau via une adresse IP d'alias extérieure à la VM L1 précédemment créée. Pour en savoir plus sur la création d'adresses IP d'alias, consultez la page Configurer des plages d'adresses IP d'alias.

La procédure suivante suppose que vous avez créé un sous-réseau appelé subnet1. Si vous avez déjà un sous-réseau portant un nom différent, remplacez subnet1 par le nom de votre sous-réseau ou créez un sous-réseau nommé subnet1.

  1. Créez une VM L1 en activant la virtualisation imbriquée, et veillez à inclure une plage d'adresses IP d'alias et la compatibilité avec le trafic 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
    

    Remplacez VM_NAME par le nom de la VM L1.

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

    Remplacez les éléments suivants :

    • PROJECT_ID : ID du projet

    • ZONE : zone dans laquelle créer la VM

    • VM_NAME : nom de la VM

  2. Exécutez la commande gcloud compute ssh pour vous connecter à la VM. Si vous rencontrez des difficultés pour vous connecter à la VM, essayez de la réinitialiser ou de modifier les règles de pare-feu.

    gcloud compute ssh VM_NAME
    

    Remplacez VM_NAME par le nom de la VM à laquelle se connecter.

  3. Mettez à jour la VM et installez les packages nécessaires :

    sudo apt update && sudo apt install uml-utilities qemu-kvm bridge-utils virtinst libvirt-daemon-system libvirt-clients -y
    
  4. Démarrez le réseau par défaut associé au package libvirt :

    sudo virsh net-start default
    
  5. Exécutez la commande suivante pour vérifier que vous disposez de la passerelle virbr0 :

    user@nested-vm:~$ ip addr
    
  6. Vérifiez que le résultat ressemble à ce qui suit :

    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. Créez une interface tap pour passer de la VM L1 à la VM L2 :

    sudo tunctl -t tap0
    sudo ifconfig tap0 up
    
  8. Reliez l'interface tap à la passerelle privée :

    sudo brctl addif virbr0 tap0
    
  9. Exécutez la commande suivante pour vérifier la configuration du réseau de la passerelle :

    sudo brctl show
    
  10. Vérifiez que le résultat ressemble à ce qui suit :

    bridge name     bridge id               STP enabled     interfaces
    virbr0          8000.5254008ca6a1       yes             tap0
                                                            virbr0-nic
    
  11. Téléchargez une image de l'OS compatible avec QEMU à utiliser pour la VM L2.

  12. Exécutez la commande screen et appuyez sur Entrée lorsque l'invite de bienvenue s'affiche :

    screen
    
  13. Exécutez la commande suivante pour démarrer la VM imbriquée. Lorsque vous y êtes invité, connectez-vous avec les identifiants user: root et password: root.

    sudo qemu-system-x86_64 -enable-kvm -hda IMAGE_NAME -m 512 -net nic -net tap,ifname=tap0,script=no -curses
    

    Remplacez IMAGE_NAME par le nom de l'image d'OS compatible avec QEMU à utiliser pour la VM L2.

  14. Sur la VM L2, exécutez ip addr pour vérifier que la VM L2 dispose d'une adresse dans l'espace virbr0, telle que 192.168.122.89 :

    user@nested-vm:~$ ip addr
    
  15. Démarrez un serveur Web d'espace réservé sur le port 8000 :

    user@nested-vm:~$ python -m http.server
    
  16. Quittez la session screen en utilisant Ctrl+A, Ctrl+D.

  17. Vérifiez que votre VM L1 peut pinguer la VM L2. Pour cela, remplacez l'adresse IP ci-dessous par l'adresse IP de la VM L2 :

    curl 192.168.122.89:8000
    
  18. Vérifiez que la réponse de la VM L2 est semblable à celle-ci :

    <!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. Sur la VM L1, configurez iptables pour autoriser le transfert depuis la VM L1 vers la VM L2. Pour l'image de l'OS L2 utilisée dans ces instructions, vous devez vider les tables IP :

    sudo iptables -F
    
  20. Déterminez l'adresse IP d'alias de la VM L1 :

    ip route show table local
    
  21. Vérifiez que le résultat ressemble à ce qui suit : Dans cet exemple, deux adresses IP sont associées à l'appareil Ethernet eth0 de la VM L2. La première, 10.128.0.2, est l'adresse IP principale de la VM L2, qui est renvoyée par sudo ifconfig -a. La deuxième, 10.128.0.13, est l'adresse IP d'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. Exécutez les commandes suivantes pour transférer le trafic de l'exemple d'adresse IP d'alias 10.128.0.13 vers l'exemple d'adresse IP 192.168.122.89 pour 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
    

    Pour en savoir plus sur la résolution des problèmes liés aux tables IP (iptables), consultez la section Les règles iptables ne transfèrent pas le trafic.

  23. Vérifiez l'accès à la VM L2 depuis l'extérieur de la VM L1 en vous connectant à une autre VM située sur le même réseau que la VM L1 et en envoyant une requête curl à l'adresse IP d'alias. Pour cela, remplacez l'adresse IP ci-dessous par l'adresse IP d'alias de la VM L2 :

    user@another-vm:~$ curl 10.128.0.13:8000
    
  24. Vérifiez que la réponse curl ressemble à ce qui suit :

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

Étapes suivantes