如何创建安全的Docker基础映像

# #背景# #

我第一次用Docker的时候,大家都在说它有多好用,它的内部机制有多好,它为我们节省了多少时间。但是我一用就发现几乎所有的图片都臃肿不安全(不使用包签名,就盲目相信上游的图片库是

| sh & lt/code & gt;而且,没有一个镜像能够实现Docker的初衷:隔离、单一进程、易分发、简单。

Docker image最初并不是为了取代复杂的虚拟机而设计的,它拥有完整的日志、监控、报警和资源管理模块。另一方面,Docker倾向于利用内核的

在物理机器环境中,一旦内核被初始化,

这就是为什么当你在Dockerfile

现在请检查您的流程列表并使用

如何开始?

现在的应用大多是大型复杂系统,通常需要很多依赖库,比如调度、编译等很多相关的工具应用。它们的架构通常封装得很好,底层细节隐藏在抽象层和接口中。某种程度上,这也是一个容器,但从系统架构的角度,我们需要一个比之前的虚拟环境更简单的解决方案。

以Java为例。

从头开始,想想你要构建一个最通用的基本容器,想想你的应用程序本身,它需要运行什么?

有很多种可能。如果你想运行一个Java应用程序,它需要一个Java运行时。如果你运行一个Rails应用程序,它需要一个Ruby解释器,Python应用程序也是如此。Go和其他一些编译语言有点不同,下面我会提到。

在Java示例中,下一步是考虑:JRE需要运行哪些依赖项?因为它是让应用程序运行的最重要的组件,自然下一步就是弄清楚JRE依赖于什么。

其实JRE并没有太大的依赖性。它原本是操作系统的一个抽象层,使得代码独立于主机系统运行,所以安装JRE的时候就基本准备好了。

(其实操作系统的独立性并不是理所当然的。有许多特定于系统的API和专有系统扩展,但是为了举例,我们将把重点放在简单的情况上。)

在Linux上,JVM主要调用系统的C语言库,Oracle的官方JRE使用的是libc,也就是说如果要运行任何Java程序,都需要先安装glibc。另外,你可能需要某种shell来管理环境,有一个接口来和外界交流,比如网络和资源的接口。

让我们总结一下Java应用程序示例所需的最低配置:

在示例中,我们使用Oracle JRE。

Glibc,JRE依赖

基本环境(包括网络、内存、文件系统和其他资源管理工具)

#走进阿尔卑斯Linux ##

Alpine Linux最近受到了很多关注,主要是因为它封装了一系列已经验证的可信依赖项,并且依然保持了2MB的体积!在本文发布时,其他镜像发行版如下:

Ubuntu:最新:66MB(瘦了不少,之前的一些版本超过了600MB)

Debian:最新:55MB(同上,一开始是200多MB)

arch:最新:145MB

Busybox:最新:676KB(对!KB,我以后再讨论)

Alpine:最新:2MB (2MB,带包管理工具的Linux系统)

** Busybox是最小的竞争对手?**

从上面的对比可以看出,唯一能在大小上打败Alpine Linux的是Busybox,所以现在几乎所有的嵌入式系统都在用它,它被应用到路由器,交换机,ATM,或者你的烤面包机。作为最基本的环境,它提供了一个易于维护的shell接口。

网上有很多文章解释了为什么人们选择Alpine Linux而不是Busybox。我在这里总结一下:

开放而活跃的软件包仓库:Alpine

Linux使用apk包管理工具,集成在Docker镜像中,而Busybox需要安装另一个包管理器,比如opkg。更重要的是,你需要找到稳定的包仓货源(这种货源几乎没有)。Alpine的包仓库提供了大量常用的依赖包。比如,如果还需要在容器中编译nodejs或者ruby之类的代码,可以直接运行apk添加NodeJS和Ruby。

体积确实很重要,但是当你在功能性、灵活性、易用性和1.5MB之间衡量的时候,体积就没那么重要了。Alpine上增加的包大大增强了这些方面。

广泛支持:Docker已经聘请了Alpine Linux的作者进行维护,未来所有官方镜像都将基于Alpine Linux构建。没有更有说服力的理由让你在自己的容器中使用它。

云曦cSphere很早就意识到镜像日益严重的问题,所以在去年推出了微镜像,这也是为了指导大家如何更好地构建和理解镜像。镜像只是一种软件包格式。

* *构建基于Java环境映像* *

正如我刚才解释的,在构建自己的映像时,Alpine Linux是一个不错的选择,因此我们将在这里使用它来构建一个简单高效的Docker映像。我们开始吧!

组合:阿尔卑斯+bash

每个Dockerfile的第一条指令是指定它的父容器,在我们的例子中,它通常用于继承

来自阿尔卑斯山:最新

维护者docker@csphere.cn

我们还声明谁对该图像负责,并且该信息对于上传到Docker Hub的图像是必要的。

这样,你接下来的操作就有了基础。接下来,安装我们选择的shell并添加以下命令:

运行apk add-no-cache-update-cache bash

CMD ["/bin/bash"]

最终的docker文件如下所示:

``嘘

来自阿尔卑斯山:最新

维护者cSphere & ltdocker@csphere.cn & gt;

运行apk add-no-cache-update-cache bash

CMD ["/bin/bash"]

```

好了,现在让我们来构建容器:

$ docker build-t my-Java-base-image。

将构建上下文发送到Docker守护程序2.048 kB

步骤1:来自阿尔卑斯山:最新

-& gt;2314ad3eeb90

第二步:维护者CSP here docker@csphere.cn

-& gt;在63433312d77e中运行

-& gt;bfe94713797a

拆卸中间容器63433312d77e

...省略几行

第四步:CMD /bin/bash

-& gt;在d2291684b797中运行

-& gt;ecc443d68f27

拆卸中间容器d2291684b797

成功构建ecc443d68f27

并运行它:

$ docker run-RM-ti my-Java-base-image

bash-4.3#