[流行技术分享] Docker 印象

Docker横空出世后,很快就成为了一个非常流行的部署和运行分布式应用的平台。之所以Docker 能很快火起来,除了solomonstre 的市场营销外,它的确有很多独到之处。这次包子就跟您一起探讨下 Docker 技术,以及经常被一起提及的LXC 技术,希望大家能有所收获。

Docker 初探

什么,你连Docker是神马东西都不知道?没关系,我们就先来科普一下伟大的Container 技术。

Docker 最初的出现是为了解决在软件部署的时候麻烦的依赖和配置问题。我们知道,所有软件的运行都需要一个运行环境,其包括操作系统,软件的依赖库,依赖工具,以及配置等。由于软件在开发,测试到最后部署所用的设备往往都不相同(比如你会在笔记本上开发,在服务器上部署),所以往往应用开发完成后,放入测试环境或者部署到实际的服务器之前需要在目的设备上先部署所有的依赖以及配置。

每次这么做不仅费事费力,容易出错,而且很多时候会有很多难以解决的问题。比如,应用开发人员,可能不太懂得如何对其所部署的服务器进行配置,那么每次部署前得请专业的服务器管理员来帮忙。如果在同一服务器上还运行了其它应用,我们没法保证其他应用不会破坏你所要运行应用的依赖环境,因为他们共享了一个运行环境。

Docker 对这个问题提出了一个很有效的解决方案。他的灵感来自于生活中常见的集装箱。运输公司在运送货物的时候需要借助很多交通工具,比如汽车轮船等。如果直接将货物装入运送工具,那么运输公司就要考虑如何在不同的交通工具上装载每种不同的货物,非常麻烦。集装箱的出现使得运输公司只要关心不同运输工具如何运送集装箱即可-其尺寸,操控都是一致的,而送货的雇主只需关心如何将他的货物装入集装箱,不用担心具体的运输工具。

Docker 就是这样一个软件的集装箱。所有应用开发人员在Docker里面配置好应用的运行环境,而各种设备,以及云服务提供商则负责解决如何将docker 运行在设备或云上,这样以Docker为抽象层,所有问题都解决了。什么?抽象层??对,正如某个计算机大牛所说,任何计算机问题都可以通过增加一个抽象层解决。

Docker 让应用运行在一个配置好的沙盒里,从应用的角度来讲,他所用到的所有资源都是独享的,且应用只能影响它所在docker里面的东西,即它看不到其他docker里面的环境,这起到了隔离的效果。的确,从这点来看,docker 和虚拟机非常类似,但不同的地方是docker是非常非常轻量级的“虚拟机”,因为它不需要像虚拟机一样在上面host 一个完整的OS,相反的,Docker 是完全host 在OS Kernel 上面的(基于LXC container 技术,我们在下面会有具体讲解)。这种应用层的虚拟,将会带来很大的效率提高;而其对比虚拟机唯一的限制也仅仅是同一设备上不同docker 里面的应用必须运行在同一个kernel 上面,而不能跨越操作系统。一般来说,一台服务器中可以同时运行几个到十几个虚拟机,而docker的话往往可以是成百上千个。

Docker 在实际生产中对开发者的帮助是巨大的。开发者在本地开发时,只需从公司的共享中获取预先配置好的docker image,再根据需要调整配置后,面向docker进行应用开发。开发完毕后只需将应用连同整个docker 一同发布到服务器上,不需要额外的配置即可保证其能和本地一样地运行。而当服务器上的某个docker 里面的服务需要调试修BUG时,开发者也不用配置本地开发机,而只需将服务端的docker 整个放到本地调试即可保证和服务端一致的运行结果。

Docker 和 LXC

之前我们讲到Docker 的核心应用的是 container。想必有些同学们会想到另一个类似的技术 LXC(linux container),那么他们到底有何联系又有何异同呢?

我们首先来看一下什么又是Linux Container。LCX 并不是什么新的概念,2008就已经被推出了。LXC的设计是为了提供操作系统级别的虚拟化(最轻量级的“虚拟机”),也就是在一个Linux内核上跑多个Linux环境(比如不同的发行版)。借助Linux 内核的cgroups 功能,LXC可以控制分配给每个container 的硬件资源;而通过namespace isolation 技术,每个container 之间互不干扰,产生虚拟的“独占系统”。

这么看来,Docker 和LXC 之间的确非常相似。没错,Docker 就是基于 LXC 技术的一种特殊应用。当然,这并不是说Docker 就是提供了LXC 的一个管理界面。其实,深入来说,他们的差别还是很大的,虽然docker 用到了LXC。

首先,LXC 的container 比Docker 更类似于虚拟机,在每个container 里面可以跑完整的系统,包括多个前台和后台进程;而Docker 的每一个container 是为了跑单一应用设计的,为了最小化每个container的overhead,docker 推荐每个container 内部尽量少安装不必要的包,而且每个container 尽量只跑一个进程(虽然你也可以跑多个,但是一般情况下不推荐),这就使得每个docker container 更像是一个单一应用的沙盒。

具体举一些例子来说,当docker container 内部的应用挂了需要重启的时候,推荐的做法是重启整个docker 而不是内部的那个应用进程。而当多个应用之间互相需要协同工作的时候(比如web server 和 database),我们需要起多个docker,让web server 和database 分别跑在不同的docker container 里面。这样的做法虽然会有些overhead,但是好处也是显然的:首先每个应用的环境都完全隔离,出错不会互相影响,而且能够相对应用透明地进行scale;其次每个container 启动非常快,而且重用性也提高了不少。

还有一点docker 非常独特的地方是他的文件系统。Docker container的image 的文件系统是由像蛋糕一样的很多层组成。除了最高层是可读可写的之外,其余层都是只读的。任何新内容的添加,和老内容(底层内容)的修改都是在最高层进行写入和覆盖。也就是说这是一个增量式的文件系统,永远不会删除内容,只会不停地在上层叠加修改(有点像version control)。当最上层修改完毕后,你可以将最上层的修改commit进入只读,并产生一个新的可写最上层。这种多层Image的方式可以最大化地对Image重用。比如当你在一台机器上产生一百个不同的基于Ubuntu 的docker cotnainer时,他们只需要一份Ubuntu 的base image,节省了大量的空间。当然,层次过多的文件系统对访问效率会有一定的影响。

更多最新技术分享

不知小编的讲解是否对你有所帮助?如果你还是有些模糊或者意犹未尽,也没有关系。包子在将在最新的课堂中对IT面试所需的各种知识点以及各种流行的服务端技术进行深入浅出地分析。你可以点击这里查看更多。上一期的课程学生满意度100%,而这一次我们不仅对教程再次进行改进,还为团购报名提供了优惠,所以你还在等什么呢?

博客推送