如何使用 JIB 删除容器内的目录?

问题描述

如果是docker文件,我想通过执行以下命令删除目录。

RUN rm /usr/bin/wget

我该怎么做?任何帮助表示赞赏

解决方法

首先要强调:在Dockerfile中,RUN rm /usr/bin/wget不会物理删除文件。先前层中的文件和目录在物理上将永远留在那里。因此,如果您尝试使用 rm 删除包含敏感信息的文件,这是行不通的。例如,最近,这种疏忽导致 Codecov 出现了一个引人注目的 security breach

Docker 层攻击:公开分发的 Docker 镜像应该被压缩或多级处理,以便包含敏感信息的中间层被排除在最终构建之外。

结果是,RUN rm /usr/bin/wget 创建了另一个包含“whiteout”文件 /usr/bin/.wh.wget 的层,并且这个新层位于所有先前层的顶部。然后在运行时,只是容器运行时会隐藏文件,您将看不到它。但是,如果您下载图像并检查每一层,您将能够看到并提取 /usr/bin/wget/usr/bin/.wh.wget 文件。所以,是的,稍后执行 rm 根本不会减小图像的大小。 (顺便说一句,RUN 中的每个 Dockerfile 在最后都会创建一个新层。因此,例如,如果您删除同一个 RUN 中的文件,例如 RUN touch /foo && rm /foo,您将不会在最终图像中留下 /foo。)

因此,使用 Jib,如果您要“删除”的文件或目录来自基础映像,您可以做的是为其创建一个新的 whiteout 文件。 Jib 有 <extraDirectories> feature 可以将任意文件复制到图像中。因此,例如,由于 <project root>/src/main/jib 是默认的额外目录,您可以创建一个空的 src/main/jib/usr/bin/.wh.wget,它将被处理为图像中的 /usr/bin/.wh.wget

当然,如果您真的想物理删除来自基础映像的文件,唯一的选择是重建您的基础映像,使其不包含 /usr/bin/wget

为了完整起见:如果您要删除的文件或目录不是来自您的基础映像而是来自 Jib,您可以使用 Jib 图层过滤器扩展 (Maven/Gradle)。 (这是应用层过滤,不涉及 whiteout 文件。)但是,通常没有理由删除 Jib 放置的文件。