在Docker中剥离可执行文件为什么会增加荒谬的层内存开销

125次阅读
没有评论

问题描述

在使用Docker构建镜像时,尝试通过剥离可执行文件的方式来减小镜像大小,但却发现镜像的大小反而增加了。用户在Dockerfile中使用了多阶段构建,以及尝试了多种方法,但最终的镜像大小没有得到减小。用户想知道为什么会出现这种情况,以及是否有办法在Docker中剥离可执行文件而不会导致镜像大小增加。

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1:多阶段构建中的剥离和镜像压缩

Docker中的每个指令都会增加一个新的镜像层。无论你进行哪些操作,例如删除文件、剥离可执行文件等,都会导致镜像的大小增加。在你的多阶段构建中,使用COPY指令将之前阶段的文件复制到新的阶段,并不能减小镜像的大小,因为这些操作会生成新的镜像层,包括之前的文件变更。

为了解决这个问题,你可以尝试使用“压缩镜像”的方式,将镜像的不同层压缩成一个层,从而减小镜像的大小。以下是一个示例操作:

  1. 使用docker build命令构建基础镜像,例如docker build -t squashtest:base -f Dockerfile.base .
  2. 使用docker image ls查看构建的基础镜像的IMAGE ID。
  3. 使用类似以下命令将构建的基础镜像导出为tar文件,并导入为新的镜像:

bash
docker run --rm squashtest:base \
tar -C / -cf- --exclude=./dev --exclude=./sys --exclude=./proc . |
docker import - squashtest:imported

  1. 查看新的镜像大小,例如使用docker image ls squashtest:imported

通过这种方式,你将原本的多个镜像层压缩成一个层,从而减小了镜像的大小。

请注意,压缩镜像可能会导致某些操作无法撤消,因此在执行此操作之前,请确保你的备份充分。

方案2:可执行文件剥离的必要性

在Docker环境中,很多发行版默认会对可执行文件进行剥离。因此,你之前尝试的在Dockerfile中使用strip命令剥离可执行文件可能是多余的。你可以使用file命令来验证Docker镜像中的可执行文件是否已经被剥离。

除非你运行在极度受限的环境中,否则几百兆字节的差异可能并不值得你投入大量精力去解决。在多数情况下,可执行文件的剥离并不会显著影响镜像的性能或资源利用率。

此外,Docker还提供了一些压缩镜像的方法,如使用docker-squash等工具,但在实际应用中,根据你的具体需求,是否值得进行压缩需要仔细权衡。

注意事项

在尝试任何改变之前,务必备份你的数据和镜像,以免出现意外情况。

以上方案提供了多阶段构建中的镜像压缩以及剥离可执行文件的方式,但在实际应用中,请根据你的情况进行适当调整和测试。

正文完