Docker 层隐藏的设计妥协:白障文件与被吃掉的文件名
来源: loige.co — 2026-09-30
概述
作者在研究 SOCI(可寻址 OCI)时重新审视 Docker 层,发现不少被忽略的设计妥协:删除文件靠特殊命名的 tar 条目(.wh. 白障)表达,而 tar 本身并不知道这些名字特殊。当层里真的存在一个名为 .wh.foo 的普通文件时,同一串字节在 tar 语义与 OCI 层语义下会指向完全不同的事实。
核心要点
- 并非每条 Dockerfile 指令一层:只有 RUN / COPY / ADD 这类改变文件系统的步骤才产生层,ENV、CMD、LABEL 只改配置。
- 层不可变,容器看到的是按顺序叠加的结果;正是这种不可变性支撑了构建缓存与层共享。
- 删除靠 .wh. 前缀的白障条目表达,白障在 tar 里只是一个名字古怪的普通文件,真正的语义由 OCI 消费方赋予。
- 白障只能作用于此前的层:同一层里与白障并列的文件不会被隐藏,而白障自身在合并视图中也必须是隐藏的。
- 把名为 .wh.foo 的真实文件 COPY 进镜像后,序列化出的层会被解读成删除 tmp/foo 的白障,实验证明该文件在重新解包后确实消失。
金句
同一个 tar 条目,上面叠加了不同的语义层。
👍 0
👎 0
← 返回 Lobsters 首页