Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口

Docker 官网: https://www.docker.com

Docker 发布2013年

Docker 是 PaaS 提供商 dotCloud 开源的一个基于 LXC 的高级容器引擎,源代码托管在 Github 上, 基于go语言并遵从Apache2.0协议开源。

Docker自2013年以来非常火热,无论是从 github 上的代码活跃度,还是Redhat在RHEL6.5中集成对Docker的支持, 就连 Google 的 Compute Engine 也支持 docker 在其之上运行。

一款开源软件能否在商业上成功,很大程度上依赖三件事:

1)成功的 user case(用例)

2)活跃的社区

3)一个好故事

dotCloud 自家的 PaaS 产品建立在docker之上,长期维护且有大量的用户,社区也十分活跃,接下来我们看看docker的故事。

  • 环境管理复杂 - 从各种OS到各种中间件到各种App,一款产品能够成功作为开发者需要关心的东西太多,且难于管理,这个问题几乎在所有现代IT相关行业都需要面对。

  • 云计算时代的到来 - AWS云服务器的成功,引导开发者将应用转移到 Cloud云服务上, 解决了硬件管理的问题,然而中间件相关的问题依然存在 (所以OpenStack HEAT和 AWS CloudFormation 都着力解决这个问题)。开发者思路变化提供了可能性。

  • 虚拟化手段的变化 - cloud 时代采用标配硬件来降低成本,采用虚拟化手段来满足用户按需使用的需求以及保证可用性和隔离性。然而无论是KVM还是Xen在 docker 看来,都在浪费资源,因为用户需要的是高效运行环境而非OS, GuestOS既浪费资源又难于管理, 更加轻量级的LXC更加灵活和快速

  • LXC的移动性 - LXC在 linux 2.6 的 kernel 里就已经存在了,但是其设计之初并非为云计算考虑的,缺少标准化的描述手段和容器的可迁移性,决定其构建出的环境难于迁移和标准化管理(相对于KVM之类image和snapshot的概念)。docker 就在这个问题上做出实质性的革新。这是docker最独特的地方。

面对上述几个问题,docker设想是交付运行环境如同海运,OS如同一个货轮,每一个在OS基础上的软件都如同一个集装箱,用户可以通过标准化手段自由组装运行环境,同时集装箱的内容可以由用户自定义,也可以由专业人员制造。这样,交付一个软件,就是一系列标准化组件的集合的交付,如同乐高积木,用户只需要选择合适的积木组合,并且在最顶端署上自己的名字(最后个标准化组件是用户的app)。

上述设计思想,便就是基于docker的PaaS产品的原型。

 

官网的介绍是这样的:

Overview

Docker is the world’s leading software container platform. Developers use Docker to eliminate “works on my machine” problems when collaborating on code with co-workers. Operators use Docker to run and manage apps side-by-side in isolated containers to get better compute density. Enterprises use Docker to build agile software delivery pipelines to ship new features faster, more securely and with confidence for both Linux and Windows Server apps.

What is a Container?

Using containers, everything required to make a piece of software run is packaged into isolated containers. Unlike VMs, containers do not bundle a full operating system - only libraries and settings required to make the software work are needed. This makes for efficient, lightweight, self-contained systems and guarantees that software will always run the same, regardless of where it’s deployed.

其实看完这句话还是不明白究竟是啥的,下面就慢慢解释。不过长话短说的话,把他想象成一个用了一种新颖方式实现的超轻量虚拟机,在大概效果上也是正确的。当然在实现的原理和应用上还是和VM有巨大差别的,并且专业的叫法是应用容器(Application Container)

 

为啥要用容器

那么应用容器长什么样子呢,一个做好的应用容器长得就好像一个装好了一组特定应用的虚拟机一样。

比如我现在想用MySQL那我就找个装好MySQL的容器,运行起来,那么我就可以使用 MySQL了,不用再一步一步繁琐的安装、设置密码和权限等。

那么我直接装个 MySQL不就好了,何必还需要这个容器这么诡异的概念?话是这么说,可是你要真装MySQL的话可能要再装一堆依赖库,根据你的操作系统平台和版本进行设置,有时候还要从源代码编译报出一堆莫名其妙的错误,可不是这么好装。而且万一你机器挂了,所有的东西都要重新来,可能还要把配置在重新弄一遍。

但是有了容器,你就相当于有了一个可以运行起来的虚拟机,只要你能运行容器,MySQL的配置就全省了。而且一旦你想换台机器,直接把这个容器端起来,再放到另一个机器就好了。硬件、操作系统、运行环境什么的都不需要考虑了

在公司中的一个很大的用途就是可以保证线下的开发环境、测试环境和线上的生产环境一致。当年在 Baidu 经常碰到这样的事情,开发把东西做好了给测试去测,一般会给一坨代码和一个介绍上线步骤的上线单。结果代码在测试机跑不起来,开发就跑来跑去看问题,一会儿啊这个配置文件忘了提交了,一会儿啊这个上线命令写错了。找到了一个 bug 提上去,开发一看,啊我怎么又忘了把这个命令写在上线单上了。类似的事情在上线的时候还会发生,变成啊你这个软件的版本和我机器上的不一样……在 Amazon 的时候,由于一个开发直接担任上述三个职位,而且有一套自动化部署的机制所以问题会少一点,但是上线的时候大家还是胆战心惊。

如果利用容器的话,那么开发直接在容器里开发,提测的时候把整个容器给测试,测好了把改动改在容器里再上线就好了。通过容器,整个开发、测试和生产环境可以保持高度的一致。(米扑博客评论:这个想法其实很容易想到,但能够做出来,的确是一门技术活)

此外容器也和VM一样具有着一定的隔离性,各个容器之间的数据和内存空间相互隔离,可以保证一定的安全性。

 

那为啥不用VM

那么既然容器和 VM 这么类似为啥不直接用 VM 还要整出个容器这么个概念来呢?

Docker 容器相对于 VM 有以下几个优点:

1)启动速度快,容器通常在一秒内可以启动,而 VM 通常要更久

2)资源利用率高,一台普通 PC 可以跑上千个容器,你跑上千个 VM 试试

3)性能开销小, VM 通常需要额外的 CPU 和内存来完成 OS 的功能,这一部分占据了额外的资源

为啥相似的功能在性能上会有如此巨大的差距呢,其实这和他们的设计的理念是相关的。

VM 的设计图如下:

docker-what-is-01

VM 的 Hypervisor 需要实现对硬件的虚拟化,并且还要搭载自己的操作系统(Host OS是宿主机系统,Guest OS是虚拟机系统),自然在启动速度和资源利用率以及性能上有比较大的开销。

Docker 的设计图是这样的:

docker-what-is-02

Docker 几乎就没有什么虚拟化的东西,并且直接复用了 Host 主机的 OS(只有Host OS系统,没有Guest OS),在 Docker Engine 层面实现了调度和隔离重量一下子就降低了好几个档次。

Docker 的容器利用了 LXC,管理利用了 namespaces 来做权限的控制和隔离, cgroups 来进行资源的配置,并且还通过 aufs 来进一步提高文件系统的资源利用率。

其中的 aufs 是个很有意思的东西,是 UnionFS 的一种。他的思想和 git 有些类似,可以把对文件系统的改动当成一次 commit 一层层的叠加。这样的话多个容器之间就可以共享他们的文件系统层次,每个容器下面都是共享的文件系统层次,上面再是各自对文件系统改动的层次,这样的话极大的节省了对存储的需求,并且也能加速容器的启动。

 

下一步

有了前面的这些介绍,应该对 Docker 到底是啥有些了解了吧,

Docker 是 用 Go 语言编写的,源代码托管在 github 而且居然只有 1W 行就完成了这些功能。

如果想尝试一下的话可以看官方介绍了,应该上手会容易一些了。

 

 

参考推荐

Docker资料集粹

什么是Docker(原文)

后台服务器开发总结推荐

Jetty 工作原理以及与 Tomcat 的比较

VPS 虚拟化架构 OpenVZ 和 KVM 区别

运维人员常用软件总结

Apache、Nginx、Tomcat 区别

Apache 和 Nginx 对比

Servlet 工作原理解析

Java Web Servlet 运行原理详解

Spring Boot 入门

Jetty 工作原理以及与 Tomcat 的比较

Tomcat 系统架构与设计模式:工作原理

Tomcat 系统架构与设计模式:设计模式分析