如何创建安全的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#