这种大略性的缺陷是,很随意马虎构建出大体积的容器镜像,个中包含很多不须要的东西——包括潜在的安全漏洞。
由于利用的是阐明型措辞还是编译型措辞,创建容器镜像的过程会有所不同。下面一起深入理解(下面通过dockerfile仿照):
阐明型措辞,如Ruby,Python,Node.js,PHP和其他措辞通过发送源代码到阐明器来运行代码。 这样的好处是可以跳过编译步骤,但其缺陷是哀求将阐明器与代码一起丢进去。

幸运的是,大多数这些措辞都供应了预构建的Docker容器,个中包含一个轻量级环境,许可运行更小的容器。
我们来看一个Node.js运用程序并对其进行容器化。
首先,利用node:onbuild镜像作为根本。 Docker容器的onbuild版本预先打包了您须要的所有内容,因此无需实行大量配置即可搞定。 这意味着Dockerfile非常大略(只有两行!
)。 但是要付出的磁盘大小代价——差不多700MB!
通过利用较小的根本镜像(如Alpine),您可以显著减少容器的大小。Alpine Linux是一款体积小,轻量级的Linux发行版,在Docker用户中非常受欢迎,由于它与许多运用程序兼容,同时仍旧保持小体积。
幸运的是,Node.js(以及其他盛行措辞)有一个官方的Alpine图像,可以知足您的统统需求。与默认的node镜像不同,node:alpine会删除许多文件和程序,只留下足以运行运用程序的部分。
基于Alpine Linux的Dockerfile创建起来有点繁芜,由于必须运行一些针对onbuild的命令。
但是,产生的镜像只有65MB!
编译型措辞的容器化
诸如Go,C,C ++,Rust,Haskell等编译型措辞可以创建在没有许多外部依赖性的情形下运行的二进制文件。 这意味着你可以提前构建二进制文件并将其投入生产,而无需把创建二进制文件(如编译器)放进去。
下面采取Go运用程序并利用此模式对其进行容器化。
首先,利用golang:onbuild镜像作为根本。 和以前一样,Dockerfile只有两行,但需付出磁盘大小超过700MB的代价!
下一步是利用更小的根本镜像,也便是golang:alpine镜像。
同样,利用Alpine根本镜像创建Dockerfile有点繁芜,由于必须运行一些实行onbuild镜像干系的命令。
但同样,由此产生的镜像要小得多,大小只有256MB!
但是,我们可以使镜像更小:假设不须要Go附带的任何编译器或其他构建和调试工具,可以从终极容器中删除它们。
下面利用多阶段构建来获取由golang:alpine容器创建的二进制文件并将其自行打包。
下面的这个容器镜像只有12MB大小!
在Kubernetes上拉取镜像
虽然你可能不关心构建和推送容器镜像所需的韶光,但该当非常关心拉取容器镜像所需的韶光。 对付Kubernetes,这可能是您的生产集群最主要的指标。
例如,假设有一个三节点集群,个中一个节点崩溃。 如果利用的是像Kubernetes Engine这样的托管系统,系统会自动天生一个新节点来代替它。
但是,这个新节点将是全新的,并且必须先拉取所有容器镜像才能开始事情。 拉取容器镜像所需的韶光越长,集群实行的韶光就越长!
当增加群集大小(例如,利用Kubernetes Engine Autoscaling)或将节点升级到新版本的Kubernetes时,可能会发生这种情形(接下来的几集中会关注这个问题)。
我们可以看到来自多个支配的多个容器的拉取性能可以在这里真正表示出来,利用小容器可能会摧残浪费蹂躏几分钟的支配韶光!
除了性能之外,利用较小的容器镜像还有很大的安全性提升。 与利用大根本镜像的容器镜像比较,小容器镜像常日具有较小的攻击面。
几个月前,我构建了Go onbuild和multi-age容器镜像,因此它们可能包含一些已被创造的漏洞。 利用Google Container Registry的内置漏洞扫描,可以轻松扫描容器中的已知漏洞。
小容器镜像
较小容器镜像中只有三个“中级”漏洞,而较大容器镜像中有16个严重漏洞和300多个其他漏洞。
大容器镜像
大多数存在的问题与运用程序无关,乃至没有运用程序!
由于多阶段构建利用的是更小的根本镜像,以是可以产生漏洞的东西更少。
利用小容器镜像的性能和安全上风不言而喻。利用小的根本镜像和builder pattern可以更随意马虎地构建小镜像,并且还有许多其他技能可用于单个技能栈和编程措辞,以最小化容器体积。 无论做什么,都可以确信保持容器镜像最小化的努力是值得的!
后期内容会更多分享DBA和DEVOPS内容,感兴趣的朋友可以关注下!