이 글에서는 KubeVirt로 생성한 가상 머신의 네트워크 설정에 대해 알아보겠습니다. Kubernetes 클러스터 내에서 VM이 어떻게 네트워크를 구성하고, 외부와 통신할 수 있는지를 실습과 함께 상세히 설명합니다. Docker Desktop 환경에서 KubeVirt VM이 인터넷에 접속하고, 클러스터 내 다른 서비스와 통신하는 방법까지 단계별로 살펴볼 것입니다.
📌 KubeVirt 네트워크의 이해
KubeVirt의 매력적인 특징 중 하나는 Kubernetes의 기존 네트워킹 메커니즘을 그대로 활용할 수 있다는 점입니다. 이는 가상 머신이 컨테이너와 동일한 네트워크 인프라를 공유한다는 의미로, VM과 컨테이너 간의 원활한 통신이 가능해집니다.
✅ VM 네트워크의 기본 구조
KubeVirt VM은 기본적으로 다음과 같은 네트워크 구조를 갖습니다:
- Pod 네트워크 사용: VM은 기본적으로 호스팅하는 Pod의 네트워크 인터페이스를 상속받아 사용
- virt-launcher 브리지: VM과 Pod 네트워크 사이에는 virt-launcher에서 생성한 브리지가 존재
- CNI 플러그인 호환성: 클러스터에서 사용 중인 CNI(Container Network Interface)와 자동 통합
✅ 가상 머신의 네트워크 인터페이스 이해하기
KubeVirt VM의 네트워크 인터페이스(NIC)는 VM 정의 시 명시적으로 구성됩니다. 각 인터페이스는 다음과 같은 구성 요소를 가집니다:
- name: 네트워크 인터페이스의 식별자
- model: virtio, e1000 등 가상 NIC 하드웨어 모델
- macAddress: 선택적으로 지정 가능한 MAC 주소
- network: 연결할 네트워크 리소스 참조
▶️ 예시: VM 정의 시 네트워크 인터페이스 선언
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: ubuntu-vm
spec:
running: true
template:
metadata:
labels:
kubevirt.io/vm: ubuntu-vm
spec:
domain:
devices:
disks:
- name: containerdisk
disk:
bus: virtio
# 네트워크 인터페이스 정의 시작
interfaces:
- name: default # 인터페이스 이름 (VM 내부에서 식별용)
model: virtio # virtio: 최적화된 가상화 네트워크 드라이버 모델
masquerade: {} # NAT 방식으로 외부 통신 활성화 (가장 일반적인 설정)
# 네트워크 인터페이스 정의 끝
networks:
- name: default # 위에서 정의한 인터페이스와 매칭되는 name
pod: {} # Pod 네트워크 사용 (기본 네트워크)
volumes:
- name: containerdisk
containerDisk:
image: quay.io/kubevirt/cirros-container-disk-demo:latest
📌 네트워크 모델 유형
KubeVirt에서는 VM의 네트워크 유형을 여러 가지 방식으로 구성할 수 있습니다. 각 모델은 서로 다른 유스케이스와 네트워크 요구사항에 최적화되어 있습니다.
✅ 주요 네트워크 바인딩 유형
- masquerade (NAT 방식)
- bridge
- slirp
- macvtap
이 중에서 가장 일반적으로 사용되는 모델은 masquerade 방식입니다.
✅ masquerade 모드 상세 설명
masquerade 모드는 NAT(Network Address Translation)를 사용하여 VM이 외부와 통신할 수 있게 해줍니다.
▶️ 작동 방식:
- VM 내부 IP는 Pod IP와 다름
- Pod가 VM 트래픽에 대한 NAT 역할 수행
- 외부에서는 Pod IP로 트래픽이 들어오고 Pod 내부에서 VM IP로 전달됨
interfaces:
- name: default
masquerade: {} # NAT 모드 활성화
# 추가 옵션으로 ports 포워딩 가능
ports:
- port: 80 # Pod로 들어오는 포트
targetPort: 8080 # VM 내부로 포워딩할 포트
✅ bridge 모드 이해하기
bridge 모드는 VM을 네트워크 계층에서 클러스터와 직접 연결합니다.
▶️ 특징:
- VM이 클러스터 네트워크에서 직접 IP를 획득
- Pod IP와 VM IP가 동일한 네트워크 대역
- 추가 NAT 없이 직접 통신 가능
interfaces:
- name: bridge-net
bridge: {} # 브릿지 모드 활성화
📌 VM에서 외부 통신 구성하기
실습을 통해 VM에서 외부 인터넷 및 클러스터 내 다른 서비스와 통신하는 방법을 알아보겠습니다.
✅ 기본 NAT 네트워크로 VM 생성하기
가장 간단한 방법은 masquerade 모드를 사용하는 것입니다. 다음은 외부 통신이 가능한 기본 VM 구성입니다.
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: ubuntu-net-demo
spec:
running: true
template:
metadata:
labels:
kubevirt.io/vm: ubuntu-net-demo
spec:
domain:
devices:
disks:
- name: rootdisk
disk:
bus: virtio
interfaces:
- name: default
masquerade: {} # NAT 모드로 외부 통신 활성화
resources:
requests:
memory: 1Gi
cpu: 1
networks:
- name: default
pod: {} # Kubernetes Pod 네트워크 사용
volumes:
- name: rootdisk
containerDisk:
image: quay.io/kubevirt/ubuntu:22.04 # Ubuntu 이미지 사용
이 VM 정의를 ubuntu-vm-net.yaml 파일로 저장한 후 적용합니다:
kubectl apply -f ubuntu-vm-net.yaml
✅ VM 내부에서 네트워크 연결 확인하기
VM이 생성되면 연결해서 네트워크 구성을 확인할 수 있습니다:
# VM 콘솔에 접속
kubectl virt console ubuntu-net-demo
# VM 내부에서 네트워크 인터페이스 확인
ip addr
# 외부 연결 테스트
ping -c 3 8.8.8.8
# DNS 확인
cat /etc/resolv.conf
VM 내부에서는 다음과 유사한 네트워크 구성을 볼 수 있습니다:
- eth0: VM의 주 네트워크 인터페이스 (예: 10.244.x.y와 같은 IP)
- 기본 게이트웨이: Pod의 NAT 게이트웨이 IP
📌 서비스 노출: NodePort, ClusterIP, LoadBalancer
VM을 생성했다면 이제 외부에서 VM 내부 서비스에 접근할 수 있도록 설정해 보겠습니다.
✅ VM 내부에 웹 서버 설치
예제로 간단한 웹 서버를 VM에 설치하고 외부에 노출해 보겠습니다:
# VM 콘솔 접속
kubectl virt console ubuntu-net-demo
# 패키지 업데이트 및 nginx 설치
sudo apt update
sudo apt install -y nginx
# 웹 서버 상태 확인
sudo systemctl status nginx
# 테스트 페이지 생성
echo "<h1>KubeVirt VM Network Test</h1>" | sudo tee /var/www/html/index.html
✅ Service 리소스로 VM 서비스 노출하기
VM에서 실행 중인 서비스(예: nginx)를 외부에 노출하기 위해 Kubernetes Service 리소스를 사용합니다.
▶️ NodePort 서비스 예제:
apiVersion: v1
kind: Service
metadata:
name: vm-nginx-nodeport
spec:
selector:
kubevirt.io/vm: ubuntu-net-demo # VM Pod를 선택하는 라벨
ports:
- port: 80 # 서비스 포트
targetPort: 80 # VM 내부 포트
protocol: TCP
type: NodePort # NodePort 유형 서비스
이 Service 정의를 vm-nodeport.yaml 파일로 저장한 후 적용합니다:
kubectl apply -f vm-nodeport.yaml
# 할당된 NodePort 확인
kubectl get svc vm-nginx-nodeport
▶️ LoadBalancer 서비스 예제 (클라우드 환경에서):
apiVersion: v1
kind: Service
metadata:
name: vm-nginx-lb
spec:
selector:
kubevirt.io/vm: ubuntu-net-demo # VM Pod를 선택하는 라벨
ports:
- port: 80 # 서비스 포트
targetPort: 80 # VM 내부 포트
protocol: TCP
type: LoadBalancer # LoadBalancer 유형 (클라우드 환경)
Docker Desktop 환경에서는 LoadBalancer 유형도 localhost에서 접근 가능합니다.
✅ 포트 포워딩 직접 설정
임시로 테스트하려면 kubectl port-forward 명령을 사용할 수도 있습니다:
# VM이 실행 중인 Pod 이름 찾기
POD=$(kubectl get pods -l kubevirt.io/vm=ubuntu-net-demo -o jsonpath='{.items[0].metadata.name}')
# 포트 포워딩 설정 (로컬 8080 → VM 80)
kubectl port-forward $POD 8080:80
이제 브라우저에서 http://localhost:8080으로 접속하면 VM의 웹 서버에 접근할 수 있습니다.
📌 VM 간 통신 구성하기
여러 VM 간의 통신을 설정하는 방법을 알아보겠습니다.
✅ ClusterIP 서비스로 VM 간 통신
두 VM이 있을 때, 서로 통신하는 가장 간단한 방법은 ClusterIP 서비스를 사용하는 것입니다.
▶️ ClusterIP 서비스 예제:
apiVersion: v1
kind: Service
metadata:
name: vm-internal-svc
spec:
selector:
kubevirt.io/vm: ubuntu-net-demo # 대상 VM Pod
ports:
- port: 80 # 서비스 포트
targetPort: 80 # VM 내부 포트
type: ClusterIP # 클러스터 내부 서비스 (기본값)
다른 VM에서 vm-internal-svc 이름으로 이 서비스에 접근할 수 있습니다:
# 다른 VM에서
curl vm-internal-svc
✅ VM 네트워크 디버깅 팁
VM의 네트워크 문제를 해결하기 위한 몇 가지 디버깅 팁입니다:
- Pod 네트워크 상태 확인:
# VM Pod 찾기
kubectl get pods -l kubevirt.io/vm=ubuntu-net-demo
# Pod 상세 정보 확인
kubectl describe pod <pod-name>
- VM 내부 네트워크 상태 확인:
# VM 콘솔 접속
kubectl virt console ubuntu-net-demo
# 네트워크 인터페이스 및 라우팅 테이블 확인
ip addr
ip route
- VM 네트워크 구성 로그 확인:
# virt-launcher Pod의 로그 확인
kubectl logs <pod-name> -c compute
📌 네트워크 보안 정책 적용하기
Kubernetes 네트워크 정책을 사용해 VM 트래픽을 제어할 수 있습니다.
✅ NetworkPolicy로 VM 트래픽 제어하기
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: vm-network-policy
spec:
podSelector:
matchLabels:
kubevirt.io/vm: ubuntu-net-demo # 대상 VM
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector: # 특정 Pod에서만 접근 허용
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 80 # 80 포트로만 접근 허용
egress:
- to:
- namespaceSelector: # 특정 네임스페이스로만 나가는 트래픽 허용
matchLabels:
kubernetes.io/metadata.name: database
ports:
- protocol: TCP
port: 5432 # 5432 포트로만 접근 허용
이 정책은 VM에 대한 인바운드 트래픽을 app=frontend 라벨이 있는 Pod에서 오는 80 포트 요청으로 제한하고, 아웃바운드 트래픽은 database 네임스페이스의 5432 포트로만 허용합니다.
Summary
이번 글에서는 KubeVirt VM의 기본 네트워크 설정과 외부 통신 방법에 대해 알아보았습니다. 핵심 내용을 요약하면:
- KubeVirt VM은 기본적으로 Pod 네트워크를 활용하여 통신
- masquerade(NAT) 모드는 가장 일반적인 네트워크 연결 방식
- bridge 모드는 VM이 클러스터 네트워크에 직접 연결되는 방식
- VM 서비스 노출을 위해 NodePort, ClusterIP, LoadBalancer 서비스 사용 가능
- Kubernetes NetworkPolicy를 통해 VM 트래픽 제어 가능
'Kubernetes Tools > Kubevirt' 카테고리의 다른 글
[KubeVirt Ep. 9] kubevirt에서 VM 관리하기 | 라이프사이클, 마이그레이션, HA (0) | 2025.03.21 |
---|---|
[KubeVirt Ep.8] 🚀 Multus CNI 연동하기 | VM에 다중 네트워크 붙이기 (0) | 2025.03.21 |
[KubeVirt Ep.6] 🚀 VM의 스토리지 설정 | ephemeral vs persistent (0) | 2025.03.21 |
[KubeVirt Ep.5] 🚀 VM 이미지 다루기 | ContainerDisk와 PVC 이해 및 활용 (0) | 2025.03.21 |
[KubeVirt Ep.4] 🚀 VirtualMachine 리소스 실습 | 나만의 VM 만들기 (0) | 2025.03.21 |