Byeo

QEMU VM의 네트워크를 인터넷과 연결하기 본문

프로그래밍 (Programming)/컴퓨터 네트워크 - 학부 외

QEMU VM의 네트워크를 인터넷과 연결하기

BKlee 2024. 3. 16. 23:48
반응형

QEMU를 통해 생성한 VM이 외부와 통신이 가능하도록 설정해 봅니다.

 

1. QEMU script 작성

qemu를 실행하는 스크립트를 다음과 같이 작성합니다.

#!/bin/bash

qemu-system-x86_64 \
        -m 2G \
        -smp cores=4 \
        -kernel ./arch/x86/boot/bzImage \
        -drive file=image/ubuntu-from-debootstrap.img,format=raw \
        -append "root=/dev/sda rw console=ttyS0" \
        -netdev tap,id=byeonet0,ifname=byeotap0 \
        -device e1000,netdev=byeonet0,mac=fa:16:3e:00:11:22 \
        -enable-kvm \
        -nographic \
        -pidfile vm.pid \
        2>&1 | tee vm.log

 

여기서 byeotap0이 host가 보게 될  device name입니다.

 

위와 같이 실행 명령어를 작성하고 qemu를 실행시키면 VM과 host의 ip link에 다음과 같은 device가 추가됩니다.

 

VM (bklee-qemu)

root@bklee-qemu:~# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp0s3: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 1000
    link/ether fa:16:3e:00:11:22 brd ff:ff:ff:ff:ff:ff
3: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/sit 0.0.0.0 brd 0.0.0.0

 

Host (bklee)

root@bklee:/home/bklee# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: wlo1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DORMANT group default qlen 1000
    link/ether c0:b8:83:ee:37:1b brd ff:ff:ff:ff:ff:ff
    altname wlp0s20f3
3: byeotap0: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel state DOWN mode DEFAULT group default qlen 1000
    link/ether 16:df:d3:0d:3d:d6 brd ff:ff:ff:ff:ff:ff

 

 

 

2. Device setup (VM <-> Host 통신)

VM (bklee-qemu)의 NIC enp0s3에 몇 가지 설정을 부여합니다. 

ip address add 10.0.0.20/24 dev enp0s3  # enp0s3에 10.0.0.20이라는 주소를 부여합니다.
ip link set dev enp0s3 up # enp0s3 장비를 활성화 합니다.
ip route add default via 10.0.0.1 dev enp0s3 # VM에서 내보낼 packet들의 기본 routing은 enp0s3로 나가도록 합니다.

 

영구 적용은 VM 내에서 /etc/netplan 내에 파일을 하나 생성하여 편집하면 됩니다. 

  • vi /etc/netplan/01-netcfg.yaml
  • sudo netplan apply
network:
  version: 2
  renderer: networkd
  ethernets:
    enp0s3:
      dhcp4: no
      addresses:
        - 10.0.0.20/24
      gateway4: 10.0.0.1
      nameservers:
        addresses: [8.8.8.8]

 

 

Host (bklee)의 NIC에도 다음과 같은 설정을 해줍니다.

ip route add 10.0.0.20 dev byeotap0 # 10.0.0.20으로 향하는 packet은 byeotap0으로 집어넣습니다.
ip link set dev byeotap0 up

 

 

위와 같은 설정을 끝마치면 VM (bklee-qemu, 10.0.0.20) Host (bklee, 192.168.45.201)이 통신이 가능해집니다. 

root@bklee-qemu:~# ping 192.168.45.201
PING 192.168.45.201 (192.168.45.201) 56(84) bytes of data.
64 bytes from 192.168.45.201: icmp_seq=1 ttl=64 time=0.260 ms
64 bytes from 192.168.45.201: icmp_seq=2 ttl=64 time=0.865 ms
64 bytes from 192.168.45.201: icmp_seq=3 ttl=64 time=0.826 ms

 

아직 구조가 올바른 느낌은 아니긴 한데요 (Host의 다른 net device IP에 ping을 때리는 느낌), 어쨌든 VM과 Host가 packet을 주고받을 수 있다는 것은 확인했습니다.

 반대로 host에서 10.0.0.20으로 ping을 쏘면 VM이 응답을 주게 됩니다. Host에서 VM으로 ssh 접속도 가능합니다.

 

 하지만 아직 문제가 있습니다. VM이 인터넷에 접속할 수 있도록 만들고 싶은데, 아직 외부로는 나갈 수 없어요.

 

3. Bridging (VM <-> Internet 통신)

이제 byeotap0에서 나온 packet을 진짜 wlo1 (노트북의 와이파이 인터페이스)으로 나갈 수 있도록 연결해 봅시다.

 

▶ 추후에 VM의 수가 늘어나는 등의 확장성을 위해서 bridge를 통해 연결하였습니다. 딱 하나만 운영한다면 굳이 bridge를 통해 연결할 필요는 없을 듯합니다.

openvswitch도 좋은 사용 방안이긴 하나, linux bridge를 연습 겸 사용해보려고 합니다.

 

Host에 linux bridge util 설치

 apt install bridge-utils

 

Bridge 생성 및 연결하기

# bridge 생성
brctl addbr br0

# 생성한 br0 bridge에 byeotap0 인터페이스 연결
brctl addif br0 byeotap0

# bridge br0 활성화
ip link set dev br0 up

# br0에 ip 주소 부여
ip address add 10.0.0.1/24 dev br0

# VM source IP (10.0.0.20)를 Host source IP (192.168.45.201, Host IP)로 NAT 허용
iptables -t nat -A POSTROUTING -j MASQUERADE

 

forward 설정 (영구적용은 /etc/sysctl.conf 편집)

 sysctl -w net.ipv4.ip_forward=1

 

VM에서 ping 8.8.8.8 확인

root@bklee-qemu:~# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=114 time=35.6 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=114 time=38.3 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=114 time=38.2 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=114 time=38.3 ms
^C
--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3006ms
rtt min/avg/max/mdev = 35.560/37.581/38.264/1.167 ms

 

 이제 VM도 인터넷과 통신이 가능합니다~ 그래서 패키지 설치 같은 것도 가능해졌네요!

 

인스턴스가 여러 개라면 br0에 NAT와 dhcp를 섞어서 설정을 조금 더  자동화하는 방법이 가능할 텐데, 나중에 기회가 되면 다루겠습니다~

반응형
Comments