중첩된 VM 만들기


기본적으로 중첩된 가상화가 허용되므로 다른 사용자가 중첩된 가상화의 제약조건을 수정하지 않는 한 조직, 폴더 또는 프로젝트에서 중첩된 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

    1. Google Cloud CLI를 설치한 후 다음 명령어를 실행하여 초기화합니다.

      gcloud init
    2. 기본 리전 및 영역을 설정합니다.

    REST

    로컬 개발 환경에서 이 페이지의 REST API 샘플을 사용하려면 gcloud CLI에 제공한 사용자 인증 정보를 사용합니다.

      Google Cloud CLI를 설치한 후 다음 명령어를 실행하여 초기화합니다.

      gcloud init

외부 네트워크 액세스로 L2 VM 만들기

다음 절차를 수행하여 외부 네트워크 액세스 권한이 있는 L2 VM을 만듭니다. 이 절차에서는 qemu-system-x86_64를 사용하여 L2 VM을 시작합니다. 다른 절차를 사용하여 L2 VM을 만드는 데 문제가 있는 경우 지원팀에 문의하기 전에 이 절차를 수행하여 문제를 재현합니다.

  1. 중첩된 가상화가 사용 설정된 L1 VM을 만듭니다.

  2. gcloud compute ssh 명령어를 사용하여 VM에 연결합니다.

    gcloud compute ssh VM_NAME
    

    VM_NAME을 연결할 VM의 이름으로 바꿉니다.

  3. 최신 qemu-kvm 패키지를 설치합니다.

    sudo apt update && sudo apt install qemu-kvm -y
    
  4. L2 VM에 사용할 QEMU 호환 OS 이미지를 다운로드합니다.

  5. 다음 명령어를 사용하여 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 이미지의 이름으로 바꿉니다.

  6. L2 VM에 외부 액세스가 포함되는지 테스트합니다.

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

L1 VM에 대한 비공개 네트워크 브리지가 있는 L2 VM 만들기

다음 절차를 수행하여 이전에 만든 L1 VM에 대한 비공개 네트워크 브리지가 있는 L2 VM을 만듭니다. VPC 네트워크의 기본 최대 전송 단위(MTU)를 변경하는 방법은 최대 전송 단위 개요를 참조하세요.

  1. 중첩된 가상화가 사용 설정된 L1 VM을 만듭니다.

  2. gcloud compute ssh 명령어를 사용하여 VM에 연결합니다.

    gcloud compute ssh VM_NAME
    

    VM_NAME을 연결할 VM의 이름으로 바꿉니다.

  3. 비공개 브리지를 만드는 데 필요한 패키지를 설치합니다.

    sudo apt update && sudo apt install uml-utilities qemu-kvm bridge-utils virtinst libvirt-daemon-system libvirt-clients -y
    
  4. libvirt 패키지에 제공되는 기본 네트워크를 시작합니다.

    sudo virsh net-start default
    
  5. 다음 명령어를 실행하여 virbr0 브리지가 있는지 확인합니다.

    ip addr
    
  6. 출력은 다음과 비슷합니다.

    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. tap 인터페이스를 만들어 L1 VM에서 L2 VM으로 이동합니다.

    sudo tunctl -t tap0
    sudo ifconfig tap0 up
    
  8. tap 인터페이스를 비공개 브리지에 결합합니다.

    sudo brctl addif virbr0 tap0
    
  9. 다음 명령어를 실행하여 브리지 네트워크의 설정을 확인합니다.

    sudo brctl show
    
  10. 출력은 다음과 비슷합니다.

    bridge name     bridge id               STP enabled     interfaces
    virbr0          8000.5254008ca6a1       yes             tap0
                                                            virbr0-nic
    
  11. L2 VM에 사용할 QEMU 호환 OS 이미지를 다운로드합니다.

  12. screen을 실행하고 환영 메시지가 표시되면 Enter 키를 누릅니다.

    screen
    
  13. 다음 명령어를 사용하여 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 이미지의 이름으로 바꿉니다.

  14. L2 VM에서 ip addr show를 실행하여 VM 주소가 virbr0 공간에 있는지 확인합니다(예: 192.168.122.89).

    user@nested-vm:~$ ip addr
    
  15. 포트 8000에서 자리표시자 웹 서버를 시작합니다.

    user@nested-vm:~$ python -m http.server
    
  16. Ctrl+A, Ctrl+D를 사용하여 screen 세션에서 분리합니다.

  17. 다음 IP 주소를 L2 VM의 IP 주소로 바꿔 L1 VM이 L2 VM을 핑할 수 있는지 테스트합니다.

    curl 192.168.122.89:8000
    
  18. 출력은 다음과 비슷합니다.

    <!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이라는 새 서브넷을 만듭니다.

  1. 중첩된 가상화가 사용 설정된 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: 프로젝트 ID

    • ZONE: VM을 만들 영역

    • VM_NAME: VM의 이름입니다.

  2. gcloud compute ssh 명령어를 사용하여 VM에 연결합니다. VM에 연결하는 데 문제가 발생하면 VM을 재설정하거나 방화벽 규칙을 수정해 보세요.

    gcloud compute ssh VM_NAME
    

    VM_NAME을 연결할 VM의 이름으로 바꿉니다.

  3. VM을 업데이트하고 필요한 패키지를 설치합니다.

    sudo apt update && sudo apt install uml-utilities qemu-kvm bridge-utils virtinst libvirt-daemon-system libvirt-clients -y
    
  4. libvirt 패키지에 제공되는 기본 네트워크를 시작합니다.

    sudo virsh net-start default
    
  5. 다음 명령어를 실행하여 virbr0 브리지가 있는지 확인합니다.

    user@nested-vm:~$ ip addr
    
  6. 다음과 비슷한 출력이 표시되는지 확인합니다.

    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. tap 인터페이스를 만들어 L1 VM에서 L2 VM으로 이동합니다.

    sudo tunctl -t tap0
    sudo ifconfig tap0 up
    
  8. tap 인터페이스를 비공개 브리지에 결합합니다.

    sudo brctl addif virbr0 tap0
    
  9. 다음 명령어를 실행하여 브리지 네트워크의 설정을 확인합니다.

    sudo brctl show
    
  10. 다음과 비슷한 출력이 표시되는지 확인합니다.

    bridge name     bridge id               STP enabled     interfaces
    virbr0          8000.5254008ca6a1       yes             tap0
                                                            virbr0-nic
    
  11. L2 VM에 사용할 QEMU 호환 OS 이미지를 다운로드합니다.

  12. screen을 실행하고 환영 메시지가 표시되면 Enter 키를 누릅니다.

    screen
    
  13. 중첩된 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 이미지의 이름으로 바꿉니다.

  14. L2 VM에서 ip addr를 실행하여 L2 VM 주소가 virbr0 공간에 있는지 확인합니다(예: 192.168.122.89).

    user@nested-vm:~$ ip addr
    
  15. 포트 8000에서 자리표시자 웹 서버를 시작합니다.

    user@nested-vm:~$ python -m http.server
    
  16. Ctrl+A, Ctrl+D를 사용하여 screen 세션에서 분리합니다.

  17. 다음 IP 주소를 L2 VM의 IP 주소로 바꿔 L1 VM이 L2 VM을 핑할 수 있는지 테스트합니다.

    curl 192.168.122.89:8000
    
  18. 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>
    
  19. L1 VM에서 iptables를 설정하여 L1 VM에서 L2 VM으로의 전달을 허용합니다. 이 안내에 사용된 L2 OS 이미지의 경우 IP 테이블을 플러시해야 합니다.

    sudo iptables -F
    
  20. L1 VM의 별칭 IP를 확인합니다.

    ip route show table local
    
  21. 출력이 다음과 비슷하게 표시되는지 확인합니다. 이 예시의 경우 L2 VM의 eth0 이더넷 기기와 연결된 IP 주소가 2개 있습니다. 첫 번째 IP 주소인 10.128.0.2sudo ifconfig -a에서 반환하는 L2 VM의 기본 IP 주소입니다. 두 번째 IP 주소인 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
    
  22. 다음 명령어를 실행하여 트래픽을 10.128.0.13 예시 별칭 IP에서 L2 VM의 192.168.122.89 예시 IP로 전달합니다.

    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를 참조하세요.

  23. L1 VM과 동일한 네트워크에 있는 다른 VM에 로그인하고 IP 주소를 아래의 L2 VM의 별칭 IP로 바꿔 별칭 IP에 대한 curl 요청을 수행하여 L1 VM 외부에서 L2 VM 액세스를 확인합니다.

    user@another-vm:~$ curl 10.128.0.13:8000
    
  24. 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>
    

다음 단계