TT Lab
요금제

한국어

시작하기
블로그

블로그

학생 VM 이 뜨기까지 3: 디스크는 PVC 다 — DataVolume, 접근 모드, 볼륨 모드

상태: 초안 (2026-10-16), 공식 문서 + 일부 실측. KubeVirt·CDI·쿠버네티스 문서를 2026-10-16 에 열어 확인했습니다 (KubeVirt v1.9.0, CDI v1.66.0, 쿠버네티스 v1.34). 스토리지 클래스의 설정은 같은 날 읽기 전용으로 조회했고, 공개 글이라 저장소 제품과 드라이버 이름은 「공유 스토리지의 CSI 드라이버」, 「노드 로컬 클래스」 로 일반화했습니다. 작성 규칙: 실측 데이터가 기본이고, 못 잰 것은 「미실측」, 문서에서 찾지 못한 것은 「미확인」으로 표시합니다.

학생 VM 이 뜨기까지 3: 디스크는 PVC 다

목차

1편의 ⑦ 「볼륨 붙이기」 를 엽니다. 결론부터 말하면, KubeVirt 의 디스크는 **게스트에게 보이는 장치(disk)**와 **그 내용을 담는 쿠버네티스 볼륨(volume)**의 짝입니다. 매니페스트에서 둘은 이름으로 이어집니다.

domain:
  devices:
    disks:
      - name: root          # 게스트에게는 virtio 디스크(/dev/vda)
        disk: {bus: virtio}
volumes:
  - name: root              # 내용은 이 볼륨에서 온다
    containerDisk: {image: quay.io/containerdisks/ubuntu:24.04}

볼륨 자리에 무엇을 넣느냐에 따라 디스크의 성질이 완전히 달라집니다.

1. 볼륨의 종류

KubeVirt 사용자 안내서가 꼽는 볼륨 원본 가운데 실습 VM 에 쓰는 것은 다섯입니다.

원본 무엇 끄면 실습에서
containerDisk 컨테이너 이미지의 /disk 안에 든 디스크 이미지 사라진다(임시) 기본 루트 디스크
emptyDisk 노드에 만드는 빈 희소 qcow2. 용량을 적어야 한다 게스트 재부팅에는 남고, VM 을 다시 만들면 사라진다 도커·쿠버네티스 실습의 스크래치
persistentVolumeClaim 이미 있는 PVC 남는다 —
dataVolume CDI 가 가져와 만든 PVC 남는다(VM 이 소유하면 VM 과 함께 지워진다) 영구 디스크 선택지
ephemeral PVC 를 읽기 전용 바탕으로 쓰고 쓰기는 로컬 쓰기 층으로 쓰기 층만 사라진다 골든 디스크(4편)
cloudInitNoCloud cloud-init 자료(Secret 에서) — 첫 부팅 설정(1편 ③)
루트 디스크를 마련하는 세 갈래 A. 컨테이너 디스크 (기본) 레지스트리 이미지 노드가 한 번 받음 노드 캐시 바탕(읽기만) 쓰기 층 emptyDir · VM 마다 루트 2.4GiB · Running 20초(실측) · 끄면 초기화 B. DataVolume (VM 마다 PVC) 레지스트리 이미지 VM 마다 다시 CDI 가져오기 파드 + 스크래치 PVC PVC 하나 RWO · 10Gi 원하는 크기 · 첫 부팅 최대 195초(실측) C. 골든 + 쓰기 층 골든 PVC 운영자가 한 번 · RWX 읽기 전용 readOnly: true 쓰기 층 emptyDir · VM 마다 골든 크기(10·20Gi) · 부팅 시간 미실측 A 와 C 는 같은 원리다: 읽기 전용 바탕 + VM 마다 쓰기 층. 바탕이 노드 캐시냐 PVC 냐만 다르고, 바탕의 크기가 곧 게스트 루트의 크기다.
그림: 루트 디스크를 마련하는 세 갈래

2. 컨테이너 디스크: 빠르지만 작다

컨테이너 디스크는 OS 이미지를 컨테이너 이미지처럼 레지스트리에서 받습니다. 노드가 한 번 받아 두면 다음 VM 은 받지 않고 바로 씁니다. 디스크가 임시라서 「만들고, 망가뜨리고, 지운다」 는 실습에 잘 맞고, 그래서 기본값입니다. 1편의 실측대로 20초 안팎에 Running 이 됩니다.

임시라는 것은 바탕은 노드에 받아 둔 이미지 파일이고, 게스트의 쓰기는 따로 쌓인다는 뜻입니다. 9일째 돌던 운영자용 VM 의 virt-launcher 안을 읽어 보니, 루트는 바탕(노드에 받아 둔 디스크 이미지, 할당 약 596MiB) 위에 얹힌 qcow2 쓰기 층(할당 약 1.10GiB)이었습니다(실측, 2026-10-14). 4편에서 다룰 골든 디스크는 이 구조에서 바탕만 PVC 로 바꾼 것입니다.

단점은 크기입니다. 컨테이너 디스크의 루트는 바탕 이미지의 가상 크기, 우리가 쓰는 우분투 이미지로는 2.4GiB 뿐입니다(실측). 실습을 만들며 이것 때문에 두 번 막혔습니다.

3. DataVolume: 크지만 느리다

루트가 커야 하는 실습을 위해 persistent 선택지가 있습니다. 이때 백엔드는 VM 매니페스트에 dataVolumeTemplates 를 넣고, CDI(Containerized Data Importer)가 VM 마다 PVC 를 만들어 이미지를 가져옵니다.

CDI 가 레지스트리 이미지를 가져오는 순서는 이렇습니다(CDI 「Scratch space」 문서). 가져오기 파드가 이미지를 받아 레이어를 풀고 디스크 이미지를 찾은 뒤 qemu-img 로 바꿔 대상 PVC 에 씁니다. 이 과정에 대상과 같은 크기의 스크래치 PVC 가 잠깐 필요하고, 끝나면 돌려줍니다. 그래서 10Gi 디스크 하나를 가져오는 동안에는 PVC 가 둘 생깁니다.

VM 이 DataVolume 을 소유하므로 VM 을 지우면 PVC 도 함께 지워집니다. 문제는 시간입니다. 실습 세션은 매번 VM 을 새로 만드는 구조라, VM 을 만들 때마다 이미지를 새로 가져오고 첫 부팅이 최대 195초까지 갔습니다(실측, 실습 개발 중 최대값만 기록). 백엔드가 VM 준비를 기다리는 상한을 컨테이너 디스크(150초)와 DataVolume(300초)으로 따로 둔 것도 이 때문입니다.

크기에도 함정이 하나 있습니다. 파일시스템 PVC 에서 KubeVirt 는 디스크를 PVC 루트의 disk.img 라는 raw 파일로 두므로, 파일시스템 자체가 차지하는 몫만큼 공간이 빕니다. CDI 문서에 따르면 DataVolume 을 spec.pvc 가 아니라 spec.storage 로 적을 때만 CDI 가 이 몫(파일시스템 여분)을 계산해 PVC 를 더 크게 요청합니다. TT Lab 의 CDI 설정에서 여분은 6% 이므로(2026-10-16 확인), 10Gi 를 spec.storage 로 요청하면 게스트 디스크는 10Gi, PVC 는 그보다 조금 큰 크기가 될 것입니다(계산값, 미실측). 설계 문서는 「10Gi 골든의 게스트 루트가 약 9.4GiB 일 것」 이라고 적었는데 CDI 문서와 어긋납니다. 어느 쪽이 맞는지는 4편 끝의 측정으로 확인합니다. 또 KubeVirt 는 disk.img 가 요청보다 조금 작아도(기본 10% 까지) 받아들입니다(사용자 안내서).

4. 접근 모드: 몇 노드가 동시에 붙을 수 있나

PVC 의 접근 모드는 VM 에서 특히 중요합니다. 쿠버네티스 문서의 정의를 요약하면 이렇습니다.

모드 뜻 VM 에서
ReadWriteOnce (RWO) 노드 하나가 읽고 쓰기로 붙는다. 같은 노드의 파드 여럿은 함께 쓸 수 있다 VM 이 그 노드에 묶인다. 라이브 마이그레이션 불가
ReadOnlyMany (ROX) 여러 노드가 읽기 전용으로 붙는다 바탕 디스크에 맞아 보이지만, 아래 주의
ReadWriteMany (RWX) 여러 노드가 읽고 쓰기로 붙는다 라이브 마이그레이션 가능, 여러 노드가 같은 바탕을 공유
ReadWriteOncePod (RWOP) 클러스터 전체에서 파드 하나만 CSI 볼륨에서만

두 가지를 짚어 둡니다.

접근 모드는 쓰기 보호가 아닙니다. 쿠버네티스 문서는 접근 모드가 붙은 뒤의 쓰기를 막지 않는다고, ROX 로 만든 볼륨도 읽기 전용이 보장되지 않는다고 분명히 적습니다. 진짜 보호는 볼륨을 읽기 전용으로 마운트하는 것입니다. 4편의 골든 디스크가 RWX 로 만들되 붙일 때 readOnly: true 를 빼지 않는 이유입니다.

라이브 마이그레이션은 RWX 를 요구합니다. KubeVirt 사용자 안내서는 PVC 를 쓰는 VM 은 접근 모드가 RWX 일 때만 옮길 수 있다고 적습니다. 옮길 수 있는지는 VMI 가 시작될 때 계산되어 LiveMigratable 조건으로 남고, 방법은 메모리만 옮기는 LiveMigration 과 디스크도 복사해야 하는 BlockMigration 으로 나뉩니다. 실제로 컨테이너 디스크와 emptyDisk 를 쓰는 VM 하나를 읽어 보니 LiveMigratable=True, 방법은 BlockMigration 이었습니다(2026-10-16 조회). 노드 로컬 디스크는 옮기려면 통째로 복사해야 한다는 뜻입니다. TT Lab 의 DataVolume 선택지는 RWO 로 만들므로 그 VM 은 옮길 수 없습니다. 실습 VM 은 어차피 옮기지 않으므로 받아들인 선택입니다.

5. 볼륨 모드: 파일시스템이냐 블록이냐

모드 파드에 보이는 모양 KubeVirt 의 디스크
Filesystem(기본) 디렉터리로 마운트 그 안의 disk.img(raw) 파일. 소유자는 UID 107 이어야 한다
Block 파일시스템 없는 블록 장치 장치를 그대로 디스크로

쿠버네티스 문서는 블록 모드를 파드와 볼륨 사이에 파일시스템 층이 없는 가장 빠른 길로 설명합니다. 대신 쓰는 쪽이 블록 장치를 다룰 줄 알아야 하는데, QEMU 는 다룰 줄 압니다. TT Lab 의 공유 스토리지 클래스는 CDI 가 파일시스템 모드만 내준다고 보고합니다(아래 6절). 그래서 골든 디스크도 파일시스템 PVC 안의 disk.img 입니다.

6. 바인딩 시점과 StorageProfile

PVC 를 만들자마자 볼륨을 잡느냐(Immediate), 그 PVC 를 쓰는 파드가 노드에 앉을 때까지 미루느냐(WaitForFirstConsumer)도 VM 에서 차이를 만듭니다. 노드 로컬 클래스는 미루는 쪽이어야 합니다. 볼륨이 특정 노드의 디스크라서, 파드가 어디 앉을지 알기 전에 잡으면 엉뚱한 노드에 생기기 때문입니다.

CDI 는 이 미룸을 존중하는 기능 게이트(HonorWaitForFirstConsumer)를 둡니다. 그러면 가져오기도 첫 사용자(VM)가 앉을 때까지 미뤄집니다. 골든 디스크처럼 VM 이 오기 전에 다 가져와 있어야 하는 볼륨은 그래서 「바로 바인딩해 달라」 는 어노테이션(cdi.kubevirt.io/storage.bind.immediate.requested)을 답니다.

CDI 는 스토리지 클래스마다 StorageProfile 을 만들어, 그 클래스에 맞는 접근 모드·볼륨 모드·복제 전략을 채웁니다. 이름을 아는 프로비저너에는 권장값을 넣고, 모르는 프로비저너는 비워 둡니다. 비어 있는 클래스에 접근 모드 없이 DataVolume 을 만들면 실패합니다(CDI StorageProfile 문서). 글을 쓰는 날 TT Lab 의 클래스를 읽어 보니 이랬습니다.

클래스 바인딩 확장 StorageProfile 이 내준 것 복제 전략
공유 스토리지(CSI 드라이버) Immediate 가능 RWX · Filesystem copy
노드 로컬 WaitForFirstConsumer — 비어 있음 copy

공유 스토리지 클래스만 여러 노드에 붙는 볼륨을 내줍니다. 그래서 골든 디스크는 이 클래스로 만듭니다. 복제 전략 copy 와 스냅샷 클래스가 없다는 사실은 4편에서 「왜 PVC 복제가 아니라 쓰기 층인가」 의 근거가 됩니다.

7. 정리: 세 갈래의 거래

컨테이너 디스크 DataVolume 골든 + 쓰기 층(4편)
루트 크기 2.4GiB(실측) 원하는 크기 골든 크기(10Gi·20Gi 메뉴)
VM 을 만들 때 하는 일 노드에 이미지가 있으면 거의 없음 이미지를 새로 가져와 PVC 에 씀 빈 쓰기 층 하나
첫 부팅 약 20초(실측) 최대 195초(실측) 미실측
VM 마다 생기는 PVC 없음 하나(+가져오는 동안 스크래치 하나) 없음
끄면 쓰기 층 사라짐 PVC 남음(VM 을 지우면 함께) 쓰기 층 사라짐

가운데 열의 「VM 마다 이미지를 새로 가져온다」 를 「한 번만 가져와 나눠 쓴다」 로 바꾼 것이 4편의 골든 디스크입니다.

티티 한마디. 접근 모드는 「몇 군데서 붙일 수 있나」 이지 「못 쓰게 막아 준다」 가 아니에요. 바탕 디스크를 지키고 싶으면 RWX 든 ROX 든 꼭 읽기 전용으로 붙이세요. 그리고 디스크가 차면 오류 메시지가 엉뚱한 말을 하니까, 이상하면 df -h 부터!

참고

문서는 모두 2026-10-16 에 열람했습니다.

로그인하면 좋아요를 누를 수 있습니다

댓글

아직 댓글이 없습니다.

로그인하면 댓글을 쓸 수 있습니다