Docker的`COPY --chmod`可将镜像文件大小减少35%


本周早些时候,我正在编写一个 Dockerfile 来下载和运行二进制文件,这时我注意到镜像图像大小远远超出了我的预期:

FROM ubuntu:21.10 AS downloader
# Install wget, gnupg; download a zip archive; verify checksum; unzip the binary

FROM ubuntu:21.10
LABEL ...

[b]COPY --from[/b]=downloader /bin/<binary> /bin/<binary>

RUN apt-get update && apt-get install -y openssl dumb-init iproute2 ca-certificates  \
    && rm -rf /var/lib/apt/lists/* \
    && chmod +x /bin/<binary>
    && mkdir -p <couple of empty directories> \
    && ...
...

`COPY --chmod`在 BuildKit中可用。
 
解释:如果你把文件复制到一个容器中,那么这些文件就有自己的 "层",类似于它们自己的压缩文件。
然后,如果你对所有这些文件进行`COPY --chmod`,它们将被复制到第二层,并带有新的访问修饰符。
当容器运行时解压镜像时,它将把这两层视为独立的压缩文件,并解压第一层,然后再解压第二层,完全覆盖第一层。
做到这两点,即在同一层中进行复制和chmod,镜像文件的大小减少了50%,或者在更现实的情况下减少了一点。
这是更明显的改进之一,尽管由于某些原因很少使用。
  
但是,docker-slim是创建最小且安全的 Docker 映像的方法:
不要浪费时间来尝试使用 Alpine 基础镜像和静态编译复杂的软件。当 docker-slim 在从镜像中删除操作系统方面做得更好,同时让您可以使用任何您想要的基础镜像时,这带来的所有性能、兼容性、包可用性问题都不值得。
  
其他提升办法:按照底部的“变化最大”的顺序放置您的步骤。所以:在顶部加载库,在底部复制代码本身。
层在 Dockerfile 中按从上到下的顺序进行处理。
如果其中一个发生了变化,那么所有后续层也将被重建。
因此,永远不会改变的东西,比如 LABEL 声明,应该放在第一位,而经常改变的东西,比如你的代码,应该放在最后。