이 글에서는 KubeVirt에서 VM 이미지를 다루는 다양한 방법을 알아보겠습니다. ContainerDisk의 개념과 활용법, Docker를 사용하여 qcow2 이미지를 ContainerDisk로 변환하는 방법, 그리고 PVC 기반 스토리지 및 DataVolume을 활용하는 방법을 실습 중심으로 살펴보겠습니다.
📌 KubeVirt의 VM 이미지 개요
KubeVirt에서 VM을 실행하려면 운영체제가 설치된 디스크 이미지가 필요합니다. 여러 방식으로 VM 이미지를 제공할 수 있으며, 각 방식에는 장단점이 있습니다.
✅ VM 이미지 제공 방식
KubeVirt에서 VM 이미지를 제공하는 주요 방식은 다음과 같습니다:
- ContainerDisk: 디스크 이미지를 컨테이너 이미지로 패키징
- 장점: 컨테이너 레지스트리를 통한 배포, 불변성, 재사용성
- 단점: 상태 유지 불가, 대용량 이미지 관리 어려움
- PVC (PersistentVolumeClaim): 쿠버네티스 영구 볼륨에 디스크 이미지 저장
- 장점: 상태 유지, 쿠버네티스 스토리지 통합
- 단점: 이미지 관리 복잡성, 초기 설정 필요
- DataVolume: CDI(Containerized Data Importer)를 통한 이미지 가져오기 및 관리
- 장점: HTTP 소스에서 직접 가져오기, VM 생성 과정 자동화
- 단점: 추가 구성요소(CDI) 필요
- ephemeral 스토리지: 임시 디스크 기반 VM 실행
- 장점: 빠른 프로비저닝, 테스트 용도로 적합
- 단점: VM 재시작 시 모든 데이터 손실
✅ 디스크 이미지 형식
KubeVirt는 다양한 디스크 이미지 형식을 지원합니다:
- QCOW2 (QEMU Copy-On-Write v2):
- 가장 널리 사용되는 형식
- 공간 효율적, 스냅샷 지원
- 예: ubuntu-20.04.qcow2
- RAW:
- 압축되지 않은 원시 디스크 이미지
- 최고 성능, 단순함
- 공간 효율성 낮음
- ISO:
- 설치 미디어 용도
- 읽기 전용
- VM 설치 과정에 주로 사용
▶️ 이미지 선택 팁: "프로덕션 환경에서는 QCOW2 형식이 공간 효율성과 스냅샷 기능을 제공하기 때문에 권장됩니다. 개발 및 테스트 환경에서는 ContainerDisk를 사용하면 빠르고 간편하게 VM을 배포할 수 있습니다."
📌 ContainerDisk 개념 이해하기
ContainerDisk는 KubeVirt의 혁신적인 기능 중 하나로, VM 디스크 이미지를 컨테이너 이미지로 패키징하여 쿠버네티스의 컨테이너 인프라를 활용하는 방식입니다.
✅ ContainerDisk의 작동 원리
ContainerDisk는 다음과 같은 원리로 작동합니다:
- 디스크 이미지(qcow2, raw 등)를 컨테이너 이미지로 패키징
- 컨테이너 레지스트리에 이미지 저장 및 배포
- VM 생성 시 컨테이너에서 디스크 이미지를 추출하여 VM에 마운트
- VM Pod의 초기화 컨테이너를 통해 디스크 이미지 제공
# ContainerDisk를 사용한 VM 예시
apiVersion: kubevirt.io/v1 # KubeVirt API 버전
kind: VirtualMachine # 리소스 종류: 가상머신 정의
metadata:
name: containerdisk-vm # VM 이름
spec:
running: true # VM 생성 후 바로 실행 여부
template:
spec:
domain: # VM 하드웨어 정의 시작
devices:
disks: # 디스크 장치 목록
- name: containerdisk # 디스크 이름 (volumes와 연결됨)
disk:
bus: virtio # 디스크 버스 유형 (virtio: 성능 최적화)
volumes: # 볼륨 정의 시작
- name: containerdisk # 디스크와 동일한 이름 (연결 필요)
containerDisk: # ContainerDisk 볼륨 유형 지정
image: quay.io/kubevirt/fedora-container-disk-demo:latest # 컨테이너 이미지 위치
path: /disk/fedora.qcow2 # 컨테이너 내 디스크 이미지 경로 (선택적)
imagePullPolicy: IfNotPresent # 이미지 풀 정책 (기존 이미지 재사용)
✅ ContainerDisk의 장점
ContainerDisk는 다음과 같은 장점을 제공합니다:
- 불변성(Immutability): 이미지가 변경되지 않으므로 일관된 환경 보장
- 재현성(Reproducibility): 동일한 이미지를 여러 VM에서 재사용 가능
- 배포 간소화: 컨테이너 레지스트리를 통한 간편한 배포 및 버전 관리
- 쿠버네티스 통합: 기존 컨테이너 인프라와 워크플로우 활용
✅ ContainerDisk의 단점 및 제한사항
ContainerDisk에는 다음과 같은 제한사항도 있습니다:
- 상태 유지 불가: 변경사항이 유지되지 않음 (읽기 전용 특성)
- 디스크 이미지 크기: 대용량 이미지의 경우 컨테이너 이미지 크기 증가
- 이미지 레이어 제한: 컨테이너 이미지 계층 구조로 인한 제약
▶️ 사용 사례 가이드: "ContainerDisk는 OS 이미지나 불변 애플리케이션 이미지에 적합합니다. 사용자 데이터나 동적으로 변경되는 데이터는 별도의 PVC를 추가하여 관리해야 합니다."
📌 Docker로 qcow2 이미지를 ContainerDisk로 만들기
이제 직접 qcow2 이미지를 ContainerDisk로 변환하는 과정을 실습해 보겠습니다.
✅ 필요한 도구 및 사전 준비
ContainerDisk를 만들기 위해 다음 도구가 필요합니다:
- Docker 또는 Podman (컨테이너 이미지 빌드용)
- qcow2 또는 raw 형식의 VM 이미지
- 컨테이너 레지스트리 계정 (Docker Hub, Quay.io 등)
사전에 VM 이미지를 준비하거나 다운로드해야 합니다. 예를 들어, Ubuntu 클라우드 이미지:
# Ubuntu 클라우드 이미지 다운로드
$ wget https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img
# Ubuntu 20.04 LTS (Focal) 클라우드 이미지를 다운로드합니다
# 클라우드 이미지는 cloud-init으로 초기화되도록 미리 구성되어 있습니다
✅ Dockerfile 작성
ContainerDisk 이미지를 만들기 위한 간단한 Dockerfile을 작성합니다:
# Dockerfile
FROM scratch # 빈 베이스 이미지 사용 (최소 크기로 컨테이너 생성)
ADD focal-server-cloudimg-amd64.img /disk/ubuntu.qcow2 # 로컬 디스크 이미지를 /disk 경로에 추가
# 참고: scratch 이미지를 사용해 최소한의 오버헤드만 갖게 됨
# /disk 경로는 KubeVirt가 기본적으로 디스크 이미지를 찾는 위치입니다
이 Dockerfile은 매우 단순합니다:
- FROM scratch: 빈 베이스 이미지 사용 (추가 OS 레이어 없음)
- ADD: 로컬 디스크 이미지를 컨테이너 이미지에 추가
✅ 이미지 빌드 및 푸시
Dockerfile을 사용하여 컨테이너 이미지를 빌드하고 레지스트리에 푸시합니다:
# 이미지 빌드
$ docker build -t yourusername/ubuntu-container-disk:20.04 .
# Dockerfile을 사용해 ContainerDisk 이미지를 빌드합니다
# -t: 이미지 태그 지정 (registry/name:tag 형식)
# . : 현재 디렉토리의 Dockerfile 사용
# 이미지 푸시
$ docker push yourusername/ubuntu-container-disk:20.04
# 빌드한 이미지를 컨테이너 레지스트리에 업로드합니다
# 이렇게 하면 KubeVirt가 이미지를 가져와 VM 디스크로 사용할 수 있습니다
✅ 여러 디스크 이미지를 포함하는 ContainerDisk
여러 디스크 이미지를 하나의 ContainerDisk에 포함시킬 수도 있습니다:
# 여러 디스크가 포함된 Dockerfile
FROM scratch # 빈 베이스 이미지
ADD ubuntu-20.04.qcow2 /disk/ubuntu.qcow2 # 시스템 디스크 이미지
ADD data-disk.qcow2 /disk/data.qcow2 # 데이터 디스크 이미지
ADD windows-2019.qcow2 /disk/windows.qcow2 # Windows 이미지
# 여러 디스크 이미지를 하나의 컨테이너에 패키징합니다
# 각 이미지는 다른 경로에 저장됩니다
이 경우 VM 정의에서 path 속성을 사용하여 특정 디스크를 지정합니다:
volumes:
- name: rootdisk
containerDisk:
image: yourusername/multi-disk-container:latest # 여러 디스크가 들어있는 이미지
path: /disk/ubuntu.qcow2 # 특정 디스크 경로 지정
# path를 사용하면 하나의 컨테이너에서 특정 디스크만 선택해 사용할 수 있습니다
✅ 빈 ContainerDisk 생성
새로운 빈 디스크를 ContainerDisk로 만들어야 할 경우:
# 빈 디스크 이미지 생성
$ qemu-img create -f qcow2 empty-disk.qcow2 10G
# qemu-img 도구로 10GB 크기의 빈 qcow2 이미지 생성
# -f qcow2: qcow2 형식 지정
# 10G: 디스크 크기 (10 기가바이트)
# Dockerfile 작성
$ echo 'FROM scratch
ADD empty-disk.qcow2 /disk/empty.qcow2' > Dockerfile.empty
# 빈 디스크를 포함하는 간단한 Dockerfile 생성
# 이미지 빌드
$ docker build -f Dockerfile.empty -t yourusername/empty-disk:10g .
# 특정 Dockerfile을 지정하여 빌드 (-f 옵션 사용)
# 이미지 푸시
$ docker push yourusername/empty-disk:10g
# 빌드한 이미지를 레지스트리에 업로드
▶️ 최적화 팁: "ContainerDisk 이미지 크기를 줄이려면 디스크 이미지를 압축하고 불필요한 데이터를 제거하세요. 예를 들어 qemu-img convert -O qcow2 -c source.qcow2 compressed.qcow2 명령으로 압축된 qcow2 이미지를 만들 수 있습니다."
📌 ContainerDisk로 VM 생성하기
이제 만든 ContainerDisk를 사용하여 VM을 생성해 보겠습니다.
✅ 기본 ContainerDisk VM 매니페스트
다음은 방금 만든 Ubuntu ContainerDisk를 사용하는 VM 매니페스트입니다:
apiVersion: kubevirt.io/v1 # KubeVirt API 버전
kind: VirtualMachine # 리소스 종류
metadata:
name: ubuntu-vm # VM 이름
spec:
running: true # 생성 즉시 VM 실행
template:
metadata:
labels:
kubevirt.io/vm: ubuntu-vm # VM 식별 레이블
spec:
domain: # VM 하드웨어 정의 시작
cpu:
cores: 2 # 2개 CPU 코어 할당
devices:
disks: # 디스크 장치 목록
- name: rootdisk # 루트 디스크 (OS 이미지)
disk:
bus: virtio # virtio 버스 사용 (성능 최적화)
- name: cloudinitdisk # cloud-init 설정 디스크
disk:
bus: virtio
interfaces: # 네트워크 인터페이스
- name: default
masquerade: {} # NAT 모드 네트워킹 (외부 통신 가능)
resources:
requests:
memory: 2Gi # 2GB 메모리 할당
networks: # 네트워크 정의
- name: default
pod: {} # 기본 Pod 네트워크 사용
volumes: # 볼륨 정의
- name: rootdisk # 루트 디스크 볼륨
containerDisk:
image: yourusername/ubuntu-container-disk:20.04 # 방금 만든 이미지
- name: cloudinitdisk # cloud-init 볼륨
cloudInitNoCloud: # cloud-init 구성 (NoCloud 방식)
userData: | # VM 초기 설정 데이터
#cloud-config
hostname: ubuntu-vm # 호스트명 설정
user: ubuntu # 사용자 생성
password: ubuntu # 비밀번호 설정
chpasswd: { expire: False } # 비밀번호 만료 비활성화
ssh_pwauth: True # SSH 비밀번호 인증 허용
✅ 읽기 전용 ContainerDisk와 쓰기 가능 PVC 조합
운영체제는 ContainerDisk로, 데이터는 PVC로 구성하는 일반적인 패턴입니다:
apiVersion: kubevirt.io/v1 # KubeVirt API 버전
kind: VirtualMachine # 리소스 종류
metadata:
name: ubuntu-with-data # VM 이름
spec:
running: true # 생성 즉시 VM 실행
template:
spec:
domain:
devices:
disks:
- name: rootdisk # 루트 디스크 (OS)
disk:
bus: virtio # virtio 버스 사용
- name: datadisk # 데이터 디스크 (영구 저장소)
disk:
bus: virtio
volumes:
- name: rootdisk
containerDisk:
image: yourusername/ubuntu-container-disk:20.04 # 읽기 전용 OS 이미지
# ContainerDisk는 불변이므로 OS 이미지에 적합
- name: datadisk
persistentVolumeClaim:
claimName: ubuntu-data-pvc # 쓰기 가능한 PVC 사용
# PVC는 상태를 유지하므로 데이터 저장에 적합
이 패턴에서:
- rootdisk: 읽기 전용 OS 이미지 (ContainerDisk)
- datadisk: 쓰기 가능한 데이터 스토리지 (PVC)
✅ 부팅 가능한 CD-ROM 이미지 사용
ISO 이미지를 사용하여 설치 미디어를 제공하는 방법:
apiVersion: kubevirt.io/v1 # KubeVirt API 버전
kind: VirtualMachine # 리소스 종류
metadata:
name: installer-vm # VM 이름
spec:
running: true # 생성 즉시 VM 실행
template:
spec:
domain:
devices:
disks:
- name: installer # 설치 미디어 디스크
cdrom: # CD-ROM으로 마운트 (부팅 가능)
bus: sata # SATA 버스 사용 (CD-ROM에 적합)
- name: harddrive # 설치 대상 하드 디스크
disk:
bus: virtio # virtio 버스 사용
volumes:
- name: installer
containerDisk:
image: quay.io/kubevirt/iso-installer:latest # ISO 이미지 컨테이너
# ISO 이미지가 CD-ROM으로 마운트됨
- name: harddrive
persistentVolumeClaim:
claimName: installation-target-pvc # 설치 대상 PVC
# OS가 설치될 영구 볼륨
이 예제에서는:
- ISO 이미지가 CD-ROM으로 마운트됨 (cdrom 설정)
- 설치 대상은 영구 볼륨 (harddrive)
▶️ VM 초기화 팁: "ContainerDisk와 cloud-init을 함께 사용하면 VM을 빠르게 초기화하고 사용자 지정할 수 있습니다. cloud-init으로 SSH 키, 네트워크 설정, 사용자 등을 구성하세요."
📌 PVC 기반 VM 루트 디스크 구성
지속적인 상태를 유지해야 하는 VM의 경우, 영구 볼륨 클레임(PVC)을 루트 디스크로 사용할 수 있습니다.
✅ VM용 PVC 생성
VM용 PVC를 직접 생성하는 방법:
# vm-rootdisk-pvc.yaml
apiVersion: v1 # 쿠버네티스 코어 API 버전
kind: PersistentVolumeClaim # PVC 리소스 정의
metadata:
name: vm-rootdisk # PVC 이름
spec:
accessModes:
- ReadWriteOnce # 접근 모드: 단일 노드에서 읽기/쓰기
# RWO: 하나의 노드만 읽기/쓰기 가능
# 대부분의 VM 디스크에 적합
resources:
requests:
storage: 10Gi # 요청 스토리지 용량: 10GB
storageClassName: standard # 스토리지 클래스 (클러스터에 맞게 조정)
# 클러스터 설정에 따라 다른 스토리지 클래스 사용 가능
# 예: aws-ebs, azurefile, local-path 등
# PVC 생성
$ kubectl apply -f vm-rootdisk-pvc.yaml
# PVC 매니페스트 적용
# PVC 상태 확인
$ kubectl get pvc vm-rootdisk
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
vm-rootdisk Bound pvc-a9d75bd5-2c0b-4b66-9f3b-4a4f4e79699b 10Gi RWO standard 5s
# STATUS가 Bound인지 확인
# Bound 상태는 PVC가 PV(PersistentVolume)에 연결되었음을 의미
✅ PVC를 사용하는 VM 생성
이제 생성한 PVC를 VM의 루트 디스크로 사용합니다:
# pvc-vm.yaml
apiVersion: kubevirt.io/v1 # KubeVirt API 버전
kind: VirtualMachine # 리소스 종류
metadata:
name: pvc-vm # VM 이름
spec:
running: true # 생성 즉시 VM 실행
template:
metadata:
labels:
kubevirt.io/vm: pvc-vm # VM 식별 레이블
spec:
domain:
devices:
disks:
- name: rootdisk # 루트 디스크
disk:
bus: virtio # virtio 버스 사용
- name: cloudinitdisk # cloud-init 디스크
disk:
bus: virtio
resources:
requests:
memory: 1Gi # 1GB 메모리 할당
volumes:
- name: rootdisk
persistentVolumeClaim:
claimName: vm-rootdisk # 앞서 생성한 PVC 사용
# PVC를 VM의 루트 디스크로 사용
- name: cloudinitdisk
cloudInitNoCloud:
userData: | # cloud-init 설정
#cloud-config
password: ubuntu # 사용자 비밀번호
chpasswd: { expire: False } # 비밀번호 만료 비활성화
하지만 이 VM은 아직 부팅할 수 없습니다. PVC에 부팅 가능한 OS가 설치되어 있지 않기 때문입니다.
✅ 설치 미디어로 OS 설치하기
PVC에 OS를 설치하기 위해 부팅 디스크와 설치 미디어를 함께 구성합니다:
# os-installer-vm.yaml
apiVersion: kubevirt.io/v1 # KubeVirt API 버전
kind: VirtualMachine # 리소스 종류
metadata:
name: os-installer # VM 이름
spec:
running: true # 생성 즉시 VM 실행
template:
spec:
domain:
devices:
disks:
- name: rootdisk # 대상 디스크 (OS 설치 대상)
disk:
bus: virtio # virtio 버스 사용
- name: installer # 설치 미디어 디스크
cdrom: # CD-ROM으로 마운트
bus: sata # SATA 버스 사용 (CD-ROM용)
resources:
requests:
memory: 2Gi # 2GB 메모리 할당 (설치에 충분한 메모리)
volumes:
- name: rootdisk
persistentVolumeClaim:
claimName: vm-rootdisk # 대상 PVC (여기에 OS 설치)
- name: installer
containerDisk:
image: quay.io/kubevirt/ubuntu-installer:20.04 # 설치 ISO 이미지
# ContainerDisk로 패키징된 Ubuntu 설치 ISO
이 방식은 수동 설치 과정이 필요합니다:
# VM 생성
$ kubectl apply -f os-installer-vm.yaml
# 설치용 VM 생성
# 콘솔에 접속하여 설치 진행
$ virtctl console os-installer
# 직렬 콘솔에 접속하여 텍스트 모드 설치 진행
# 또는 VNC로 접속 (그래픽 설치)
$ virtctl vnc os-installer
# 그래픽 설치 환경에 VNC로 접속
# 설치 마법사를 따라 OS를 PVC에 설치
▶️ PVC 활용 팁: "프로덕션 환경에서는 골든 이미지를 미리 만들어 놓고, 이를 복제하여 새 VM의 PVC를 초기화하는 것이 효율적입니다. 이를 위해 DataVolume과 KubeVirt CDI를 활용할 수 있습니다."
📌 DataVolume과 CDI 활용하기
DataVolume과 CDI(Containerized Data Importer)를 사용하면 VM 이미지 관리와 PVC 초기화 과정을 자동화할 수 있습니다.
✅ CDI 설치
먼저 CDI 컴포넌트를 클러스터에 설치합니다:
# 최신 CDI 버전 확인
$ CDI_VERSION=$(curl -s https://github.com/kubevirt/containerized-data-importer/releases/latest | grep -o "v[0-9]\.[0-9]*\.[0-9]*")
# GitHub API를 통해 최신 CDI 버전 확인
# CDI 설치
$ kubectl create -f https://github.com/kubevirt/containerized-data-importer/releases/download/$CDI_VERSION/cdi-operator.yaml
# CDI Operator 설치 (CRD 및 컨트롤러 배포)
$ kubectl create -f https://github.com/kubevirt/containerized-data-importer/releases/download/$CDI_VERSION/cdi-cr.yaml
# CDI 커스텀 리소스 생성 (CDI 인스턴스 배포)
# 설치 확인
$ kubectl get pods -n cdi
NAME READY STATUS RESTARTS AGE
cdi-apiserver-7f58b68b95-xl9bn 1/1 Running 0 2m
cdi-deployment-5d8f84756f-l6s7v 1/1 Running 0 2m
cdi-operator-7565c7f5d4-xz6zn 1/1 Running 0 3m
cdi-uploadproxy-6dd497b5b-fh2v8 1/1 Running 0 2m
# CDI 관련 모든 Pod가 Running 상태인지 확인
# 4개의 주요 컴포넌트: apiserver, deployment, operator, uploadproxy
✅ DataVolume 직접 생성
HTTP URL에서 이미지를 가져와 DataVolume을 생성하는 예:
# ubuntu-dv.yaml
apiVersion: cdi.kubevirt.io/v1beta1 # CDI API 버전
kind: DataVolume # DataVolume 리소스 정의
metadata:
name: ubuntu-dv # DataVolume 이름
spec:
source: # 소스 정의 (데이터 가져올 곳)
http: # HTTP 소스 지정
url: "https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img"
# Ubuntu 20.04 클라우드 이미지 URL
# CDI는 이 URL에서 이미지를 다운로드하여 PVC에 저장
pvc: # 생성할 PVC 명세
accessModes:
- ReadWriteOnce # 단일 노드 읽기/쓰기 접근
resources:
requests:
storage: 10Gi # 10GB 스토리지 요청
storageClassName: standard # 스토리지 클래스 지정
# DataVolume 생성
$ kubectl apply -f ubuntu-dv.yaml
# DataVolume 리소스 생성
# CDI 컨트롤러가 자동으로 이미지 다운로드 시작
# 진행 상황 모니터링
$ kubectl get datavolume ubuntu-dv
NAME PHASE PROGRESS RESTARTS AGE
ubuntu-dv ImportInProgress 20% 0 45s
# PHASE: 현재 단계 표시
# PROGRESS: 가져오기 진행률
# ImportInProgress → Succeeded로 변경되면 완료
CDI 컨트롤러는 자동으로:
- 지정된 URL에서 이미지를 다운로드
- 이미지를 PVC에 기록
- VM에서 사용할 수 있도록 준비
✅ DataVolume을 사용하는 VM 생성
DataVolume을 VM의 볼륨으로 직접 지정할 수 있습니다:
# datavolume-vm.yaml
apiVersion: kubevirt.io/v1 # KubeVirt API 버전
kind: VirtualMachine # 리소스 종류
metadata:
name: datavolume-vm # VM 이름
spec:
running: true # 생성 즉시 시작
template:
metadata:
labels:
kubevirt.io/vm: datavolume-vm # VM 식별 레이블
spec:
domain:
devices:
disks:
- name: rootdisk # 루트 디스크
disk:
bus: virtio # virtio 버스 사용
- name: cloudinitdisk # cloud-init 디스크
disk:
bus: virtio
resources:
requests:
memory: 2Gi # 2GB 메모리 할당
volumes:
- name: rootdisk
dataVolume:
name: ubuntu-dv # 기존 DataVolume 참조
# 이미 생성된 DataVolume을 VM의 디스크로 사용
- name: cloudinitdisk
cloudInitNoCloud: # cloud-init 설정
userData: |
#cloud-config
user: ubuntu # 사용자 이름
password: ubuntu # 비밀번호
chpasswd: { expire: False } # 비밀번호 만료 비활성화
✅ VM 정의에서 DataVolume 인라인 생성
VM 정의 내에서 DataVolume을 인라인으로 정의할 수도 있습니다:
# inline-datavolume-vm.yaml
apiVersion: kubevirt.io/v1 # KubeVirt API 버전
kind: VirtualMachine # 리소스 종류
metadata:
name: inline-datavolume-vm # VM 이름
spec:
running: true # 생성 즉시 시작
dataVolumeTemplates: # 인라인 DataVolume 템플릿 정의
- metadata:
name: inline-dv # 생성될 DataVolume 이름
spec:
source: # 소스 정의
http:
url: "https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img"
# Ubuntu 클라우드 이미지 URL
pvc: # PVC 스펙
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi # 10GB 스토리지
template:
spec:
domain:
devices:
disks:
- name: rootdisk
disk:
bus: virtio
resources:
requests:
memory: 2Gi
volumes:
- name: rootdisk
dataVolume:
name: inline-dv # 인라인 템플릿 참조
# dataVolumeTemplates에서 정의한 DataVolume 참조
이 방식은 VM 생성 과정을 자동화하여 한 단계로 처리합니다:
- 사용자가 VM을 생성
- DataVolume이 자동으로 생성되고 이미지 임포트
- 임포트가 완료되면 VM이 자동으로 시작
▶️ CDI 활용 사례: "CDI는 ISO 이미지, 클라우드 이미지, 레지스트리 이미지 등 다양한 소스에서 VM 이미지를 가져올 수 있습니다. 또한 이미지 클론, VM 스냅샷, PVC 복제 등 고급 데이터 관리 기능도 제공합니다."
📌 고급 이미지 관리 기법
마지막으로, 고급 이미지 관리 기법과 유용한 팁들을 알아보겠습니다.
✅ VM 이미지 변환 및 최적화
VM 이미지 형식을 변환하거나 최적화하는 방법:
# raw에서 qcow2로 변환
$ qemu-img convert -f raw -O qcow2 disk.raw disk.qcow2
# -f raw: 소스 이미지 형식 지정
# -O qcow2: 출력 이미지 형식 지정
# 원시 이미지를 공간 효율적인 qcow2로 변환
# 압축된 qcow2 이미지 생성
$ qemu-img convert -O qcow2 -c source.qcow2 compressed.qcow2
# -c: 압축 사용 (공간 절약)
# 기존 qcow2 이미지를 압축하여 크기 감소
# 이미지 크기 확인
$ qemu-img info disk.qcow2
# 이미지 정보 표시: 크기, 형식, 가상 크기, 실제 크기 등
# 이미지 크기 조정
$ qemu-img resize disk.qcow2 +10G
# 기존 디스크 이미지 크기를 10GB 증가
# 참고: 파일 시스템은 VM 내부에서 별도로 확장해야 함
✅ 기존 VM에서 이미지 만들기
기존 VM을 골든 이미지로 만드는 과정:
- VM 종료:
$ virtctl stop my-vm
# 이미지 생성을 위해 VM 중지 (데이터 일관성 보장)
- PVC 스냅샷 생성:
# vm-snapshot.yaml
apiVersion: snapshot.storage.k8s.io/v1 # 스냅샷 API 버전
kind: VolumeSnapshot # 볼륨 스냅샷 리소스
metadata:
name: my-vm-rootdisk-snapshot # 스냅샷 이름
spec:
volumeSnapshotClassName: csi-hostpath-snapclass # 스냅샷 클래스
# 사용 가능한 스냅샷 클래스는 클러스터 설정에 따라 다름
source:
persistentVolumeClaimName: my-vm-rootdisk # 스냅샷 대상 PVC
# 스냅샷을 생성할 VM 디스크 PVC
- 스냅샷에서 새 PVC 생성:
# golden-image-pvc.yaml
apiVersion: v1 # 쿠버네티스 API 버전
kind: PersistentVolumeClaim # PVC 리소스
metadata:
name: golden-image # 골든 이미지 PVC 이름
spec:
dataSource: # 데이터 소스 정의
name: my-vm-rootdisk-snapshot # 소스 스냅샷 이름
kind: VolumeSnapshot # 소스 종류: 볼륨 스냅샷
apiGroup: snapshot.storage.k8s.io # 스냅샷 API 그룹
accessModes:
- ReadWriteOnce # 접근 모드
resources:
requests:
storage: 10Gi # 스토리지 크기
# 스냅샷을 기반으로 새 PVC 생성 (빠른 복제)
✅ DataVolume 복제 및 클론
DataVolume을 사용하여 기존 PVC를 복제하는 방법:
# clone-datavolume.yaml
apiVersion: cdi.kubevirt.io/v1beta1 # CDI API 버전
kind: DataVolume # DataVolume 리소스
metadata:
name: cloned-dv # 복제본 이름
spec:
source:
pvc: # PVC 소스 지정
namespace: default # 소스 PVC 네임스페이스
name: golden-image # 소스 PVC 이름 (골든 이미지)
pvc:
accessModes:
- ReadWriteOnce # 접근 모드
resources:
requests:
storage: 10Gi # 스토리지 크기
# 기존 PVC를 복제하여 새 DataVolume 생성
# CDI가 효율적인 복제 수행 (가능한 경우 스냅샷 활용)
✅ 이미지 업로드 기능 활용
로컬 이미지를 직접 클러스터에 업로드할 수 있는 방법:
# 업로드 프록시 포트포워딩
$ kubectl port-forward -n cdi service/cdi-uploadproxy 8443:443
# CDI 업로드 프록시 서비스에 로컬 포트 연결
# 이렇게 하면 로컬 시스템에서 8443 포트로 업로드 가능
# 이미지 업로드
$ virtctl image-upload dv new-vm-disk \
--size=10Gi \
--image-path=/path/to/local/disk.qcow2 \
--insecure
# virtctl 도구를 사용하여 로컬 이미지 업로드
# --size: 생성할 DataVolume 크기
# --image-path: 로컬 디스크 이미지 경로
# --insecure: 인증서 검증 무시 (테스트 환경용)
▶️ 팁: "프로덕션 환경에서는 골든 이미지 접근 방식을 사용하세요. 미리 설정된 OS, 보안 패치, 기본 소프트웨어가 설치된 이미지를 준비하고, DataVolume 클론 기능으로 새 VM을 빠르게 프로비저닝할 수 있습니다."
📌 Summary
이 글에서는 KubeVirt에서 VM 이미지를 다루는 다양한 방법을 알아보았습니다:
- ContainerDisk: VM 디스크 이미지를 컨테이너로 패키징하여 불변 OS 이미지 제공
- Docker로 ContainerDisk 생성: qcow2 이미지를 컨테이너 이미지로 변환하는 방법
- PVC 기반 VM 디스크: 상태를 유지해야 하는 VM을 위한 영구 스토리지 구성
- DataVolume과 CDI: URL, 레지스트리, 기존 PVC 등에서 VM 이미지를 자동으로 가져오기
- 고급 이미지 관리: 이미지 변환, 골든 이미지 생성, 복제, 업로드 등의 기법
이러한 방법을 조합하여 효율적인 VM 이미지 관리 전략을 구축할 수 있습니다. 불변 OS 이미지는 ContainerDisk로, 데이터는 PVC로, 이미지 관리 자동화는 CDI로 처리하는 것이 일반적인 패턴입니다.
'Kubernetes Tools > Kubevirt' 카테고리의 다른 글
[KubeVirt Ep.7] 🚀 기본 네트워크 설정 | VM에서 외부로 나가기 (0) | 2025.03.21 |
---|---|
[KubeVirt Ep.6] 🚀 VM의 스토리지 설정 | ephemeral vs persistent (0) | 2025.03.21 |
[KubeVirt Ep.4] 🚀 VirtualMachine 리소스 실습 | 나만의 VM 만들기 (0) | 2025.03.21 |
[KubeVirt Ep.3] 🚀 kubevirt 설치하기 | Docker Desktop으로 실습 환경 구성 (0) | 2025.03.21 |
[KubeVirt Ep.2] 🚀 kubevirt 아키텍처 이해하기 | 주요 구성요소와 동작 흐름 (0) | 2025.03.21 |