结果:已合并(2026-10-23 04:09, kubevirt/containerized-data-importer#4318). 实际上取自 GitHub 的 PR、评论、时间线、检查记录,以及 CDI 源码(PR 的基础提交
9cd4fbdb)、贡献记录草稿和集群列表原始数据。 时间为韩国时间。
目录
一句话总结
| 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 正文中所写,我们在阅读本文档决定虚拟机根磁盘大小时,猜测请求 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 Pod 内通过 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.go第 234–243 行 的GetRequiredSpace。 注释中也提到,预留空间是作为“包含已对齐镜像的整个新大小的比例”来计算的。 - 镜像大小 =
min(여유 공간, PVC 요청) ÷ (1 + overhead)按 1MiB 单位向下取整。util.go第 225–232 行 的GetUsableSpace与pkg/importer/data-processor.go第 360–389 行 的calculateTargetSize。 代码注释中写道,之所以向下取整,是因为 qemu-img 会向上取整从而超出可用空间。
直接代入 10Gi 计算如下。10Gi 等于 10737418240 字节,且已经是 1MiB 的倍数,对齐后保持不变。乘以 1.06 得到 11381663334.4,向上取整后为 11381663335(第 1 节表格的第一行)。如果该 PVC 拥有充足的自由空间,11381663335 ÷ 1.06 会略大于 10737418240,以 1MiB 为单位向下取整后又回到 10737418240,即 10GiB。因此客机磁盘正好是请求的大小(计算结果)。
相反,如果配置的文件系统的实际可用空间小于 PVC 请求大小,镜像就会相应变小。关于在小镜像中该计算出错的 Issue #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 侧的语句并非测得。我们在 PR 正文中说明,这是通过阅读代码路径得出——导入、上传和空磁盘这三个路径都使用 GetUsableSpace 来确定镜像大小(未实测)。图中的 ② 即属于这种情况。
关于 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 也要跑 18 个 e2e,协作人员需要输入 /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 公斤的箱子里只能装 0.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 计算修正,Issue #4024
- 修改同一函数附近的日志: 第 9 篇,containerized-data-importer#4320