Skip to content

필사 모드: [가상화] 06. KubeVirt: 쿠버네티스 위에서 VM 실행하기

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

들어가며

컨테이너와 가상머신(VM)은 서로 대체재가 아닌 보완재입니다. 레거시 애플리케이션, Windows 워크로드, 커널 수준 커스터마이징이 필요한 경우에는 여전히 VM이 필수적입니다. KubeVirt는 쿠버네티스 API를 확장하여 VM을 Pod처럼 관리할 수 있게 해주는 프로젝트입니다.

KubeVirt란?

KubeVirt는 쿠버네티스 네이티브 VM 오케스트레이션 솔루션입니다. 쿠버네티스 API를 확장하여 VM 생명주기를 kubectl로 관리할 수 있습니다.

핵심 특징

- 쿠버네티스 CRD(Custom Resource Definition)로 VM 정의

- 기존 쿠버네티스 인프라(네트워킹, 스토리지, 모니터링) 재활용

- 컨테이너와 VM이 동일 클러스터에서 공존

- libvirt/QEMU/KVM 기반의 검증된 가상화 스택 활용

CNCF 프로젝트 현황

KubeVirt는 CNCF(Cloud Native Computing Foundation)의 주요 프로젝트입니다.

| 항목 | 상세 |

| -------------- | ------------------------------- |

| CNCF 레벨 | Incubating (Graduation 신청 중) |

| 도입 기업 | 41개 이상 |

| CNCF 순위 | Top 20 프로젝트 |

| GitHub 스타 | 5,000+ |

| 주요 사용 기업 | Red Hat, NVIDIA, ARM, CoreWeave |

아키텍처 상세

KubeVirt의 전체 아키텍처를 살펴보겠습니다.

+------------------------------------------------------------------+

| Kubernetes Control Plane |

| +------------+ +----------------+ +-------------------------+ |

| | API Server | | etcd | | Controller Manager | |

| +------+-----+ +----------------+ +-------------------------+ |

| | |

| +------v------------------+ |

| | virt-api | <-- API 확장, 유효성 검증 |

| | (Deployment) | |

| +------+------------------+ |

| | |

| +------v------------------+ |

| | virt-controller | <-- VM/VMI 감시, 생명주기 관리 |

| | (Deployment) | |

| +-------------------------+ |

+------------------------------------------------------------------+

+------------------------------------------------------------------+

| Worker Node |

| +-------------------------+ |

| | virt-handler | <-- 노드 수준 DaemonSet |

| | (DaemonSet) | |

| +------+------------------+ |

| | |

| +------v------------------+ +-------------------------------+ |

| | virt-launcher Pod | | virt-launcher Pod | |

| | +------------------+ | | +-------------------------+ | |

| | | libvirt | | | | libvirt | | |

| | | +------------+ | | | | +-------------------+ | | |

| | | | QEMU/KVM | | | | | | QEMU/KVM | | | |

| | | | (VM 1) | | | | | | (VM 2) | | | |

| | | +------------+ | | | | +-------------------+ | | |

| | +------------------+ | | +-------------------------+ | |

| +-------------------------+ +-------------------------------+ |

+------------------------------------------------------------------+

컴포넌트 상세

virt-api

API 서버의 확장 포인트로, VM 관련 API 요청을 처리합니다.

- Admission Webhook을 통한 VM 스펙 유효성 검증

- Subresource API 제공 (start, stop, restart, migrate)

- VNC/Console 프록시 엔드포인트

virt-controller

클러스터 수준 Deployment로, VM과 VMI 리소스를 감시합니다.

- VM CRD 변경 감지 및 VMI 생성/삭제

- virt-launcher Pod 스케줄링 요청

- 라이브 마이그레이션 오케스트레이션

- VM 상태 동기화

virt-handler

노드 수준 DaemonSet으로, 실제 VM 생명주기를 관리합니다.

- libvirt와 직접 통신

- VM 도메인 XML 생성 및 적용

- 노드 수준 네트워킹 설정

- 디바이스 핫플러그 처리

virt-launcher

개별 VM마다 생성되는 Pod입니다.

- libvirt 데몬 실행

- QEMU/KVM 프로세스 관리

- VM 콘솔 접근 제공

- Pod 종료 시 VM 정리(cleanup)

CRD (Custom Resource Definitions)

VirtualMachine (VM)

VM은 가상머신의 선언적 정의입니다. Pod에 대한 Deployment와 유사한 역할을 합니다.

apiVersion: kubevirt.io/v1

kind: VirtualMachine

metadata:

name: my-vm

namespace: default

spec:

running: true

template:

metadata:

labels:

app: my-vm

spec:

domain:

cpu:

cores: 2

memory:

guest: 4Gi

devices:

disks:

- name: rootdisk

disk:

bus: virtio

- name: cloudinitdisk

disk:

bus: virtio

interfaces:

- name: default

masquerade: {}

networks:

- name: default

pod: {}

volumes:

- name: rootdisk

dataVolume:

name: my-vm-dv

- name: cloudinitdisk

cloudInitNoCloud:

userData: |

#cloud-config

hostname: my-vm

ssh_authorized_keys:

- ssh-rsa AAAA...

VirtualMachineInstance (VMI)

VMI는 실행 중인 VM 인스턴스를 나타냅니다. Pod와 유사하게, 실제 실행 상태를 반영합니다.

apiVersion: kubevirt.io/v1

kind: VirtualMachineInstance

metadata:

name: my-vmi

spec:

domain:

cpu:

cores: 1

memory:

guest: 2Gi

devices:

disks:

- name: rootdisk

disk:

bus: virtio

volumes:

- name: rootdisk

containerDisk:

image: quay.io/kubevirt/fedora-cloud-container-disk-demo:latest

VirtualMachineInstanceReplicaSet

동일한 VMI를 여러 개 복제하여 실행합니다.

apiVersion: kubevirt.io/v1

kind: VirtualMachineInstanceReplicaSet

metadata:

name: my-vmirs

spec:

replicas: 3

selector:

matchLabels:

app: web-vm

template:

metadata:

labels:

app: web-vm

spec:

domain:

cpu:

cores: 1

memory:

guest: 1Gi

devices:

disks:

- name: rootdisk

disk:

bus: virtio

volumes:

- name: rootdisk

containerDisk:

image: quay.io/kubevirt/fedora-cloud-container-disk-demo:latest

VirtualMachineInstanceMigration

VMI를 다른 노드로 라이브 마이그레이션합니다.

apiVersion: kubevirt.io/v1

kind: VirtualMachineInstanceMigration

metadata:

name: migration-job

spec:

vmiName: my-vmi

CDI (Containerized Data Importer)

CDI는 VM 디스크 이미지를 쿠버네티스 PVC로 가져오는 컴포넌트입니다.

DataVolume CRD

apiVersion: cdi.kubevirt.io/v1beta1

kind: DataVolume

metadata:

name: ubuntu-dv

spec:

source:

http:

url: 'https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img'

storage:

accessModes:

- ReadWriteOnce

resources:

requests:

storage: 10Gi

storageClassName: local-path

다양한 이미지 소스

CDI는 여러 소스에서 디스크 이미지를 가져올 수 있습니다.

+------------------+ +-------+ +------------------+

| HTTP/HTTPS URL | --> | | | |

+------------------+ | | | |

| | | |

+------------------+ | CDI | --> | PersistentVolume|

| Container Registry| --> | | | Claim (PVC) |

+------------------+ | | | |

| | | |

+------------------+ | | | |

| S3 Bucket | --> | | | |

+------------------+ +-------+ +------------------+

| oVirt / VMware | -->

+------------------+

컨테이너 레지스트리에서 가져오기

apiVersion: cdi.kubevirt.io/v1beta1

kind: DataVolume

metadata:

name: registry-dv

spec:

source:

registry:

url: 'docker://quay.io/kubevirt/fedora-cloud-container-disk-demo:latest'

storage:

accessModes:

- ReadWriteOnce

resources:

requests:

storage: 5Gi

S3에서 가져오기

apiVersion: cdi.kubevirt.io/v1beta1

kind: DataVolume

metadata:

name: s3-dv

spec:

source:

s3:

url: 's3://my-bucket/images/rhel9.qcow2'

secretRef: s3-credentials

storage:

accessModes:

- ReadWriteOnce

resources:

requests:

storage: 20Gi

네트워킹

기본 Pod 네트워크

기본적으로 VM은 Pod 네트워크를 사용합니다. masquerade 모드가 권장됩니다.

spec:

domain:

devices:

interfaces:

- name: default

masquerade: {}

networks:

- name: default

pod: {}

Multus를 통한 다중 네트워크

Multus CNI를 사용하면 VM에 여러 네트워크 인터페이스를 연결할 수 있습니다.

apiVersion: k8s.cni.cncf.io/v1

kind: NetworkAttachmentDefinition

metadata:

name: br-vlan100

spec:

config: |

{

"cniVersion": "0.3.1",

"type": "bridge",

"bridge": "br-vlan100",

"vlan": 100,

"ipam": {

"type": "host-local",

"subnet": "10.100.0.0/24"

}

}

apiVersion: kubevirt.io/v1

kind: VirtualMachine

metadata:

name: multi-net-vm

spec:

running: true

template:

spec:

domain:

devices:

interfaces:

- name: default

masquerade: {}

- name: vlan100

bridge: {}

networks:

- name: default

pod: {}

- name: vlan100

multus:

networkName: br-vlan100

스토리지

VM 디스크는 PVC(PersistentVolumeClaim)를 통해 관리됩니다.

스토리지 옵션 비교

| 스토리지 유형 | 용도 | 지속성 |

| ---------------- | ------------------------ | ------ |

| PVC | 영구 디스크 | 영구 |

| DataVolume | CDI를 통한 이미지 임포트 | 영구 |

| containerDisk | 읽기 전용 부팅 이미지 | 임시 |

| emptyDisk | 임시 데이터 | 임시 |

| cloudInitNoCloud | 초기 설정 데이터 | 임시 |

라이브 마이그레이션

라이브 마이그레이션은 VM을 중단 없이 다른 노드로 이동하는 기능입니다.

요구 사항

- ReadWriteMany(RWX) 접근 모드의 PVC

- 공유 스토리지 (Ceph, NFS 등)

- 소스/대상 노드 간 동일한 CPU 기능 세트

마이그레이션 실행

kubectl로 마이그레이션 시작

kubectl virt migrate my-vm

또는 Migration CRD 생성

cat <<EOF | kubectl apply -f -

apiVersion: kubevirt.io/v1

kind: VirtualMachineInstanceMigration

metadata:

name: migration-my-vm

spec:

vmiName: my-vm

EOF

마이그레이션 상태 확인

kubectl get vmim migration-my-vm -o yaml

마이그레이션 정책 설정

apiVersion: migrations.kubevirt.io/v1alpha1

kind: MigrationPolicy

metadata:

name: high-priority-policy

spec:

bandwidthPerMigration: 1Gi

completionTimeoutPerGiB: 800

allowAutoConverge: true

selectors:

namespaceSelector:

matchLabels:

migration-policy: high-priority

설치 가이드

Operator 설치

최신 버전 확인

export KUBEVIRT_VERSION=$(curl -s https://api.github.com/repos/kubevirt/kubevirt/releases/latest | grep tag_name | cut -d '"' -f 4)

Operator 배포

kubectl apply -f "https://github.com/kubevirt/kubevirt/releases/download/$KUBEVIRT_VERSION/kubevirt-operator.yaml"

KubeVirt CR 생성

kubectl apply -f "https://github.com/kubevirt/kubevirt/releases/download/$KUBEVIRT_VERSION/kubevirt-cr.yaml"

설치 완료 대기

kubectl wait kv kubevirt -n kubevirt --for=condition=Available --timeout=300s

virtctl CLI 설치

virtctl 다운로드

curl -L -o virtctl \

"https://github.com/kubevirt/kubevirt/releases/download/$KUBEVIRT_VERSION/virtctl-$KUBEVIRT_VERSION-linux-amd64"

chmod +x virtctl

sudo mv virtctl /usr/local/bin/

CDI 설치

export CDI_VERSION=$(curl -s https://api.github.com/repos/kubevirt/containerized-data-importer/releases/latest | grep tag_name | cut -d '"' -f 4)

kubectl apply -f "https://github.com/kubevirt/containerized-data-importer/releases/download/$CDI_VERSION/cdi-operator.yaml"

kubectl apply -f "https://github.com/kubevirt/containerized-data-importer/releases/download/$CDI_VERSION/cdi-cr.yaml"

실전 예제: Ubuntu VM 생성

apiVersion: cdi.kubevirt.io/v1beta1

kind: DataVolume

metadata:

name: ubuntu-22-04

spec:

source:

http:

url: 'https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img'

storage:

accessModes:

- ReadWriteOnce

resources:

requests:

storage: 20Gi

apiVersion: kubevirt.io/v1

kind: VirtualMachine

metadata:

name: ubuntu-server

labels:

app: ubuntu-server

spec:

running: true

template:

metadata:

labels:

app: ubuntu-server

spec:

domain:

cpu:

cores: 2

memory:

guest: 4Gi

devices:

disks:

- name: rootdisk

disk:

bus: virtio

- name: cloudinitdisk

disk:

bus: virtio

interfaces:

- name: default

masquerade: {}

networks:

- name: default

pod: {}

volumes:

- name: rootdisk

dataVolume:

name: ubuntu-22-04

- name: cloudinitdisk

cloudInitNoCloud:

userData: |

#cloud-config

hostname: ubuntu-server

user: ubuntu

password: changeme

chpasswd:

expire: false

ssh_authorized_keys:

- ssh-rsa AAAA...your-key

packages:

- qemu-guest-agent

runcmd:

- systemctl enable --now qemu-guest-agent

유스케이스

1. 하이브리드 컨테이너/VM 워크로드

마이크로서비스(컨테이너)와 레거시 모놀리스(VM)를 하나의 클러스터에서 운영합니다.

2. 레거시 애플리케이션 마이그레이션

VMware, OpenStack 등에서 실행 중인 기존 VM을 쿠버네티스로 점진적으로 이전합니다.

3. Windows 워크로드

.NET Framework 애플리케이션이나 Active Directory 서버를 쿠버네티스 클러스터에서 실행합니다.

4. 개발/테스트 환경

다양한 OS 환경을 빠르게 프로비저닝하고 테스트에 활용합니다.

마치며

KubeVirt는 컨테이너와 VM의 경계를 허물어 통합 인프라 관리를 가능하게 합니다. CNCF 프로젝트로서 활발한 커뮤니티 지원을 받고 있으며, Red Hat OpenShift Virtualization의 핵심 기술이기도 합니다.

다음 글에서는 NVIDIA GPU Operator를 통해 쿠버네티스에서 GPU를 자동으로 관리하는 방법을 알아보겠습니다.

**Q1. KubeVirt에서 VM의 선언적 정의를 담당하는 CRD는?**

A) VirtualMachineInstance

B) VirtualMachine

C) VirtualMachineInstanceReplicaSet

D) VirtualMachineInstanceMigration

정답: B) VirtualMachine - Deployment와 유사하게 VM의 원하는 상태(desired state)를 선언합니다.

**Q2. virt-launcher의 역할은?**

A) 클러스터 수준에서 VM 리소스를 감시

B) API 요청 유효성 검증

C) 개별 VM마다 생성되는 Pod로 libvirt/QEMU 실행

D) 노드 수준에서 libvirt와 통신

정답: C) virt-launcher는 각 VM에 대해 하나의 Pod로 생성되며, 내부에서 libvirt와 QEMU/KVM 프로세스를 관리합니다.

**Q3. CDI의 DataVolume이 지원하지 않는 이미지 소스는?**

A) HTTP/HTTPS URL

B) 컨테이너 레지스트리

C) Git 리포지토리

D) S3 버킷

정답: C) Git 리포지토리는 CDI 소스로 지원되지 않습니다. HTTP, Registry, S3, oVirt, VMware가 지원됩니다.

**Q4. 라이브 마이그레이션의 필수 요구 사항은?**

A) ReadWriteOnce PVC

B) ReadWriteMany PVC + 공유 스토리지

C) emptyDisk 볼륨

D) containerDisk 볼륨

정답: B) 라이브 마이그레이션은 소스/대상 노드에서 동시에 접근 가능한 공유 스토리지(RWX)가 필요합니다.

현재 단락 (1/412)

컨테이너와 가상머신(VM)은 서로 대체재가 아닌 보완재입니다. 레거시 애플리케이션, Windows 워크로드, 커널 수준 커스터마이징이 필요한 경우에는 여전히 VM이 필수적입니다. ...

작성 글자: 0원문 글자: 9,632작성 단락: 0/412