使用多阶段构建,我想在 Dockerfile 末尾缩小图像,如下所示:
FROM ubuntu AS ubuntu_build
RUN # do a lot of build things
FROM alpine
COPY --from=ubuntu_build /app /app
ENTRYPOINT whatever
alpine 图像很小,理论上只有 /app 的东西会从 ubuntu 图像中复制出来,这是书中最好的技巧,还是有其他方法可以最小化最终图像的大小?
使用多阶段构建,我想在 Dockerfile 末尾缩小图像,如下所示:
FROM ubuntu AS ubuntu_build
RUN # do a lot of build things
FROM alpine
COPY --from=ubuntu_build /app /app
ENTRYPOINT whatever
alpine 图像很小,理论上只有 /app 的东西会从 ubuntu 图像中复制出来,这是书中最好的技巧,还是有其他方法可以最小化最终图像的大小?
Google 提供了说明和工具来帮助制作distroless 映像。
“Distroless”映像仅包含您的应用程序及其运行时依赖项。它们不包含包管理器、shell 或您希望在标准 Linux 发行版中找到的任何其他程序。
为什么要使用 distroless 映像?
将运行时容器中的内容严格限制为应用所需的内容是 Google 和其他在生产环境中使用容器多年的科技巨头采用的最佳实践。它提高了扫描仪(例如 CVE)的信噪比,并减轻了根据您的需要确定出处的负担。
如果您的应用程序是已编译的二进制文件,那么您可以使用单个二进制文件加上它链接的共享库。如果你限制你链接的库,你可能只需要几个。例如,这里是在我的机器上使用 gcc 链接编译的最小 C 程序:
$ ldd basic-program
linux-vdso.so.1 (0x00007fffd3fa2000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2e4611b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f2e4670e000)
哎呀,您甚至可以静态链接整个程序并且完全没有依赖关系。
Google 提供了一组针对不同语言的基本图像:
他们只有一些基本的文件,远远少于像 alpine 这样的最小发行版,因为它仍然具有apk
包管理器、用户空间实用程序等。您使用它们的方式与您在问题中描述的方式相同:作为最后阶段在多阶段构建中。
FROM gcr.io/distroless/base
COPY --from=build /go/bin/app /
CMD ["/app"]
您还可以走完整的生食生活在森林中的路线并建立您的最终形象FROM scratch
。没有比这更纯粹的了。绝对没有你自己没有放在那里的东西。例如,这是traefik选择的路线。
FROM scratch
COPY certs/ca-certificates.crt /etc/ssl/certs/
COPY traefik /
EXPOSE 80
VOLUME ["/tmp"]
ENTRYPOINT ["/traefik"]
除了 use multi-stage
,另一种典型的方法是使用docker-slim
来减小最终构建图像的大小,如下所示:
docker-slim build --http-probe your-name/your-app
详情参考本指南
如果您需要,请添加其他常见的想法摘录自“五种方法来精简 Docker 图像”:
COPY . /
,更多,如果不使用.gitignore
,则需要避免使用COPY . /
可能会将一些必要的东西复制到图像。