결과: 병합 (2026-10-23 04:09, kubevirt/containerized-data-importer#4318). 사실은 GitHub 의 PR·댓글·타임라인·검사 기록, CDI 소스(PR 의 바탕 커밋
9cd4fbdb), 기여 원장의 초안과 클러스터 목록 원자료에서 가져왔습니다. 시각은 한국 시간입니다.
목차
- 한 줄 요약
- 1. 무엇이 문제였나: 6% 는 어느 쪽에서 빠지나
- 2. 원인: 문서와 코드의 어느 줄인가
- 3. 무엇을 바꿨나: diff 요지
- 4. 반응: 말없는 승인과 e2e 하나의 override
- 5. 배운 것: 오픈소스 기여 요령
- 링크
한 줄 요약
| PR | kubevirt/containerized-data-importer#4318 doc: explain how filesystem overhead changes PVC and image size |
| 바꾼 것 | doc/datavolumes.md 에 두 문단, doc/cdi-config.md 에 한 문단. 22줄 추가, 삭제 없음 |
| 반응 | 리뷰 댓글 없음. 메인테이너 한 명이 /lgtm·/approve, 나중에 e2e 하나를 /override |
| 결과 | PR 공개 10-17 00:50 → 승인 10-22 21:53 → 병합 10-23 04:09, 약 6일 3시간 18분 |
1. 무엇이 문제였나: 6% 는 어느 쪽에서 빠지나
CDI 는 Filesystem 모드 볼륨에 디스크 이미지를 쓸 때 파일시스템 메타데이터 몫으로 여분(filesystem overhead)을 남깁니다. 기본값은 0.06 입니다.
문서에는 두 문장이 있었습니다.
doc/datavolumes.md: Filesystem 모드면 CDI 가 「이미지와 파일시스템 메타데이터가 모두 들어갈 만큼 큰 PVC 를 요청한다」, 이 논리는spec.storage에만 적용된다.doc/cdi-config.md:filesystemOverhead는 Filesystem 볼륨에서 「남겨 둘 양」이다.
어느 문장도 결과로 PVC 와 디스크 이미지가 몇 바이트가 되는지는 말하지 않습니다. 「6% 를 남긴다」를 읽으면 PVC 를 요청한 크기로 두고 그 안에서 6% 를
떼는 그림이 떠오르기 쉽습니다. PR 본문에 적은 대로, 우리는 이 문서를 보고 VM 루트 디스크 크기를 정하면서 10Gi 를 요청하면 게스트가 약 9.4GiB 를 보리라
짐작했습니다. 실제로는 반대였습니다. spec.storage 를 쓰면 게스트 디스크가 꼭 10GiB 이고, 커지는 것은 PVC 입니다.
PR 본문의 실측은 TT Lab 클러스터의 CDI v1.66.0, 여분 기본값 0.06, NFS 스토리지 클래스(Filesystem 모드)에서 잰 것입니다.
DataVolume spec.storage 요청 |
PVC 요청(바이트) | 같은 값 |
|---|---|---|
| 10Gi | 11381663335 | ceil(10737418240 × 1.06) |
| 60Gi | 68289980007 | ceil(64424509440 × 1.06) |
| 80Gi | 91053306676 | ceil(85899345920 × 1.06) |
10Gi 볼륨은 virt-launcher 파드 안에서 qemu-img info 로 disk.img 의 virtual size: 10 GiB (10737418240 bytes) 를 확인했습니다.
원자료는 고르지 않게 남아 있습니다. 10Gi 볼륨의 PVC 크기 11381663335 는 2026-10-17 에 받아 둔 원장의 클러스터 목록(measure/kv/02-workloads.txt, 59일 된 PVC)에도
그대로 보입니다. 60Gi·80Gi 의 값과 qemu-img 출력은 PR 본문과 초안에만 있고 출력 원본 파일은 없습니다.
2. 원인: 문서와 코드의 어느 줄인가
줄 번호는 PR 의 바탕 커밋 9cd4fbdb 기준입니다.
문서 쪽
계산은 두 함수가 한다
계산식은 #3779(「overhead 크기 계산의 수학을 고침」, 2025-07-03 병합) 이후 이렇습니다.
- PVC 요청 =
align(size, 1MiB) × (1 + overhead)올림.pkg/util/util.go234–243행 의GetRequiredSpace입니다. 주석도 여분을 「정렬된 이미지를 포함한 전체 새 크기의 비율」로 센다고 적습니다. - 이미지 크기 =
min(여유 공간, PVC 요청) ÷ (1 + overhead)를 1MiB 단위로 내림.util.go225–232행 의GetUsableSpace와pkg/importer/data-processor.go360–389행 의calculateTargetSize입니다. 내림하는 이유는 qemu-img 가 올림을 해서 쓸 수 있는 공간을 넘기 때문이라고 주석에 적혀 있습니다.
10Gi 로 직접 따라가 보면 이렇습니다. 10Gi 는 10737418240 바이트이고 이미 1MiB 의 배수라 정렬해도 그대로입니다. 1.06 을 곱하면 11381663334.4 이고 올림하면 11381663335 입니다(1절 표의 첫 줄). 이 PVC 에 여유 공간이 충분하면 11381663335 ÷ 1.06 은 10737418240 을 살짝 넘고, 1MiB 단위로 내리면 다시 10737418240, 곧 10GiB 입니다. 그래서 게스트 디스크가 꼭 요청한 크기가 됩니다(계산).
거꾸로, 프로비저닝된 파일시스템의 실제 여유 공간이 PVC 요청보다 작으면 이미지가 그만큼 작아집니다. 작은 이미지에서 이 계산이 틀어진다는 이슈 #4024 가 2026-10-29 기준 열려 있습니다.
3. 무엇을 바꿨나: diff 요지
두 문서에 계산식과 예시를 더했습니다. 기존 문장은 하나도 지우지 않았습니다.
# doc/datavolumes.md, spec.storage 의 여분 설명 바로 뒤
+In that case the requested size is the size of the disk image, and CDI requests a PVC of
+`size * (1 + overhead)`, where `size` is rounded up to a multiple of 1MiB ...
+For example, with the default overhead, a DataVolume that requests `storage: 10Gi`
+creates a PVC that requests `11381663335` bytes (`10Gi * 1.06`), and the resulting
+`disk.img` has a virtual size of `10Gi`. If the filesystem on the provisioned volume has
+less free space than the PVC request, the image is sized down ... (see #4024).
+
+With `DataVolume.spec.pvc` the PVC is created with the requested size as is, but the
+overhead is still reserved inside it when CDI writes the image (import, upload or blank),
+so the disk image ends up smaller than the requested size (about `size / (1 + overhead)`).
# doc/cdi-config.md, filesystemOverhead 설명 뒤
+The overhead is a fraction of the disk image size, added on top of it. ...
spec.pvc 쪽 문장은 잰 것이 아닙니다. 가져오기·올리기·빈 디스크 세 경로가 모두 GetUsableSpace 로 이미지 크기를 정한다는 코드 경로를 읽고 쓴 것이라고
PR 본문에 밝혔습니다(미실측). 그림의 ② 가 그 경우입니다.
AI 사용은 커밋 꼬리말 Co-Authored-By: Claude Opus 5.5 와 Signed-off-by, 본문 끝의 「이 변경은 AI 의 도움으로 초안을 쓰고 내가 검토했다」 한 문장으로
밝혔습니다. KubeVirt 의 AI 기여 정책은 도구가 자동으로 넣는
Co-authored-by 도 받아들인다고 적고 있습니다. 커밋에는 SSH 서명이 붙어 있습니다(GitHub 에서 확인됨).
4. 반응: 말없는 승인과 e2e 하나의 override
| 시각 | 일 |
|---|---|
| 10-17 00:50 | PR 공개. prow 가 release-note-none·size/S 라벨, 「신뢰되지 않은 작성자는 시험을 직접 못 연다」 안내, 리뷰어 둘 지정 |
| 10-22 21:53 | 메인테이너 한 명이 /lgtm 과 /approve 를 한 댓글로 |
| 10-22 22:06 | coveralls 의 범위 보고 |
| 10-23 04:07 | 같은 메인테이너가 /override pull-containerized-data-importer-e2e-ceph |
| 10-23 04:09 | tide 가 병합 |
리뷰 댓글은 하나도 없었습니다. 원장에는 「문서 PR 도 e2e 18개를 돈다, 협업자가 /test all 을 쳐야 한다」, 그리고 「10-20 무렵 조용하면 #4024 의 분석을 쓴
리뷰어를 /cc 하자」는 계획이 적혀 있었습니다. 타임라인을 보면 그 /cc 는 하지 않았고, 엿새째 되는 날 다른 메인테이너가 먼저 승인했습니다.
병합 두 분 전의 /override 는 ceph 를 쓰는 e2e 하나의 결과를 메인테이너 권한으로 통과로 바꾼 것입니다. 왜 override 했는지는 PR 에 적혀 있지 않습니다.
문서만 바꾼 PR 이라 e2e 결과가 변경과 관계없다고 본 것으로 보입니다. 병합 뒤 GitHub 의 검사는 21개가 모두 통과로 보입니다.
같은 문제를 「KubeVirt 소스 코드 읽기」 6편에서도 다뤘습니다. 그 글을 쓸 때는 이 PR 이 리뷰 중이었습니다.
5. 배운 것: 오픈소스 기여 요령
- 「비율을 말하는 문서에는 기준이 무엇인지 적습니다.」 「6% 를 남긴다」는 같은 말이 「PVC 에서 6% 를 뗀다」로도, 「이미지에 6% 를 더한다」로도 읽힙니다. 숫자 하나(10Gi → 11381663335 바이트)를 보여 주면 두 해석 중 하나가 바로 지워집니다.
- 「문서의 숫자는 코드로 다시 계산되게 씁니다.」 PR 의 표에
ceil(10737418240 × 1.06)을 함께 적어, 리뷰어가 클러스터 없이 계산기만으로 확인할 수 있게 했습니다. 리뷰 댓글이 하나도 없었던 이유 중 하나로 보입니다. - 「잰 것과 읽은 것을 문장 단위로 나눕니다.」
spec.storage쪽은 실측,spec.pvc쪽은 코드 경로로 읽은 것이라고 본문에 갈라 적었습니다. 「다 확인했다」 라고 뭉뚱그리지 않아야 리뷰어가 어디를 더 봐야 하는지 압니다. - 「원자료는 PR 본문 말고 원장에도 남깁니다.」 60Gi·80Gi 의 값은 지금 PR 본문에만 있습니다. 나중에 같은 계산을 다시 쓸 때 원본 출력이 있으면 이 글처럼 「본문에만 있다」고 적지 않아도 됩니다.
티티 한마디. 「상자에 10킬로를 담아 주세요」 하면 상자 값이 6% 더 나온대요. 상자 벽 두께 몫이래요. 그래서 저는 10킬로 상자에 9.4킬로만 들어가는 줄 알았어요. 그런데 달아 보니 내용물은 딱 10킬로, 상자가 커진 거였어요! 안내문에 「10킬로를 담으면 상자는 10.6킬로짜리로 드려요」라고 한 줄 써 붙였더니, 아무 말 없이 「좋아요」 도장이 찍혔어요.
링크
모든 자료는 2026-10-29 에 열람했습니다.
- PR: kubevirt/containerized-data-importer#4318 (병합 커밋
0bafeaa7) - 고친 문서(바탕 커밋):
doc/datavolumes.md,doc/cdi-config.md - 계산 코드(바탕 커밋):
GetUsableSpace·GetRequiredSpace,calculateTargetSize - 관련: #3779 계산 수정, 이슈 #4024
- 같은 함수 근처의 로그 수정: 9편, containerized-data-importer#4320