在我们的好镜像标准中,”轻量”是一个非常重要的标准,其关键就在于体积小,要剪裁掉应用服务不需要的组件,代码或者文件。由于镜像是分层次的,每个镜像都是基于根镜像一层一层继承下来的。考虑到一般应用软件的可执行文件都不会太占体积,那么根镜像的体积就决定了最终镜像的体积。
因此,如果需要一个轻量的好镜像,根镜像的选择就较为重要了。
Scratch镜像
说到轻量的根镜像,首先要想到的是Scratch镜像。
Scratch镜像是一种特殊镜像。它是一个虚拟镜像, 不可以直接拉取或运行它,因为它完全为空。基于Scratch构建的镜像往往只包含应用的可执行文件,可谓把轻量做到了极致。当然,使用Scratch镜像,你得接受它的种种不便。
首先,scratch没有shell ,这意味着在Dockerfile中的CMD和RUN指令中不能使用字符串语法。使用字符串语法,CRI会通过shell来执行,从而导致出错。其解决方案是使用JSON语法,这样Docker直接会直接执行,而不是交给shell。
其次,scratch没有调试工具,因为scratch是空的,所以构建出的镜像不包含任何工具,如ls,ps,ping等,我们也就无法进入到该容器中。
最后,scratch会有一些动态链接库的缺失,例如libc,因此使用scratch作为根镜像,需要在编译的时候采用静态链接,或者手工为镜像增加动态链接库。
操作系统镜像
目前,Scratch常常用在go生态的采用静态编译的开源镜像中,传统的应用如C语言发布的应用还是会依赖操作系统提供的动态链接库,像Java类的应用甚至依赖操作系统提供的JVM,这些应用就必须采用其他的根镜像选择。
我们先看看主流操作系统镜像的大小。
REPOSITORY TAG IMAGE ID CREATED SIZE
debian latest 676aedd4776f 8 days ago 117MB
fedora latest 86226de74a8c 13 days ago 191MB
ubuntu latest e4c58958181a 2 weeks ago 77.8MB
alpine latest 8ca4688f4f35 3 weeks ago 7.34MB
centos latest 5d0da3dc9764 2 years ago 231MB
上面是主流linux操作系统镜像的大小,其中最小的是alpine,才7.34MB,大的是centos,高达231MB。
Alpine Linux是一种基于musl libc和BusyBox的轻量级Linux发行版,它的镜像非常小,这使得它适合于云原生应用和微服务架构。Alpine内置apk包管理器,软件安装和更新变得简单和快速,可以让你利用alpine扩展出非常多的应用;Alpine还内置了busybox,支持多数linux内置指令,对开发调测非常有利。
从轻量,易定制,易调试这三个标准来看,Alpine无疑是最佳的选择。
但这也不是说,centos和ubuntu等镜像就毫无价值,某些涉及到内核的系统软件就必须适配专门的操作系统版本。我们曾经为了编译并构建kubevirt的arm架构镜像,尝试了alpine,fedora等操作系统,最终在centos上才得以成功。