Kubernetes Tools/Kubevirt

[KubeVirt Ep.8] 🚀 Multus CNI 연동하기 | VM에 다중 네트워크 붙이기

ygtoken 2025. 3. 21. 14:57
728x90

이 글에서는 KubeVirt 환경에서 Multus CNI를 활용하여 가상 머신에 여러 개의 네트워크 인터페이스를 연결하는 방법에 대해 알아보겠습니다. Docker Desktop 환경에서 실습하며, VM에 별도의 NIC를 추가하고 고정 IP를 설정하는 방법부터 실무에서 Multus를 활용할 때 고려해야 할 사항까지 다룹니다.


📌 Multus CNI 개념 이해하기

✅ Multus CNI란?

Multus CNI는 Pod 또는 VM에 여러 개의 네트워크 인터페이스를 연결할 수 있게 해주는 메타 플러그인입니다. 기본적으로 Kubernetes는 Pod당 하나의 네트워크 인터페이스만 지원하지만, Multus를 사용하면 여러 개의 네트워크에 동시에 연결할 수 있습니다.

 

▶️ Multus CNI의 주요 특징:

  • 여러 CNI 플러그인의 동시 사용 지원
  • 메인 네트워크(기본 Pod 네트워크) 외에 추가 네트워크 구성 가능
  • NetworkAttachmentDefinition CRD를 통한 네트워크 정의
  • SR-IOV, Macvlan, Bridge 등 다양한 CNI 플러그인과의 통합

✅ KubeVirt에서 Multus가 필요한 이유

KubeVirt에서 Multus를 사용하는 이유는 다음과 같습니다:

  1. 격리된 네트워크 구성: 서로 다른 네트워크 세그먼트에 VM을 연결해야 하는 경우
  2. 성능 최적화: SR-IOV와 같은 고성능 네트워킹이 필요한 경우
  3. 레거시 시스템 마이그레이션: 복잡한 네트워크 구성을 가진 기존 VM 마이그레이션
  4. 네트워크 분리: 관리 네트워크와 서비스 네트워크 분리

 

Multus CNI와 KubeVirt VM 다중 네트워크 구조


📌 Multus CNI 설치하기

Docker Desktop 환경에서 Multus CNI를 설치하고 구성해 보겠습니다.

✅ Multus CNI 설치

# Multus CNI 설치
kubectl apply -f https://raw.githubusercontent.com/k8snetworkplumbingwg/multus-cni/master/deployments/multus-daemonset.yml

# 설치 확인
kubectl get pods -n kube-system | grep multus

위 명령어는 다음과 같은 작업을 수행합니다:

  • multus-daemonset.yml 파일을 적용하여 Multus CNI 설치
  • DaemonSet 형태로 각 노드에 Multus 컨테이너 배포
  • NetworkAttachmentDefinition CRD 생성

✅ NetworkAttachmentDefinition 생성

Multus CNI는 NetworkAttachmentDefinition이라는 커스텀 리소스를 사용하여 추가 네트워크 정의를 관리합니다. 다음은 Bridge 타입의 네트워크를 정의하는 예시입니다:

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: bridge-network           # 네트워크 정의 이름
  namespace: default             # 네임스페이스
spec:
  config: '{
    "cniVersion": "0.3.1",       # CNI 버전
    "name": "bridge-network",    # 네트워크 이름
    "type": "bridge",            # CNI 플러그인 타입 (bridge 사용)
    "bridge": "br0",             # 브릿지 이름
    "isGateway": true,           # 게이트웨이 역할 활성화
    "ipam": {
      "type": "host-local",      # IP 주소 관리 방식
      "subnet": "192.168.100.0/24", # 서브넷 설정
      "rangeStart": "192.168.100.10", # 시작 IP
      "rangeEnd": "192.168.100.50",   # 종료 IP
      "gateway": "192.168.100.1"      # 게이트웨이 IP
    }
  }'

위 설정을 bridge-network.yaml 파일로 저장한 후 적용합니다:

kubectl apply -f bridge-network.yaml

Docker Desktop 환경에서는 실제 브릿지 네트워크를 완전히 구성하는 데 제한이 있을 수 있습니다. 실제 환경에서는 호스트에 필요한 네트워크 브릿지가 미리 구성되어 있어야 합니다.


📌 VM에 다중 네트워크 구성하기

이제 Multus CNI를 사용하여 VM에 여러 네트워크 인터페이스를 구성해 보겠습니다.

✅ 다중 네트워크 VM 정의 작성

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: multi-net-vm
spec:
  running: true
  template:
    metadata:
      labels:
        kubevirt.io/vm: multi-net-vm
      annotations:
        # Multus 네트워크 연결 정의
        k8s.v1.cni.cncf.io/networks: bridge-network  # 위에서 생성한 네트워크 정의 이름
    spec:
      domain:
        devices:
          disks:
          - name: rootdisk
            disk:
              bus: virtio
          # 네트워크 인터페이스 정의
          interfaces:
          - name: default          # 기본 Pod 네트워크 (첫 번째 인터페이스)
            masquerade: {}         # NAT 방식 사용
          - name: bridge-net       # 추가 네트워크 (두 번째 인터페이스)
            bridge: {}             # 브릿지 모드 사용
            # 선택적으로 MAC 주소 지정 가능
            macAddress: "52:55:00:d1:55:01"
        resources:
          requests:
            memory: 1Gi
            cpu: 1
      networks:
      - name: default              # 기본 Pod 네트워크
        pod: {}                    # Kubernetes Pod 네트워크 사용
      - name: bridge-net           # 추가 네트워크
        multus:                    # Multus CNI 사용 명시
          networkName: bridge-network  # NetworkAttachmentDefinition 이름
      volumes:
      - name: rootdisk
        containerDisk:
          image: quay.io/kubevirt/ubuntu:22.04  # Ubuntu 이미지 사용

이 VM 정의를 multi-net-vm.yaml 파일로 저장한 후 적용합니다:

kubectl apply -f multi-net-vm.yaml

✅ VM 내부에서 네트워크 인터페이스 확인

VM이 생성되면 연결해서 네트워크 구성을 확인할 수 있습니다:

# VM 콘솔에 접속
kubectl virt console multi-net-vm

# VM 내부에서 네트워크 인터페이스 확인
ip addr

# 라우팅 테이블 확인
ip route

정상적으로 구성되었다면 VM 내부에서 다음과 같은 인터페이스를 볼 수 있습니다:

  • eth0: 기본 Pod 네트워크 인터페이스 (예: 10.244.x.y/24 IP)
  • eth1: Multus로 추가된 두 번째 네트워크 인터페이스 (예: 192.168.100.z/24 IP)

📌 다양한 Multus CNI 구성 옵션

Multus를 통해 다양한 네트워크 유형을 구성할 수 있습니다. 몇 가지 유용한 구성을 살펴보겠습니다.

✅ Macvlan 기반 네트워크 구성

Macvlan은 물리적 인터페이스를 여러 개의 가상 인터페이스로 나눕니다. 각 가상 인터페이스는 고유한 MAC 주소를 갖습니다.

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: macvlan-network
spec:
  config: '{
    "cniVersion": "0.3.1",
    "name": "macvlan-network",
    "type": "macvlan",           # macvlan 타입 사용
    "master": "eth0",            # 호스트의 물리 인터페이스
    "mode": "bridge",            # macvlan 모드 (bridge, vepa, private 등)
    "ipam": {
      "type": "host-local",
      "subnet": "192.168.200.0/24",
      "rangeStart": "192.168.200.10",
      "rangeEnd": "192.168.200.50",
      "gateway": "192.168.200.1"
    }
  }'

✅ SR-IOV 기반 고성능 네트워크 구성

SR-IOV(Single Root I/O Virtualization)는 물리적 네트워크 카드의 가상화 기능을 활용하여 고성능 네트워킹을 제공합니다. 실제 운영 환경에서 고성능이 필요한 경우 사용합니다.

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: sriov-network
spec:
  config: '{
    "cniVersion": "0.3.1",
    "name": "sriov-network",
    "type": "sriov",              # SR-IOV 타입 사용
    "ipam": {
      "type": "host-local",
      "subnet": "10.56.217.0/24",
      "rangeStart": "10.56.217.10",
      "rangeEnd": "10.56.217.50",
      "gateway": "10.56.217.1"
    }
  }'

SR-IOV를 사용하기 위해서는 클러스터에 SR-IOV 장치 플러그인과 CNI 플러그인이 설치되어 있어야 합니다.


📌 VM에 고정 IP 설정하기

Multus로 추가된 네트워크 인터페이스에 고정 IP를 설정하는 방법을 알아보겠습니다.

✅ VM 내부에서 고정 IP 설정

Ubuntu VM의 경우 Netplan을 사용하여 고정 IP를 구성할 수 있습니다:

# VM에 접속
kubectl virt console multi-net-vm

# Netplan 설정 파일 생성
sudo nano /etc/netplan/50-cloud-init.yaml

다음과 같이 Netplan 설정 파일을 작성합니다:

network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:  # 기본 Pod 네트워크 인터페이스
      dhcp4: true
    eth1:  # Multus로 추가된 두 번째 인터페이스
      dhcp4: no
      addresses:
        - 192.168.100.20/24  # 고정 IP 설정
      gateway4: 192.168.100.1
      nameservers:
        addresses: [8.8.8.8, 8.8.4.4]

설정을 적용합니다:

sudo netplan apply

✅ 시작 시 자동 IP 설정을 위한 cloud-init 활용

VM 템플릿에 cloud-init을 사용하여 시작 시 자동으로 네트워크 설정을 적용할 수 있습니다:

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: cloud-init-vm
spec:
  running: true
  template:
    metadata:
      labels:
        kubevirt.io/vm: cloud-init-vm
      annotations:
        k8s.v1.cni.cncf.io/networks: bridge-network
    spec:
      domain:
        devices:
          disks:
          - name: rootdisk
            disk:
              bus: virtio
          - name: cloudinitdisk  # cloud-init 디스크 추가
            disk:
              bus: virtio
          interfaces:
          - name: default
            masquerade: {}
          - name: bridge-net
            bridge: {}
      networks:
      - name: default
        pod: {}
      - name: bridge-net
        multus:
          networkName: bridge-network
      volumes:
      - name: rootdisk
        containerDisk:
          image: quay.io/kubevirt/ubuntu:22.04
      - name: cloudinitdisk     # cloud-init 볼륨 추가
        cloudInitNoCloud:
          userData: |
            #cloud-config
            password: password
            chpasswd: { expire: False }
            ssh_pwauth: True
            network:
              version: 2
              ethernets:
                eth0:
                  dhcp4: true
                eth1:
                  dhcp4: false
                  addresses: [192.168.100.20/24]
                  gateway4: 192.168.100.1
                  nameservers:
                    addresses: [8.8.8.8, 8.8.4.4]

이 설정을 cloud-init-vm.yaml 파일로 저장한 후 적용합니다:

kubectl apply -f cloud-init-vm.yaml

📌 실무에서 Multus 사용 시 고려 사항

✅ 네트워크 성능과 리소스 관리

Multus를 사용할 때 고려해야 할 성능 관련 사항입니다:

  1. CPU 오버헤드: 여러 네트워크 인터페이스는 추가 CPU 오버헤드를 발생시킵니다.
  2. 메모리 사용량: 각 인터페이스의 버퍼와 캐시로 인한 메모리 사용량 증가
  3. MTU 설정: 각 네트워크 인터페이스의 MTU 설정을 일관되게 유지

▶️ 성능 최적화 팁:

  • 불필요한 인터페이스 제거
  • SR-IOV와 같은 고성능 옵션 고려
  • 네트워크 격리가 필요한 경우에만 Multus 사용

✅ 네트워크 정책과 보안

다중 네트워크 환경에서 보안을 강화하기 위한 고려 사항입니다:

  1. 네트워크 분리: 중요한 트래픽은 별도의 네트워크로 분리
  2. 네트워크 정책 적용: 각 네트워크 인터페이스에 적절한 NetworkPolicy 적용
  3. 보안 그룹: 추가 네트워크의 트래픽에 대한 방화벽 규칙 구성

예를 들어, 다음과 같이 특정 네트워크에만 적용되는 NetworkPolicy를 구성할 수 있습니다:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: multus-network-policy
spec:
  podSelector:
    matchLabels:
      kubevirt.io/vm: multi-net-vm
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: database
    ports:
    - protocol: TCP
      port: 3306
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: api-server
    ports:
    - protocol: TCP
      port: 8080

✅ 관리 및 모니터링

다중 네트워크 VM 환경의 효과적인 관리를 위한 고려 사항입니다:

  1. 인터페이스 명명 규칙: 일관된 이름 지정으로 관리 용이성 확보
  2. IP 할당 추적: IPAM 시스템을 통한 IP 주소 관리
  3. 트래픽 모니터링: 각 네트워크 인터페이스별 트래픽 모니터링

▶️ Prometheus 메트릭 설정 예시:

  • 네트워크 인터페이스별 대역폭 사용량
  • 패킷 손실 및 오류율
  • 연결 상태 모니터링

✅ 배포 및 확장 전략

프로덕션 환경에서의 Multus 배포 전략에 대한 고려 사항입니다:

  1. 점진적 마이그레이션: 기존 VM을 단계적으로 Multus 네트워크로 마이그레이션
  2. 자동화 도입: 네트워크 구성 자동화를 위한 Operator 활용
  3. 재해 복구: 네트워크 장애 시 복구 전략 수립

▶️ 배포 자동화 예시:

  • Helm 차트를 통한 표준화된 Multus 배포
  • GitOps 기반 네트워크 구성 관리
  • 자동 검증 및 테스트 파이프라인 구축

📌 문제 해결 및 디버깅

Multus 네트워크 문제를 해결하는 방법을 알아보겠습니다.

✅ 일반적인 문제와 해결 방법

  1. Pod/VM에 추가 인터페이스가 나타나지 않는 경우
    • NetworkAttachmentDefinition 확인: kubectl get net-attach-def
    • Multus Pod 로그 확인: kubectl logs -n kube-system -l app=multus
    • 어노테이션 형식 확인: k8s.v1.cni.cncf.io/networks 형식이 올바른지 확인
  2. IP 할당 실패
    • IPAM 설정 확인
    • 서브넷 중복 여부 확인
    • IP 풀 고갈 여부 확인
  3. 네트워크 연결 문제
    • VM 내부에서 ip addr 및 ip route 확인
    • 호스트 네트워크 구성 확인
    • CNI 플러그인 로그 확인

✅ 디버깅 명령어 모음

# Multus 상태 확인
kubectl get pods -n kube-system -l app=multus

# NetworkAttachmentDefinition 확인
kubectl get net-attach-def
kubectl describe net-attach-def <name>

# VM Pod 확인
kubectl get pods -l kubevirt.io/vm=multi-net-vm
kubectl describe pod <vm-pod-name>

# VM Pod 로그 확인
kubectl logs <vm-pod-name> -c compute

# VM 내부에서 네트워크 디버깅
kubectl virt console multi-net-vm
# VM 내부에서:
ip addr
ip route
ping <target-ip>
traceroute <target-ip>

📌 실제 활용 사례

✅ 멀티 티어 애플리케이션 구성

여러 네트워크 인터페이스를 활용한 멀티 티어 애플리케이션 구성 예시입니다:

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: web-app-vm
spec:
  running: true
  template:
    metadata:
      labels:
        kubevirt.io/vm: web-app-vm
        app: web-tier
      annotations:
        k8s.v1.cni.cncf.io/networks: public-net, private-net
    spec:
      domain:
        devices:
          disks:
          - name: rootdisk
            disk:
              bus: virtio
          interfaces:
          - name: default        # 관리용 네트워크
            masquerade: {}
          - name: public         # 사용자 접속용 공개 네트워크
            bridge: {}
          - name: private        # 백엔드 서비스 통신용 내부 네트워크
            bridge: {}
      networks:
      - name: default
        pod: {}
      - name: public
        multus:
          networkName: public-net
      - name: private
        multus:
          networkName: private-net
      volumes:
      - name: rootdisk
        containerDisk:
          image: quay.io/kubevirt/ubuntu:22.04

✅ 데이터베이스 VM 구성

보안이 강화된 별도 네트워크에 데이터베이스 VM을 구성하는 예시입니다:

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: db-vm
spec:
  running: true
  template:
    metadata:
      labels:
        kubevirt.io/vm: db-vm
        app: database
      annotations:
        k8s.v1.cni.cncf.io/networks: secure-net
    spec:
      domain:
        devices:
          disks: # [...]
          interfaces:
          - name: default        # 관리용 네트워크
            masquerade: {}
          - name: secure         # 보안 강화된 DB 전용 네트워크
            bridge: {}
      networks:
      - name: default
        pod: {}
      - name: secure
        multus:
          networkName: secure-net
      volumes: # [...]

Summary

이번 글에서는 KubeVirt VM에 Multus CNI를 연동하여 다중 네트워크를 구성하는 방법에 대해 알아보았습니다. 핵심 내용을 요약하면:

  1. Multus CNI는 Pod 또는 VM에 여러 네트워크 인터페이스를 제공하는 메타 플러그인
  2. NetworkAttachmentDefinition을 통해 추가 네트워크를 정의하고 VM에 연결 가능
  3. VM에 고정 IP를 설정하기 위해 VM 내부 설정 또는 cloud-init 활용 가능
  4. 다양한 네트워크 유형(Bridge, Macvlan, SR-IOV 등)을 지원하여 유연한 네트워크 구성 가능
  5. 실무에서는 성능, 보안, 관리, 모니터링 등 다양한 측면을 고려해야 함
728x90