简介: 本文主要讲解针对不同的语言来选择适当的精简策略,其中主要讨论 Go,同时也涉及到了 Java,Node,Python,Ruby和 Rust。同时也会详细介绍 Alpine 镜像的避坑指南。



镜像下载、域名解析、时间同步请点击 阿里巴巴开源镜像站

一、Go 语言镜像精简

GoGocgonetbusybox:glibccgoCGO_ENABLED=0
scratchcgo-tags-tags netgo
cgoCGO_ENABLED=0
AlpineAlpineAlpineCentOSUbuntuArchlinuxapkRed HatCanonical1000050000Alpineifconfignetstat100M5Mtcpdump

测试结果如下:

runrunbuild

run 阶段使用 Alpine

带着激动的心情,将 Alpine 镜像加入了 Dockerfile:

第一个坑来了,启动容器出现了错误:

scratchCscratchmusl libcglibcglibcmusl libcglibcglibcmusl libcmusl libc

所有阶段使用 Alpine

musl libc
  • 某些官方镜像提供了 Alpine 版本,可以直接拿来用。
  • 还有些官方镜像没有提供 Alpine 版本,我们需要自己构建。
golang:alpineGoDockerfile

生成的镜像大小为 7.5M,对于一个只打印 『hello world』的程序来说确实有点大了,但我们可以换个角度:

  • 即使程序很复杂,生成的镜像也不会很大。
  • 包含了很多有用的调试工具。
  • 即使运行时缺少某些特殊的调试工具,也可以迅速安装。
gcc:alpine
build-basegccbuild-essentials

最后来对比一下不同构建方法得到的 『hello world』镜像大小:

golanggolangubuntugolang:alpinealpinegolangscratch
99.75%net
golanggolangubuntugolang:alpinealpinegolangbusybox:glibcgolangubuntu
99%

三、Java 语言镜像精简

JavaJVM

静态还是动态?

JVMJava APIJARWARopen()fopen()JVMJVMmusl libcglibcJVMJVM

类文件格式

Java APIJava 5-target--release--release

JDK vs JRE

JDKJREJREJava Runtime EnvironmentJVMJDKJava Development KitbuildJDKrunJRE

Java vs OpenJDK

openjdkAmazon

开始构建

说了那么多,到底该用哪个镜像呢?这里给出几个参考:

  • openjdk:8-jre-alpine(85MB)
  • openjdk:11-jre(267MB)或者 openjdk:11-jre-slim(204MB)
  • openjdk:14-alpine(338MB)

如果你想要更直观的数据,可以看我的例子,还是搬出屡试不爽的 『hello world』,只不过这次是 Java 版本:

不同构建方法得到的镜像大小:

javaopenjdkopenjdkopenjdk:jreamazoncorrettoopenjdk:11openjdk:11-jreopenjdk:8openjdk:8-jre-alpine

所有的 Dockerfile 都可以在这个仓库找到。

四、解释型语言镜像精简

NodePythonRust

Alpine 镜像

Alpine
  • 简单:依赖库有针对 Alpine 的安装说明,一般会说明需要安装哪些软件包以及如何建立依赖关系。但这种情况非常罕见,原因前面也提到了,Alpine 的软件包数量比大多数流行的发行版要少得多。
  • 中等:依赖库没有针对 Alpine 的安装说明,但有针对别的发行版的安装说明。我们可以通过对比找到与别的发行版的软件包相匹配的 Alpine 软件包(假如有的话)。
  • 困难:依赖库没有针对 Alpine 的安装说明,但有针对别的发行版的安装说明,但是 Alpine 也没有与之对应的软件包。这种情况就必须从源码开始构建!
numpypandaswheeleggpipglibc

:slim 镜像

xxx:slimDebianglibc
matplotlibnumpypandas
Django

最后来总结一下:到底使用哪个基础镜像并不能盖棺定论,有时使用 Alpine 效果更好,有时反而使用 slim 效果更好,如果你对镜像体积有着极致的追求,可以这两种镜像都尝试一下。相信随着时间的推移,我们就会积累足够的经验,知道哪种情况该用 Alpine,哪种情况该用 slim,不用再一个一个尝试。

五、Rust 语言镜像精简

RustMozillaWebUbuntuDebianFedorabusybox:glibclibdlbusybox:glibcrust:alpinemusl libcmusl libcscratch