微容器— 轻量级Docker容器

microcontainers

Docker能够让你将应用程序和依赖环境打包到一个独立的镜像中,这样就可以使用该镜像在容器中运行应用。问题是你通常会打包额外的、非必须的内容,以至于生成了巨大的镜像,从而也需要巨大的容器。多数使用Docker的人都会选择官方仓库中的镜像,但很不幸,你仅仅需要一个鸟笼大小的镜像却得到了帝国大厦规模的镜像。如果你基于官方的Node镜像构建了自己的镜像,那它最小也要643MB。

我基于官方Node镜像创建了一个简单的Hello World程序,大小为644MB.

microcontainers1

 

这样的镜像太大了 !我的应用程序加上依赖是小于1 MB的,Node.js运行时约20MB,什么内容占据了另外的620 MB?我们一定能做得更好。

什么是微容器?

微容器只包含OS库、运行应用程序所需要的语言依赖以及应用程序本身。仅此而已

与其增加所有的东西,不如设置一个最低限度,在需要的基础上增加依赖。

使用上文中提到的完全相同的Node应用,和一个很小的基础镜像且仅安装了最核心的Node.js及其依赖。构建结果是29MB,整整小了22倍!

microcontainers2

 

microcontainers3

 

 

 

 

 

 

 

 

 

常规镜像对比微镜像

尝试运行这两个镜像,docker run –rm -p 8080:8080 treeder/tiny-node:fat ,然后docker run –rm -p 8080:8080 treeder/tiny-node:latest.完全相同的应用,截然不同的大小。

为什么微容器这么赞?

使用微服务有很多优势:

●  尺寸 —  如上所示微容器很小,在不改变任何代码的情况下镜像比典型镜像 小22倍。

●  快速/简单的分发— 由于尺寸更小了,从 Docker registry (例如: Docker Hub)下载镜像更快了,因此它可以更快地分发到不同的机器上。●  提高安全性-容器中的代码/程序越少意味着受攻击面越小。这样基础OS会更安全(详细的可以看下文)。

这些优势与Unikernels的优势类似,没有任何缺点。

如何构建微容器?

所有的Docker镜像的基础镜像是“空”镜像(`scratch` image),它基本上什么都没有。听起来然并卵,但如果你可以把你的应用程序编译成像Go或 C一样的零依赖静态的二进制的文件中,你就可能创建最小的应用镜像。就如我的treeder/static-go镜像包含一个 Go Web应用程序,整个镜像包括应用是5MB。

scratch镜像+应用程序二进制是你能得到的尽可能小的镜像。

不是每个人都使用Go,所以你可能有更多的依赖,而且你会希望得到比scratch镜像更多的东西。加入Alpine Linux。我不想用细节恶心你,但他们的广告语说明了一切:“Alpine Linux是 基于musl libc 和BusyBox的一个安全型,轻量级的Linux发行版。”你可以在此了解更多上述内容的含义,但是这篇文章我们最关心的是“轻量级”部分。基础 Alpine 镜像仅5MB:

因此,现在我们有一个非常好的OS作为基础,它提供了一款很好的包管理系统来增加我们的依赖。对于简单的Node应用程序来说,我们只需要Node本身,所以我们不需要Node包以外的其他内容。我们的Dockerfile看起来像这样:

简单整洁。现在在镜像中我们只有Node和Node依赖。

现在把代码添加到镜像中,在Dockerfile中添加几行:

你可以在这里获取示例代码并看到完整的构建指令。我们现在有一个非常小的操作系统+只有我们需要的依赖+我们的应用程序代码。仅此而已。

所有语言适用相同的规则

所有语言的基础镜像

幸运的是,我们已经建立了所有主要语言的基础镜像,你可以在这里找到他们:

https://github.com/iron-io/dockers

为了使镜像尽可能小我们做了一些优化,而且我们会定期更新他们,相比于自己构建,这些镜像会是更好的选择。使用 Iron.io基础图像,上述Node应用程序的Dockerfile就变成了这样:

此外,我们为每一种语言都构建了2个版本的镜像。分别用于构建和运行。用于构建的镜像包含了所有的构建工具,所以一般比用于运行的更大。

例如要构建你的Node依赖,可以像下面这样使用iron/node:dev:

然后在你的Dockerfile中使用iron/node或者运行它:

其他所有语言也是相同的,但是你会使用他们的build/vendor/run指令。

如果你想使用一个语言的不同版本,你可以改变标签。例如,你可以使用iron/node:4.1或 iron/node:0.12。你可以在Docker Hub上找到每种语言的所有版本标签。比如Node的标签: https://hub.docker.com/r/iron/node/tags/。你能从iron-io/dockers 项目里找到其他所有Docker Hub tags的链接。

如何为所有语言构建和打包?

这下可能不再走运了,但我们也有一些使用以上最主要语言的基础镜像的例子:

https://github.com/iron-io/dockerworker

如果你在仓库中查看每种语言的README ,它将指导你如何构建依赖,测试你的代码,构建一个小的Docker镜像并且测试镜像。

不再回头

读完这篇文章后,你应该能够为你的应用容器创建Docker镜像,其中只包含运行应用所必需的内容。容器本质上是一个镜像的实例,所以一旦开始使用镜像运行容器,你就已经进入了微容器的世界。而且不再回头。

原文链接:https://dzone.com/articles/microcontainers-tiny-portable-docker-containers

暂无评论

发表评论