Kubernetes Tools/Kubevirt

[KubeVirt Ep.6] 🚀 VM의 스토리지 설정 | ephemeral vs persistent

ygtoken 2025. 3. 21. 13:56
728x90

이 글에서는 KubeVirt에서 VM의 스토리지를 구성하는 다양한 방법에 대해 살펴보겠습니다. 임시(ephemeral) 디스크와 영구(persistent) 디스크의 차이점, 각 스토리지 유형의 장단점, 그리고 실제 운영체제 설치와 디스크 관리 방법을 실습을 통해 알아보겠습니다.


📌 VM 스토리지 기본 개념

KubeVirt에서 VM 스토리지를 이해하기 위해서는 몇 가지 기본 개념을 알아야 합니다.

 

디스크와 볼륨의 관계

 

디스크와 볼륨의 관계

KubeVirt에서 VM 스토리지는 크게 두 부분으로 구성됩니다:

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: example-vm
spec:
  template:
    spec:
      domain:
        devices:
          disks:              # 디스크 정의 부분 - VM 내부에 보이는 장치
          - name: rootdisk    # 디스크 이름 (volumes의 이름과 일치해야 함)
            disk:             # 디스크 유형 (disk, cdrom, lun 등)
              bus: virtio     # 디스크 버스 유형 (virtio, sata, scsi 등)
      volumes:                # 볼륨 정의 부분 - 실제 스토리지 구현
      - name: rootdisk        # 볼륨 이름 (disks의 이름과 일치해야 함)
        persistentVolumeClaim:  # 볼륨 유형 (PVC, containerDisk, emptyDisk 등)
          claimName: my-vm-disk  # 볼륨 유형별 설정

디스크(disks): VM 내부에서 보이는 블록 장치를 정의합니다. 디스크 이름, 유형(disk, cdrom 등), 버스 유형(virtio, sata 등)을 지정합니다.

볼륨(volumes): 실제 스토리지 구현 방식을 정의합니다. PVC, containerDisk, emptyDisk 등 다양한 유형이 있으며, 디스크와 볼륨은 이름으로 연결됩니다.

 

VM 디스크 타입

VM 내부에서 볼 수 있는 디스크 장치 유형:

disks:
- name: rootdisk
  disk: {}         # 일반 디스크 (읽기/쓰기 가능)
  
- name: installdisk
  cdrom: {}        # CD-ROM 디스크 (읽기 전용)
  
- name: datastorage
  lun: {}          # LUN 디스크 (직접 패스스루)
  • disk: 일반적인 읽기/쓰기 가능 디스크
  • cdrom: 읽기 전용 CD-ROM 장치 (주로 설치 미디어용)
  • lun: SCSI LUN을 직접 패스스루 (특수 스토리지용)

디스크 버스 유형

VM에서 디스크를 어떤 버스를 통해 연결할지 정의합니다:

disks:
- name: rootdisk
  disk:
    bus: virtio    # virtio 버스 (반가상화, 높은 성능)
    
- name: datastorage
  disk:
    bus: sata      # SATA 버스 (넓은 호환성)
    
- name: legacydisk
  disk:
    bus: ide       # IDE 버스 (레거시 호환성)
  • virtio: 가장 성능이 좋은 반가상화 버스, 최신 OS에 권장
  • sata: 대부분의 OS와 호환성이 좋은 버스
  • scsi: 고급 스토리지 기능 지원
  • ide: 오래된 OS 지원을 위한 레거시 버스

볼륨 타입: ephemeral vs persistent

KubeVirt에서는 크게 두 가지 종류의 볼륨이 있습니다:

  1. 임시(ephemeral) 볼륨: VM이 재시작되면 데이터가 손실됨
    • containerDisk: 컨테이너 이미지에서 제공되는 읽기 전용 디스크
    • emptyDisk: 빈 임시 디스크 (VM 실행 중에만 유지)
    • cloudInitNoCloud: 초기 설정을 위한 임시 디스크
  2. 영구(persistent) 볼륨: VM이 재시작되어도 데이터가 유지됨
    • persistentVolumeClaim: 쿠버네티스 PVC 기반 볼륨
    • dataVolume: CDI를 통해 관리되는 PVC

▶️ 스토리지 선택 가이드: "OS 이미지는 불변성을 위해 ContainerDisk를, 데이터는 지속성을 위해 PVC를, 임시 데이터는 효율성을 위해 emptyDisk를 사용하는 것이 좋은 조합입니다."


📌 Ephemeral 디스크 상세 설명

임시(ephemeral) 디스크는 VM 라이프사이클에 종속된 일시적인 스토리지입니다. VM이 삭제되거나 재시작되면 데이터가 손실되지만, 빠른 프로비저닝과 리소스 효율성이 장점입니다.

 

ContainerDisk

ContainerDisk는 컨테이너 이미지로 패키징된 VM 디스크 이미지를 제공합니다:

volumes:
- name: rootdisk
  containerDisk:
    image: quay.io/kubevirt/fedora-container-disk-demo:latest  # 컨테이너 이미지
    path: /disk/fedora.qcow2                                   # 이미지 내부 경로 (선택적)
    imagePullPolicy: IfNotPresent                              # 이미지 풀 정책

 

특징:

  • 읽기 전용 (불변)
  • 컨테이너 레지스트리를 통한 배포
  • OS 이미지 배포에 이상적
  • 변경사항은 VM 재시작 시 사라짐

사용 사례:

  • 기본 OS 이미지 제공
  • 템플릿 기반 VM 배포
  • CI/CD 환경의 테스트 VM

EmptyDisk

EmptyDisk는 VM 시작 시 생성되는 빈 임시 디스크입니다:

volumes:
- name: scratchdisk
  emptyDisk:
    capacity: "10Gi"      # 디스크 용량

특징:

  • VM 시작 시 생성되고 종료 시 삭제됨
  • 빠른 프로비저닝 (스토리지 클래스 불필요)
  • 호스트 노드의 로컬 스토리지 사용
  • 용량 지정 필요

사용 사례:

  • 스크래치 공간
  • 임시 데이터 처리
  • 캐시 저장소
  • 단기 분석 작업

CloudInitNoCloud

CloudInitNoCloud는 VM 초기화를 위한 cloud-init 구성을 제공하는 임시 디스크입니다:

volumes:
- name: cloudinitdisk
  cloudInitNoCloud:
    userData: |          # cloud-init 사용자 데이터
      #cloud-config
      hostname: testvm
      user: fedora
      password: fedora
      chpasswd: { expire: False }
    networkData: |       # 네트워크 구성 (선택적)
      version: 2
      ethernets:
        eth0:
          dhcp4: true

 

특징:

  • VM 초기 설정을 위한 메커니즘
  • 사용자, 네트워크, 스크립트 등 설정 가능
  • VM 부팅 시에만 사용됨
  • 읽기 전용

사용 사례:

  • VM 초기 사용자 설정
  • 호스트명 및 네트워크 구성
  • 부팅 스크립트 실행
  • SSH 키 배포

▶️ Ephemeral 디스크 활용 팁: "다중 ContainerDisk를 사용하여 OS 이미지와 설치 미디어를 함께 제공하고, EmptyDisk를 추가하여 임시 작업 공간을 제공하는 조합이 개발 및 테스트 환경에서 효율적입니다."


📌 EmptyDisk 실습

먼저 EmptyDisk를 사용하여 임시 작업 공간이 있는 VM을 생성해 보겠습니다.

 

EmptyDisk VM 매니페스트 작성

emptydisk-vm.yaml 파일을 다음과 같이 작성합니다:

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: emptydisk-vm
spec:
  running: true
  template:
    metadata:
      labels:
        kubevirt.io/vm: emptydisk-vm
    spec:
      domain:
        devices:
          disks:
          - name: rootdisk          # 루트 디스크 (OS)
            disk:
              bus: virtio
          - name: scratchdisk       # 임시 작업용 디스크
            disk:
              bus: virtio
          interfaces:
          - name: default
            masquerade: {}
        resources:
          requests:
            memory: 1Gi
      networks:
      - name: default
        pod: {}
      volumes:
      - name: rootdisk
        containerDisk:              # OS 이미지 (읽기 전용)
          image: quay.io/kubevirt/fedora-container-disk-demo:latest
      - name: scratchdisk
        emptyDisk:                  # 임시 디스크 (읽기/쓰기)
          capacity: "10Gi"          # 10GB 용량

이 VM은 ContainerDisk로 OS를 제공하고, EmptyDisk로 10GB의 추가 임시 디스크를 제공합니다.

 

VM 생성 및 접속

# VM 생성
$ kubectl apply -f emptydisk-vm.yaml
virtualmachine.kubevirt.io/emptydisk-vm created

# VM 상태 확인
$ kubectl get vm emptydisk-vm
NAME           AGE    STATUS    READY
emptydisk-vm   10s    Running   True

# VM 콘솔 접속
$ virtctl console emptydisk-vm

# 로그인 (Fedora 기본 계정)
emptydisk-vm login: fedora
Password: fedora

 

VM 내에서 EmptyDisk 확인 및 사용

VM에 접속한 후, EmptyDisk가 정상적으로 연결되었는지 확인합니다:

# 디스크 확인
$ lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
vda    252:0    0    5G  0 disk 
├─vda1 252:1    0  200M  0 part /boot/efi
└─vda2 252:2    0  4.8G  0 part /
vdb    252:16   0   10G  0 disk  # 이것이 EmptyDisk

# EmptyDisk 포맷 및 마운트
$ sudo mkfs.ext4 /dev/vdb
mke2fs 1.45.6 (20-Mar-2020)
Creating filesystem with 2621440 4k blocks and 655360 inodes
...

$ sudo mkdir -p /mnt/scratch
$ sudo mount /dev/vdb /mnt/scratch
$ df -h /mnt/scratch
Filesystem      Size  Used Avail Use% Mounted on
/dev/vdb        9.8G   37M  9.3G   1% /mnt/scratch

# 테스트 파일 생성
$ sudo dd if=/dev/zero of=/mnt/scratch/testfile bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes (1.0 GB, 1000 MiB) copied, 1.92426 s, 545 MB/s

 

VM 재시작 후 데이터 지속성 확인

EmptyDisk의 임시적 특성을 확인하기 위해 VM을 재시작합니다:

# VM 재시작
$ virtctl restart emptydisk-vm
VM emptydisk-vm was scheduled to restart

# VM 상태 확인
$ kubectl get vm emptydisk-vm
NAME           AGE    STATUS    READY
emptydisk-vm   5m     Running   True

# VM 콘솔 접속
$ virtctl console emptydisk-vm
# 로그인

# 이전에 마운트한 디스크 확인
$ lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
vda    252:0    0    5G  0 disk 
├─vda1 252:1    0  200M  0 part /boot/efi
└─vda2 252:2    0  4.8G  0 part /
vdb    252:16   0   10G  0 disk  # EmptyDisk가 여전히 있음

# 하지만 내용은 초기화됨 (다시 포맷 필요)
$ sudo mount /dev/vdb /mnt/scratch
mount: /mnt/scratch: wrong fs type, bad option, bad superblock on /dev/vdb, missing codepage or helper program, or other error.

재시작 후 EmptyDisk 자체는 다시 생성되지만, 이전에 저장한 데이터는 손실됩니다. 이것이 임시(ephemeral) 디스크의 특성입니다.

 

▶️ EmptyDisk 활용 팁: "EmptyDisk는 VM의 일시적인 작업 공간으로 적합합니다. 성능이 중요하고 지속성이 필요 없는 경우 사용하세요. 자동화 스크립트를 통해 VM 시작 시 매번 디스크를 포맷하고 마운트하는 것이 좋습니다."


📌 Persistent 디스크 상세 설명

영구(persistent) 디스크는 VM 재시작이나 삭제 후에도 데이터가 유지되는 스토리지입니다. 쿠버네티스의 영구 볼륨 시스템을 활용하여 안정적인 데이터 저장을 제공합니다.

 

PersistentVolumeClaim (PVC)

PVC는 쿠버네티스의 기본 영구 스토리지를 VM 디스크로 사용합니다:

volumes:
- name: datadisk
  persistentVolumeClaim:
    claimName: my-vm-disk    # 기존 PVC 이름
    readOnly: false          # 읽기/쓰기 모드 (기본값: false)

 

특징:

  • VM 라이프사이클과 독립적인 데이터 유지
  • 쿠버네티스 스토리지 클래스 활용
  • 읽기/쓰기 모드 지원
  • 다양한 백엔드 스토리지 지원 (NFS, AWS EBS, Ceph 등)

사용 사례:

  • 데이터베이스 스토리지
  • 사용자 데이터 저장
  • 애플리케이션 설정 및 로그
  • 장기 데이터 보존

DataVolume

DataVolume은 CDI(Containerized Data Importer)를 통해 PVC를 자동으로 프로비저닝하고 초기화하는 방법입니다:

volumes:
- name: rootdisk
  dataVolume:
    name: vm-datavolume     # DataVolume 이름

 

이 방식은 다음과 같이 DataVolume 리소스를 미리 정의하거나:

apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
  name: vm-datavolume
spec:
  source:
    http:                  # 소스 유형 (http, registry, pvc 등)
      url: "http://example.com/disk.img"  # 이미지 URL
  pvc:
    accessModes:
      - ReadWriteOnce
    resources:
      requests:
        storage: 10Gi
    storageClassName: standard  # 스토리지 클래스

 

또는 VM 정의에 인라인으로 포함시킬 수 있습니다:

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: datavolume-vm
spec:
  dataVolumeTemplates:     # 인라인 DataVolume 정의
  - metadata:
      name: vm-datavolume
    spec:
      source:
        http:
          url: "http://example.com/disk.img"
      pvc:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 10Gi
  # ... VM 설정 ...

 

특징:

  • 이미지 자동 가져오기 및 변환
  • PVC 라이프사이클 자동화
  • VM 배포 프로세스 통합
  • 다양한 소스 지원 (HTTP, Registry, 기존 PVC 등)

사용 사례:

  • OS 이미지 자동 프로비저닝
  • 골든 이미지 기반 VM 배포
  • VM 템플릿 시스템
  • 클라우드 이미지 직접 가져오기

HostDisk

HostDisk는 노드의 로컬 파일시스템을 VM 디스크로 사용합니다(개발/테스트용으로만 권장):

volumes:
- name: hostdisk
  hostDisk:
    path: /data/vm-disk.img    # 호스트 경로
    type: DiskOrCreate         # 디스크 생성 유형
    capacity: 10Gi             # 용량 (type이 DiskOrCreate인 경우 필요)

 

type 값:

  • Disk: 호스트의 기존 디스크 파일 사용
  • DiskOrCreate: 경로에 디스크가 없으면 생성
  • Directory: 호스트의 디렉토리를 디스크로 사용

특징:

  • 호스트 노드에 직접 접근
  • 노드 간 데이터 이동 불가
  • VM 스케줄링 제약 발생
  • 개발 및 테스트 환경에 적합

사용 사례:

  • 개발 환경
  • 노드 로컬 데이터 접근
  • 고성능 로컬 스토리지 필요 시
  • 특수 테스트 시나리오

▶️ Persistent 디스크 선택 가이드: "일반적인 프로덕션 환경에서는 PVC를 기반으로 한 DataVolume을 사용하는 것이 권장됩니다. 이는 쿠버네티스 스토리지 시스템과 완전히 통합되고, 이미지 관리 워크플로우를 자동화할 수 있습니다."


📌 PVC 기반 VM 실습

이제 영구 스토리지를 사용하는 VM을 만들어 보겠습니다.

 

PVC 생성

먼저 VM에서 사용할 PVC를 생성합니다:

# vm-persistent-disk.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: vm-persistent-disk
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: standard  # 환경에 맞는 스토리지 클래스 사용
# PVC 생성
$ kubectl apply -f vm-persistent-disk.yaml
persistentvolumeclaim/vm-persistent-disk created

# PVC 상태 확인
$ kubectl get pvc vm-persistent-disk
NAME                 STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
vm-persistent-disk   Bound    pvc-a1b2c3d4-e5f6-7890-a1b2-c3d4e5f67890   10Gi       RWO            standard       10s

 

PVC를 사용하는 VM 생성

다음은 ContainerDisk로 OS를 제공하고, 생성한 PVC를 데이터 디스크로 사용하는 VM 매니페스트입니다:

# pvc-vm.yaml
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: pvc-vm
spec:
  running: true
  template:
    metadata:
      labels:
        kubevirt.io/vm: pvc-vm
    spec:
      domain:
        devices:
          disks:
          - name: rootdisk          # 루트 디스크 (OS)
            disk:
              bus: virtio
          - name: datadisk          # 데이터 디스크 (영구 저장소)
            disk:
              bus: virtio
          interfaces:
          - name: default
            masquerade: {}
        resources:
          requests:
            memory: 1Gi
      networks:
      - name: default
        pod: {}
      volumes:
      - name: rootdisk
        containerDisk:              # OS 이미지 (읽기 전용)
          image: quay.io/kubevirt/fedora-container-disk-demo:latest
      - name: datadisk
        persistentVolumeClaim:      # 영구 데이터 디스크
          claimName: vm-persistent-disk
# VM 생성
$ kubectl apply -f pvc-vm.yaml
virtualmachine.kubevirt.io/pvc-vm created

# VM 상태 확인
$ kubectl get vm pvc-vm
NAME     AGE   STATUS    READY
pvc-vm   10s   Running   True

# VM 콘솔 접속
$ virtctl console pvc-vm

# 로그인 (Fedora 기본 계정)
pvc-vm login: fedora
Password: fedora

 

VM 내에서 PVC 디스크 확인 및 사용

VM에 접속한 후, PVC가 정상적으로 연결되었는지 확인합니다:

# 디스크 확인
$ lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
vda    252:0    0    5G  0 disk 
├─vda1 252:1    0  200M  0 part /boot/efi
└─vda2 252:2    0  4.8G  0 part /
vdb    252:16   0   10G  0 disk  # 이것이 PVC 디스크

# PVC 디스크 포맷 및 마운트
$ sudo mkfs.ext4 /dev/vdb
mke2fs 1.45.6 (20-Mar-2020)
Creating filesystem with 2621440 4k blocks and 655360 inodes
...

$ sudo mkdir -p /mnt/data
$ sudo mount /dev/vdb /mnt/data
$ df -h /mnt/data
Filesystem      Size  Used Avail Use% Mounted on
/dev/vdb        9.8G   37M  9.3G   1% /mnt/data

# 테스트 파일 생성
$ sudo dd if=/dev/zero of=/mnt/data/testfile bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes (1.0 GB, 1000 MiB) copied, 2.15426 s, 486 MB/s

# 장치를 향후 재부팅 시 자동 마운트하도록 설정
$ sudo bash -c 'echo "/dev/vdb /mnt/data ext4 defaults 0 0" >> /etc/fstab'

 

VM 재시작 후 데이터 지속성 확인

PVC의 영구적 특성을 확인하기 위해 VM을 재시작합니다:

# VM 재시작
$ virtctl restart pvc-vm
VM pvc-vm was scheduled to restart

# VM 상태 확인
$ kubectl get vm pvc-vm
NAME     AGE     STATUS    READY
pvc-vm   10m     Running   True

# VM 콘솔 접속
$ virtctl console pvc-vm
# 로그인

# 자동 마운트 확인 (fstab에 추가한 경우)
$ df -h /mnt/data
Filesystem      Size  Used Avail Use% Mounted on
/dev/vdb        9.8G  1.1G  8.3G   11% /mnt/data

# 이전에 생성한 파일 확인
$ ls -lh /mnt/data/
total 1000M
-rw-r--r--. 1 root root 1000M May 20 13:45 testfile

재시작 후에도 PVC 디스크의 데이터가 그대로 유지됨을 확인할 수 있습니다.

▶️ 영구 디스크 활용 팁: "프로덕션 환경에서는 중요 데이터를 위해 항상 PVC를 사용하고, /etc/fstab에 마운트 설정을 추가하여 자동 마운트되도록 하는 것이 좋습니다. 또한 정기적인 백업 전략을 함께 구현하는 것이 중요합니다."


📌 실제 OS 설치용 Persistent 디스크 구성

지금까지는 미리 준비된 ContainerDisk OS 이미지를 사용했지만, 실제 프로덕션 환경에서는 직접 OS를 설치해야 하는 경우가 많습니다. 이제 PVC에 직접 OS를 설치하는 방법을 알아보겠습니다.

 

설치 대상 PVC 생성

먼저 OS를 설치할 PVC를 생성합니다:

# os-install-target.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: os-install-target
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi  # OS 설치에 충분한 공간
  storageClassName: standard
# PVC 생성
$ kubectl apply -f os-install-target.yaml
persistentvolumeclaim/os-install-target created

 

설치 미디어 준비

OS 설치를 위해 설치 ISO를 ContainerDisk로 만들거나, 이미 준비된 것을 사용할 수 있습니다. 여기서는 이미 준비된 ContainerDisk를 사용하겠습니다(예: Ubuntu Server ISO).

 

OS 설치 VM 생성

설치 ISO를 CD-ROM으로 마운트하고, 설치 대상 PVC를 디스크로 연결하는 VM을 생성합니다:

# os-installer-vm.yaml
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: os-installer
spec:
  running: true
  template:
    metadata:
      labels:
        kubevirt.io/vm: os-installer
    spec:
      domain:
        devices:
          disks:
          - name: installdisk      # 설치 미디어
            cdrom:                 # CD-ROM으로 마운트 (ISO)
              bus: sata
          - name: harddisk         # 설치 대상 디스크
            disk:
              bus: virtio
          interfaces:
          - name: default
            masquerade: {}
        resources:
          requests:
            memory: 2Gi            # 설치에 충분한 메모리
      networks:
      - name: default
        pod: {}
      volumes:
      - name: installdisk
        containerDisk:             # Ubuntu 설치 ISO
          image: quay.io/kubevirt/ubuntu-installer:20.04
      - name: harddisk
        persistentVolumeClaim:     # 설치 대상 PVC
          claimName: os-install-target
# 설치 VM 생성
$ kubectl apply -f os-installer-vm.yaml
virtualmachine.kubevirt.io/os-installer created

# VM 상태 확인
$ kubectl get vm os-installer
NAME           AGE   STATUS    READY
os-installer   10s   Running   True

 

그래픽 콘솔로 OS 설치

대부분의 OS 설치는 그래픽 인터페이스를 통해 더 쉽게 진행할 수 있습니다. VNC를 통해 VM에 접속합니다:

# VNC 콘솔 접속
$ virtctl vnc os-installer

VNC 클라이언트가 열리고 OS 설치 화면이 표시됩니다. 일반적인 OS 설치 과정을 따라 PVC에 OS를 설치합니다:

  1. 언어, 지역, 키보드 레이아웃 등 기본 설정
  2. 디스크 파티셔닝 - /dev/vdb(또는 유사한 장치)를 설치 대상으로
  3. 사용자 계정 설정
  4. 패키지 선택 및 설치
  5. 설치 완료 및 재부팅

설치 완료 후 CD-ROM 제거

OS 설치가 완료되면, 설치 미디어(CD-ROM)를 제거하고 PVC에서 부팅하도록 VM을 수정합니다:

# os-vm.yaml (설치 후 VM)
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: os-vm
spec:
  running: true
  template:
    metadata:
      labels:
        kubevirt.io/vm: os-vm
    spec:
      domain:
        devices:
          disks:
          - name: harddisk         # OS가 설치된 디스크
            disk:
              bus: virtio
          interfaces:
          - name: default
            masquerade: {}
        resources:
          requests:
            memory: 2Gi
      networks:
      - name: default
        pod: {}
      volumes:
      - name: harddisk
        persistentVolumeClaim:     # OS가 설치된 PVC
          claimName: os-install-target
# 먼저 설치 VM 중지
$ virtctl stop os-installer
VM os-installer was scheduled to stop

# 새 VM 생성
$ kubectl apply -f os-vm.yaml
virtualmachine.kubevirt.io/os-vm created

# VM 상태 확인
$ kubectl get vm os-vm
NAME    AGE   STATUS    READY
os-vm   10s   Running   True

# 콘솔 접속
$ virtctl console os-vm

이제 PVC에 설치된 OS로 부팅된 VM이 실행됩니다. 이 VM은 영구 디스크에서 실행되므로 재시작해도 모든 데이터와 설정이 유지됩니다.

▶️ OS 설치 팁: "프로덕션 환경에서는 OS를 직접 설치하기보다 미리 구성된 골든 이미지를 사용하는 것이 더 효율적입니다. DataVolume을 통해 골든 이미지를 PVC로 가져오거나, Kubevirt CDI의 클론 기능을 사용하여 이미 설치된 OS의 PVC를 복제하는 것이 좋습니다."


📌 디스크 추가 및 확장 방법

VM에 디스크를 추가하거나 기존 디스크를 확장하는 방법을 알아보겠습니다.

 

VM에 추가 디스크 연결

VM이 실행 중인 상태에서 새 디스크를 추가하려면:

  1. 새 PVC 생성:
# additional-disk.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: additional-disk
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: standard
$ kubectl apply -f additional-disk.yaml
persistentvolumeclaim/additional-disk created
  1. VM 정의 수정 (디스크 및 볼륨 추가):
$ kubectl edit vm pvc-vm

 

spec.template.spec.domain.devices.disks 섹션에 새 디스크 추가:

disks:
- name: rootdisk
  disk:
    bus: virtio
- name: datadisk
  disk:
    bus: virtio
- name: additionaldisk  # 새 디스크 추가
  disk:
    bus: virtio

 

spec.template.spec.volumes 섹션에 새 볼륨 추가:

volumes:
- name: rootdisk
  containerDisk:
    image: quay.io/kubevirt/fedora-container-disk-demo:latest
- name: datadisk
  persistentVolumeClaim:
    claimName: vm-persistent-disk
- name: additionaldisk  # 새 볼륨 추가
  persistentVolumeClaim:
    claimName: additional-disk
  1. VM 재시작 및 확인:
$ virtctl restart pvc-vm
VM pvc-vm was scheduled to restart

# VM 콘솔 접속
$ virtctl console pvc-vm
# 로그인

# 디스크 확인
$ lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
vda    252:0    0    5G  0 disk 
├─vda1 252:1    0  200M  0 part /boot/efi
└─vda2 252:2    0  4.8G  0 part /
vdb    252:16   0   10G  0 disk  /mnt/data
vdc    252:32   0    5G  0 disk  # 새 디스크

 

PVC 디스크 크기 확장

쿠버네티스 1.11 이상에서는 PVC 크기 확장이 지원됩니다 (스토리지 클래스에 allowVolumeExpansion: true 설정 필요):

  1. PVC 크기 확장:
$ kubectl edit pvc vm-persistent-disk

spec.resources.requests.storage 값을 수정 (예: 10Gi에서 20Gi로):

spec:
  resources:
    requests:
      storage: 20Gi  # 크기 증가
  1. PVC 상태 확인:
$ kubectl get pvc vm-persistent-disk
NAME                 STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
vm-persistent-disk   Bound    pvc-a1b2c3d4-e5f6-7890-a1b2-c3d4e5f67890   20Gi       RWO            standard       2h
  1. VM 내부에서 파일시스템 확장:

VM을 재시작할 필요는 없지만, 파일시스템을 확장해야 합니다:

# VM 콘솔 접속
$ virtctl console pvc-vm
# 로그인

# 디스크 크기 확인
$ lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
vda    252:0    0    5G  0 disk 
├─vda1 252:1    0  200M  0 part /boot/efi
└─vda2 252:2    0  4.8G  0 part /
vdb    252:16   0   20G  0 disk  /mnt/data  # 크기가 20G로 증가
vdc    252:32   0    5G  0 disk

# 파일시스템 확장 (마운트 해제 필요 없음)
$ sudo resize2fs /dev/vdb
resize2fs 1.45.6 (20-Mar-2020)
Filesystem at /dev/vdb is mounted on /mnt/data; on-line resizing required
old_desc_blocks = 2, new_desc_blocks = 3
The filesystem on /dev/vdb is now 5242880 (4k) blocks long.

# 새 크기 확인
$ df -h /mnt/data
Filesystem      Size  Used Avail Use% Mounted on
/dev/vdb         20G  1.1G   18G   6% /mnt/data

▶️ 디스크 관리 팁: "VM의 디스크 구성을 변경하기 전에 항상 중요 데이터를 백업하세요. 특히 디스크 확장은 스토리지 시스템에 따라 지원 여부가 다를 수 있으므로, 사전에 스토리지 클래스의 allowVolumeExpansion 설정을 확인하는 것이 중요합니다."


📌 Summary

이 글에서는 KubeVirt에서 VM 스토리지 구성에 대해 다양한 측면을 살펴보았습니다:

  • 디스크와 볼륨의 관계: VM에서는 디스크가 장치를, 볼륨이 실제 구현을 정의합니다.
  • Ephemeral 디스크: ContainerDisk, EmptyDisk, CloudInitNoCloud 등의 임시 스토리지 옵션을 통해 빠른 프로비저닝과 효율적인 리소스 사용이 가능합니다.
  • Persistent 디스크: PVC, DataVolume, HostDisk 등의 영구 스토리지 옵션을 통해 데이터 지속성과 신뢰성을 확보할 수 있습니다.
  • 실제 OS 설치: PVC에 직접 OS를 설치하고 부팅하는 방법을 알아보았습니다.
  • 디스크 관리: VM에 추가 디스크를 연결하거나 기존 디스크를 확장하는 방법을 실습했습니다.

VM 워크로드에 적합한 스토리지 구성을 선택하는 것은 성능, 신뢰성, 관리 용이성의 균형을 고려해야 합니다. 프로덕션 환경에서는 대부분 영구 스토리지를 기반으로 하되, 필요에 따라 임시 스토리지를 조합하여 사용하는 전략이 효과적입니다.

728x90