Trouble Shooting

Cockpit에서 VM 간 네트워크 통신 문제 해결하기

Somaz 2025. 7. 28. 05:59
728x90
반응형

Overview

Cockpit을 사용해서 가상머신(VM)을 관리하다 보면 종종 네트워크 통신 문제를 마주하게 된다. 특히 "Direct" 네트워크 모드로 VM들을 구성했을 때, 외부 통신은 되지만 VM 간 내부 통신이 안 되는 문제가 자주 발생한다.

 

이 글에서는 실제 겪었던 네트워킹 문제를 단계별로 해결해가는 과정을 공유하며, Kubernetes 클러스터 구성을 위한 네트워크 설계 방법까지 다뤄보겠다.

 

 

 

문제 상황

  • VM들이 같은 물리 NIC에 macvtap으로 연결
  • VM 간 ping 통신 실패 (100% packet loss)
  • 외부 통신은 정상 작동
  • Kubernetes 클러스터 구성 시 Pod 간 통신 문제 예상

 

 

환경 정보

  • 물리 서버: Ubuntu 22.04 LTS
  • 가상화: KVM/QEMU with libvirt
  • 관리 도구: Cockpit Web Console
  • 목표: Kubernetes 클러스터 구성

 

 

 

 

 

 

 

 

 


 

 

1. 문제 진단: macvtap의 근본적 제약

 

현재 네트워크 구성 확인

먼저 물리 서버와 VM들의 네트워크 상태를 확인했다.

# 물리 서버 (ubuntu)
root@ubuntu:~# ip a
3: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 90:5a:08:74:aa:21 brd ff:ff:ff:ff:ff:ff
    inet 10.10.10.15/24 brd 10.10.10.255 scope global eno1
8: macvtap0@eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP default qlen 500
16: macvtap3@eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP default qlen 500

 

 

# VM1 (k8s-control-01)
root@k8s-control-01:~# ip a
3: enp7s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    inet 10.10.10.17/24 brd 10.10.10.255 scope global enp7s0

# VM2 (k8s-compute-01)  
root@k8s-compute-01:~# ip a
3: enp7s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    inet 10.10.10.18/24 brd 10.10.10.255 scope global enp7s0

 

 

 

 

통신 테스트 결과

# VM 간 직접 통신 (실패)
root@k8s-compute-01:~# ping 10.10.10.17
PING 10.10.10.17 (10.10.10.17) 56(84) bytes of data.
^C
--- 10.10.10.17 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

# 외부 통신 (성공)
root@k8s-compute-01:~# 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=116 time=8.42 ms
 
 
 

macvtap 제약사항 이해

 

 

macvtap의 기본 동작 원리

  • 같은 물리 NIC에 연결된 macvtap 인터페이스들 간에는 직접 통신이 차단됨
  • 보안상의 이유로 VM 간 격리를 위해 설계된 동작
  • 외부 네트워크와는 정상 통신 가능

 

이것이 바로 우리가 겪은 문제의 핵심 원인이었다.

 

 

 

 

 

 

 

2. 하드웨어 기반 해결책 검토

 

추가 NIC 활용 방안

두 번째 네트워크 인터페이스(eno2)를 활성화해서 VM들을 분산 배치하는 방법을 시도했다.

 

 

netplan 설정

network:
  ethernets:
    eno1:
      dhcp4: no
      addresses: [10.10.10.15/24]
      nameservers:
        addresses: [8.8.8.8]
      routes:
        - to: default
          via: 10.10.10.1
          metric: 100
    eno2:
      dhcp4: no
      addresses: [10.10.10.23/24]
      nameservers:
        addresses: [8.8.8.8]
      routes:
        - to: default
          via: 10.10.10.1
          metric: 200

 

 

적용 및 결과 확인

sudo netplan apply
...


# 결과 확인
root@ubuntu:~# ip a
2: eno2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    inet 10.10.10.23/24 brd 10.10.10.255 scope global eno2
3: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000  
    inet 10.10.10.15/24 brd 10.10.10.255 scope global eno1

 

 

 

계획된 VM 배치

  • VM1: macvtap@eno1 (10.10.10.17)
  • VM2: macvtap@eno2 (10.10.10.18)

 

하지만 이 방법은 VM이 2대일때까지만 유효하다.

 

 

 

 

네트워크 드라이버 분석

문제의 근본 원인을 찾기 위해 다른 환경과 비교 분석을 진행했다.

# 통신이 잘 되는 환경 (cockpit 머신)
root@cockpit:~# sudo ethtool -i enp4s0
driver: igc
version: 6.8.0-57-generic
firmware-version: 1057:8754

# 문제가 있는 환경 (ubuntu 머신)  
root@ubuntu:~# sudo ethtool -i eno1
driver: igb
version: 5.15.0-144-generic
firmware-version: 3.30, 0x8000079c

root@ubuntu:~# sudo ethtool -i eno2
driver: atlantic  
version: 5.15.0-144-generic
firmware-version: 1.3.30

 

 

 

발견된 차이점

  • igc 드라이버 (최신): macvtap hairpin 모드 지원으로 VM 간 통신 가능
  • igb/atlantic 드라이버 (구형): hairpin 모드 제한으로 VM 간 통신 불가
  • 커널 버전: 6.8.0 vs 5.15.0의 차이

 

 

 

 

 

 

3. 브리지 네트워크 구성으로 근본 해결

 

netplan 브리지 설정

하드웨어 제약을 소프트웨어로 우회하기 위해 브리지 네트워크를 구성했다.

# This is the network config written by 'subiquity'
network:
  ethernets:
    eno1:
      dhcp4: no
    eno2:
      dhcp4: no
  bridges:
    br0:
      interfaces: [eno1, eno2]
      addresses: [10.10.10.15/24]
      routes:
        - to: default
          via: 10.10.10.1
      nameservers:
        addresses: [8.8.8.8]

 

 

# 설정 적용
sudo netplan apply

# 브리지 상태 확인
brctl show
bridge name     bridge id               STP enabled     interfaces
br0             8000.905a0874aa21       no              eno1
                                                        eno2

 

 

 

libvirt 브리지 네트워크 생성

 

방법 1: XML 파일로 네트워크 정의

# 브리지 네트워크 정의 파일 생성
cat > /tmp/br0-network.xml << EOF
<network>
  <name>br0-network</name>
  <forward mode='bridge'/>
  <bridge name='br0'/>
</network>
EOF

# 네트워크 생성 및 시작
sudo virsh net-define /tmp/br0-network.xml
sudo virsh net-start br0-network
sudo virsh net-autostart br0-network

# 확인
sudo virsh net-list --all
 Name         State    Autostart   Persistent
----------------------------------------------
 br0-network  active   yes         yes
 default      active   yes         yes

 

 

 

 

 

 

 

Cockpit에서 VM 네트워크 변경

  1. 가상화네트워크에서 새로운 "br0-network" 확인
  2. 각 VM의 네트워크 설정을 "Direct" → "br0-network"로 변경
  3. VM 재시작

또는 "Bridge to LAN" 옵션 사용

  • Cockpit → 네트워크 생성Forward 모드: "Bridge to LAN"
  • 브리지: "br0" 선택

 

 

 

4. 검증 및 테스트

 

VM 간 통신 확인

# VM1에서 VM2로 ping
root@k8s-control-01:~# ping 10.10.10.18
PING 10.10.10.18 (10.10.10.18) 56(84) bytes of data.
64 bytes from 10.10.10.18: icmp_seq=1 ttl=64 time=0.231 ms
64 bytes from 10.10.10.18: icmp_seq=2 ttl=64 time=0.187 ms

# VM2에서 VM1로 ping  
root@k8s-compute-01:~# ping 10.10.10.17
PING 10.10.10.17 (10.10.10.17) 56(84) bytes of data.
64 bytes from 10.10.10.17: icmp_seq=1 ttl=64 time=0.156 ms
64 bytes from 10.10.10.17: icmp_seq=2 ttl=64 time=0.201 ms

 


네트워크 성능 측정

bash# iperf3를 사용한 대역폭 테스트
# VM1에서 서버 실행
iperf3 -s

# VM2에서 클라이언트 실행  
iperf3 -c 10.10.10.17 -t 30

 

 

 

 

 

 

트러블슈팅 팁

 

 

1. 브리지 생성 후 네트워크 끊김

# 해결: netplan 설정에서 IP를 브리지로 이동
# eno1, eno2에서 IP 제거하고 br0에만 설정

 

 

 

2. VM에서 DNS 해결 안됨

# 해결: nameservers 설정 확인
sudo systemctl restart systemd-resolved

 

 

 

3. 브리지 성능 저하

# STP 비활성화 확인
sudo brctl stp br0 off
echo 0 > /sys/class/net/br0/bridge/forward_delay

 

 

 

 

모니터링 명령어

# 브리지 상태 모니터링
watch -n1 "brctl showmacs br0"

# 네트워크 트래픽 모니터링
iftop -i br0
vnstat -i br0

 

 

 

 

 

 

 

 

마무리

이번 트러블슈팅을 통해 Cockpit에서 VM 네트워킹 문제의 근본 원인과 해결책을 찾을 수 있었다.

 

 

핵심 교훈

  1. macvtap 제약사항 이해: 같은 물리 NIC에 연결된 VM 간 통신은 기본적으로 차단됨
  2. 하드웨어 의존성: 네트워크 드라이버(igc vs igb/atlantic)에 따라 동작이 달라질 수 있음
  3. 브리지: Linux 브리지 네트워크는 하드웨어 제약을 소프트웨어로 우회가능
  4. 단순함의 가치: 복잡한 내부/외부 네트워크 분리보다 br0 기반 단일 네트워크가 더 효율적
  5. 확장성 고려: 초기부터 브리지 구성으로 VM 확장에 대비

 

 

 

최종 권장사항

 

Cockpit VM 네트워킹을 위한 베스트 프랙티스

  1. 소규모 환경 (VM 2개)
    • 서로 다른 물리 NIC에 VM 분산 배치 가능
    • 하지만 확장성을 위해 브리지 권장
  2. 중대규모 환경 (VM 3개 이상)
    • 브리지 네트워크 구성 필수
    • "Bridge to LAN" 모드 사용
  3. Kubernetes 클러스터
    • br0 기반 단일 네트워크 구성 권장
    • MetalLB와 DNS 연동으로 완전한 서비스 제공
  4. 프로덕션 환경
    • 네트워크 이중화를 위한 본딩 구성
    • 모니터링 및 로깅 시스템 구축
    • 백업 및 재해복구 계획 수립

 

 

이러한 접근 방식으로 안정적이고 확장 가능한 가상화 환경을 구축할 수 있으며, 특히 Kubernetes와 같은 컨테이너 오케스트레이션 플랫폼에서도 원활한 네트워킹을 보장할 수 있다.

 

 

 

 

 

 

 


Reference

공식 문서

기술 설명

Kubernetes 관련

트러블슈팅 도구

커뮤니티

728x90
반응형