QEMU 내에서 dnsmasq를 실행하여 다른 VM에 netboot 서비스를 제공하는 방법

QEMU 내에서 dnsmasq를 실행하여 다른 VM에 netboot 서비스를 제공하는 방법

편집: WIP: 아래 설명된 실패의 핵심 이유는 호스트 TAP 인터페이스를 적시에 불러오지 않았기 때문입니다. QEMU가 탭 장치 생성을 처리하도록 허용하면 모든 것이 예상대로 작동합니다. 오류를 더 자세히 조사하고 문제가 발생하면 문제에 대한 더 명확한 설명을 제공하겠습니다. 팁을 주신 @anx에게 감사드립니다!

목표: dnsmasq호스트에서 실행 중인 다른 QEMU VM에서 네트워크 부팅을 서비스하는 호스트 QEMU VM 내부를 실행합니다.

dnsmasq VM이 하나의 NIC를 업스트림 WAN 인터페이스로 사용하고, 하나의 NIC를 업스트림 DHCP 서버로 사용하고, 다른 인터페이스는 사설 LAN 인터페이스로 사용하여 게이트웨이처럼 작동하도록 하고 싶습니다. 이 인터페이스에 다른 VM이 "연결"되고 다음에서 넷부팅됩니다. 이 개인 LAN 인터페이스를 수신하는 dnsmasq입니다.

먼저 VM이 서로 통신할 수 있도록 호스트에 나만의 브리지를 만듭니다.

ip link add name vivianbr0 type bridge
ip link set vivianbr0 up

VM이 호스트 브리지를 통해 서로 통신하려면 두 개의 탭 장치가 필요합니다. 하나는 게이트웨이 VM의 개인 LAN 인터페이스용이고 다른 하나는 개인 VM 단일 네트워크 인터페이스용입니다.

ip tuntap add mode tap tap0 user cturner
ip tuntap add mode tap tap1 user cturner
ip link set tap0 up
ip link set tap1 up
ip link set tap0 master vivianbr0
ip link set tap1 master vivianbr0

게이트웨이 VM의 경우 테스트 목적으로 Arch Linux ISO를 사용하고 있으며 VM은 두 개의 NIC로 부팅됩니다.

 qemu-system-x86_64 \
    -drive file=arch-disk.qcow2,if=none,id=nvm \
    -device nvme,serial=deadbeef,drive=nvm \
    -cdrom archlinux-2021.09.01-x86_64.iso \
    -boot d \
    -device virtio-net-pci,romfile=,netdev=net0,mac="DE:AD:BE:EF:00:11" \
    -device virtio-net-pci,romfile=,netdev=net1,mac="DE:AD:BE:EF:00:12" \
    `# Simulate the plugged in "upstream" cable with user-mode networking` \
    -netdev user,id=net0,hostfwd=tcp::60022-:22,hostfwd=tcp::8080-:80,hostfwd=tcp::8081-:8000,hostfwd=tcp::2375-:2375 \
    `# And now the unplugged one with, with TAP networks` \
    -netdev tap,id=net1,ifname=tap0,script=no,downscript=no \
-net bridge,br=vivianbr0 \
    -m 4G \
    -enable-kvm

이 머신이 부팅되면 브리지 구성에 다음이 표시됩니다.

brctl show vivianbr0 

bridge name     bridge id               STP enabled     interfaces
vivianbr0               8000.46954a1ad851       no              tap0
                            tap1
                            tap2

tap2QEMU에서 만든 것으로 추정됩니다 .

이 VM 내부에는 두 개의 iface가 있습니다. ens4MAC DE:AD:BE:EF:00:11 및 ens5MAC DE:AD:BE:EF:00:12를 사용합니다. 이 VM 내에서 시작합니다 dnsmasq.

ip addr add 10.42.0.1/24 dev ens5
dnsmasq -d --dhcp-range=10.42.0.10,10.42.0.100 --dhcp-script=/bin/echo --enable-tftp=ens5 --interface=ens5

오류 없이 시작됩니다.

이제 다음과 같이 호스트에서 시작된 다른 VM을 네트워크 부팅하려고 합니다.

qemu-system-x86_64 \
-machine pc-q35-6.0,accel=kvm \
-m 1024 -smp 2,sockets=2,cores=1,threads=1 \
-netdev tap,id=net0,ifname=tap1,script=no,downscript=no \
-device virtio-net-pci,netdev=net0,bootindex=1,mac=DE:AD:BE:EF:00:13 \
-net bridge,br=vivianbr0 \
-enable-kvm \
-vga virtio

그러나 부팅에 실패합니다. vivianbr0사용 을 모니터링 tcpdump하고 DHCP 요청을 볼 수 있지만 응답이 없으며 첫 번째 VM 내에서 실행되는 dnsmasq에 아무것도 도달하지 않습니다.

tcpdump -i vivianbr0 -nN
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on vivianbr0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:21:39.585229 IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from de:ad:be:ef:00:13, length 397
12:21:40.587741 IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from de:ad:be:ef:00:13, length 397
12:21:40.700038 IP6 fe80::6ce2:2aff:fe94:ba48.5353 > ff02::fb.5353: 0 [7q] PTR (QM)? _nfs._tcp.local. PTR (QM)? _ftp._tcp.local. PTR (QM)? _webdav._tcp.local. PTR (QM)? _webdavs._tcp.local. PTR (QM)? _sftp-ssh._tcp.local. PTR (QM)? _smb._tcp.local. PTR (QM)? _afpovertcp._tcp.local. (118)
12:21:42.619968 IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from de:ad:be:ef:00:13, length 397
12:21:46.684448 IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from de:ad:be:ef:00:13, length 397
12:22:30.609555 IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from de:ad:be:ef:00:12, length 289
12:23:33.796148 IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from de:ad:be:ef:00:12, length 289
12:24:38.673364 IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from de:ad:be:ef:00:12, length 289

이상하게도 de:ad:be:ef:00:13(넷 부팅 VM MAC 주소) 에서 BOOTP 요청이 표시됩니다.그리고로부터 de:ad:be:ef:00:12(게이트웨이 VM의 개인 NIC), 이는 무언가 잘못 구성되었음을 나타냅니다.

이 작업을 어떻게 수행할 수 있나요?

답변1

두 손님의 단계는 괜찮습니다. 방금 설정을 복제했습니다.임대 주소까지. dnsmasq를 실행하는 하나의 VM에서 dhcp 클라이언트를 실행하는 하나의 VM으로 IP를 전달할 수 있습니다.

다음을 확인하세요:

  • 연결되지 않은 탭 장치를 불러올 수 없습니다
    • 호스트 출력의 DOWN상태 에서 볼 수 있습니다 ( 또는 라고 말해야 함 ). ip a lUNKNOWNUP
      • qemu가 탭 장치를 생성하도록 하면 해당 장치 qemu-bridge-helper가 나타납니다.
      • script=를 사용하는 경우 거기에 장치를 불러옵니다.
      • ip link set tapN up그렇지 않으면 vm start 이후에 어느 정도 시간이 걸립니다.
  • MAC 주소는 고유해야 합니다.
    • 손님의 ether주소 에 표시됩니다 .ip a l
    • 학습된(호스트가 아닌) Mac을 나열 brctl showmacs br0합니다 . 예를 들어0이 아닌 에이징 타이머가 있는 항목
  • iptables를 통해 패킷 삭제
    • 모듈이 로드되었는지 확인 /proc/sys/net/bridge/bridge-nf-call*하고br_netfilter
    • iptables -A FORWARD -j LOG --log-prefix "forward dropped"FORWARD 테이블의 삭제 전이나 DROP 정책 전과 같은 IPv4에 대한 로깅 규칙을 추가합니다.
    • 무시 /sys/class/net/br*/bridge/nf_call_*(왜 이런 일이 발생하는지 모르겠습니다.~할 수 있다필터링이 켜져 있으면 꺼짐)

테스트 중에 발견한 다른 주목할만한 점은 다음과 같습니다.

  • Qemu는 vnet_hdr내 탭 장치에 옵션을 추가했습니다. 이는 합리적으로 보이며 원하는 경우 qemu cmdline에서 비활성화할 수도 있습니다.
  • 때로는 다리에 대한 내 (스코프 링크) 경로가 누락되는 경우가 있습니다. 나는 아직 그런 일이 어떻게 일어날 수 있는지 결정하지 못했습니다.

탭 장치에 바인딩하여 테스트를 단순화하려는 시도에 대해..

dnsmasq는 QEMU VM 내에서 실행됩니다.

AFAIK 영구 탭 장치는 실제로 연결될 때까지 사용할 수 없습니다. 따라서 전체 설정 중 하나만 의미 있게 테스트할 수 있습니다.

  • 호스트에서 dnsmasq를 실행하시겠습니까?
    • 그런 다음 브리지 장치에 연결하세요.
  • 아니면 VM 내에서 dnsmasq를 실행하시겠습니까?
    • 그런 다음 해당 네트워크 인터페이스에 연결하십시오.내부에해당 VM

--인터페이스=tap0

힌트: --bind-interfaces다른 인터페이스의 트래픽을 단순히 삭제하는 것에서 실제로 바인딩을 시도하는 것으로 전환하여 dnsmasq에 지시하여 사용할 수 없는 설정으로 시작할 때 장황하게 종료하도록 지시하는 데 사용합니다.

관련 정보