看了一圈答案,都没有感觉比较满意的。
当然,如果想一两句话给个定义,或者用一个大家熟悉的东西打个比方来说明Docker, @刘允鹏 的高赞答就很好。但个人感觉还是没有完整的解释清楚Docker,自己开一个回答补充一下。
要解释清楚Docker,首先要说解释清楚容器(Container)的概念。要解释容器的话,需要从操作系统说起。太深入的一两本书都说不清楚,直接引用维基的说法,操作系统就是管理计算机的硬件软件和资源,并且为软件运行提供通用服务的系统软件。
硬件、操作系统、应用程序之间的关系可以简单的用下图表示:
+--------------------------+ | Applications | +--------------------------+ |+------------------------+| || Runtime Library || |+------------------------+| || Kernel || |+------------------------+| | Operating System | +-----+--------+-----------+ | CPU | Memory | IO Device | +-----+--------+-----------+
随着硬件的性能提升,以及软件种类的丰富,有两种情况变得很常见:
为了解决软件冲突,只能配置多台计算机,或者很麻烦的在同一台电脑上安装多个操作系统,通过重启来进行切换。显然这两个方案都有其缺点:多台计算机成本太高,多操作系统的安装、切换都很麻烦。在硬件性能过剩的时候,硬件虚拟化的普及就很自然而然的提出来了。
所谓硬件虚拟化,就是某个特殊的软件,仿真出一台或者多台计算机的各种硬件,用户可以在这一台虚拟机上安装、运行操作系统(一般叫来宾操作系统,Guest OS)和各种应用,并且把Guest OS和上面应用软件对硬件资源的访问转发到底层的硬件上来实现。对于Guest OS和上面的应用程序来说,这台虚拟机和普通的物理计算机是完全一样没有任何区别的——除了性能可能差一点。著名的VMware就是这么一个软件,这类软件英语有一个专用的单词是Hypervisor(维基的Hypervisor词条说另一种叫法是虚拟机监视器,Virtual Machine Monitor,vmm。但我个人觉得叫虚拟机管理器,Virtual Machine Manager,更合适一点,虽然可能会和微软的System Center Virtual Machine Manager以及Redhat的Virtual Machine Manager这两个软件混淆),中文大概应该叫虚拟化软件/应用之类的。
Hypervisor根据其对硬件资源的访问方式,可以分为两大类,Type I是Hypervisor直接访问硬件资源,通常会有另一个操作系统运行于Hypervisor之上来对硬件资源,例如VMware EXSi,Windows的Hyper-V,Linux的Xen;Type II是Hypervisor和普通的应用一样,运行在某个操作系统(例如Windows或者Linux等,这里称之为宿主机操作系统,Host OS)之上,Hypervisor通过Host OS访问硬件资源,例如VMware Workstation,Virtual Box等。两种类型的Hypervisor区别如图所示。
+-----+-----+-----+-----+ |App A|App B|App C|App D| +-----+-----+-----+-----+ +-----+-----+-----+-----+ |App A|App B|App C|App D| |Guest|Guest|Guest|Guest| +-----+-----+-----+-----+ | OS0 | OS1 | OS2 | OS3 | |Guest|Guest|Guest|Guest| +-----+-----+-----+-----+ | OS0 | OS1 | OS2 | OS3 | | Hypervisor | +-----+-----+-----+-----+ +-----------------------+ | Hypervisor | | Host OS | +-----------------------+ +-----------------------+ | Hardware | | Hardware | +-----------------------+ +-----------------------+ Type I Type II
虚拟机的一个缺点在于Guest OS通常会占用不少硬件资源。例如Windows安装开机不运行任何运用,就需要占用2~3G内存,20~30G硬盘空间。即使是没有图形界面的Linux,根据发行版以及安装软件的不同也会占用100~1G内存,1~4G硬盘空间。而且为了应用系统运行的性能,往往还要给每台虚拟机留出更多的内存容量。虽然不少Hypervisor支持动态内存,但基本上都会降低虚拟机的性能。如果说这样的资源占用少量的虚拟机还可以接受的话,同时运行十数台数十台虚拟机的时候,浪费的硬件资源就相当可观了。通常来说,其中相当大部分甚至全部Guest OS都是相同的。
能不能所有的应用使用同一个的操作系统减少硬件资源的浪费,但是又能避免包括运行库运行库在内的软件冲突呢?操作系统层虚拟化——容器概念的提出,就是为了解决这个问题。在Linux可以通过控制组(Control Group,通常简写为cgroup)隔离,并把应用和运行库打包在一起,来实现这个目的。容器和Type II虚拟机、物理机的区别见下图:
+-----+-----+-----+-----+ +-----+-----+-----+-----+ |App A|App B|App C|App D| +-----+-----+-----+-----+ |App A|App B|App C|App D| +-----+-----+-----+-----+ |App A|App B|App C|App D| +-----+-----+-----+-----+ |+---------------------+| +-----+-----+-----+-----+ |Guest|Guest|Guest|Guest| || Runtime Library || |Lib A|Lib B|Lib C|Lib D| | OS0 | OS1 | OS2 | OS3 | |+---------------------+| +-----+-----+-----+-----+ +-----+-----+-----+-----+ || Kernel || | Container Engine | | Hypervisor | |+---------------------+| +-----------------------+ +-----------------------+ | Operating System | | Host OS | | Host OS | +-----------------------+ +-----------------------+ +-----------------------+ | Hardware | | Hardware | | Hardware | +-----------------------+ +-----------------------+ +-----------------------+ Physical Machine Container Type II Hypervisor
上图中,每一个App和Lib的组合,就是一个容器。也就是Docker图标里面的一个集装箱。和虚拟机相比,容器有以下优点:
当然,和虚拟机相比,因为共用内核,只靠cgroup隔离,应用之间的隔离是不如虚拟机彻底的,如果某个应用运行时导致内核崩溃,所有的容器都会崩溃。而虚拟机内的应用崩溃,理论上是不会影响其它虚拟机以及上面运行的应用的,除非是硬件或者Hypervisor有Bug。
Docker把App和Lib的文件打包成为一个镜像,并且采用类似多次快照的存储技术,例如aufs/device mapper/btrfs/zfs等,可以实现:
+---------+ +---------+ +---------+ +-----+ +-----+ +-----+ | abc.com | | def.com | | xyz.com | | DB1 | | DB2 | | DB3 | +----+----+ +----+----+ +----+----+ +--+--+ +--+--+ +--+--+ | | | | | | +----+----+ +----+----+ +----+----+ +--+--+ +--+--+ +--+--+ | abc | | def.com | | xyz.com | | DB1 | | DB2 | | DB3 | | config | | config | | config | | conf| | conf| | conf| | data | | data | | data | | data| | data| | data| +----+----+ +----+----+ +----+----+ +--+--+ +--+--+ +--+--+ | | | | | | +------------+------------+ +-------+-------+ | | +------+------+ +------+------+ | Nginx Image | | MySQL Image | +------+------+ +------+------+ | | +----------------+----------------+ | +------+-------+ | Alpine Image | +------+-------+
上图是基于一个Alpine Linux的镜像,分别建立了Nginx和MySQL的镜像,并且挂载不同的配置/数据同时运行3个网站应用3个数据库应用的示意图。
此外,Docker公司提供公共的镜像仓库(Docker称之为Repository),Github connect,自动构建镜像,大大简化了应用分发、部署、升级流程。加上Docker可以非常方便的建立各种自定义的镜像文件,这些都是Docker成为最流行的容器技术的重要因素。
通过以上这些技术的组合,最后的结果就是,绝大部分应用,开发者都可以通过docker build创建镜像,通过docker push上传镜像,用户通过docker pull下载镜像,用docker run运行应用。用户不需要再去关心如何搭建环境,如何安装,如何解决不同发行版的库冲突——而且通常不会需要消耗更多的硬件资源,不会明显降低性能。这就是其他答主所说的标准化、集装箱的原因所在。
题外话:除了Docker以外,还有其它很多种容器,例如Linux上的LXC、OpenVZ,FreeBSD的Jail,Solaris的Zones等等。此外,Unix-Like操作系统的chroot命令从某种角度来说也是一种特殊的容器实现方式。和*nix采用宏内核,且内核和各种运行库耦合松散,很方便实现容器不同,Windows因为采用微内核,且内核与各种运行库耦合紧密,虽然从Windows 10/2016开始也支持容器,但事实上还是通过Hyper-V运行不同的虚拟机进行内核级隔离——虽然也有线程级的隔离,但只有Windows Server支持,并且只能运行相同版本的镜像[1]。而且即使是Hyper-V,也只支持运行更低版本的镜像而不能运行更高版本的镜像。另外Windows容器的镜像体积通常还是很大。
2010年,几个搞IT的年轻人,在美国旧金山成立了一家名叫“dotCloud”的公司。
这家公司主要提供基于PaaS的云计算技术服务。具体来说,是和LXC有关的容器技术。
后来,dotCloud公司将自己的容器技术进行了简化和标准化,并命名为——Docker。
Docker技术诞生之后,并没有引起行业的关注。而dotCloud公司,作为一家小型创业企业,在激烈的竞争之下,也步履维艰。
正当他们快要坚持不下去的时候,脑子里蹦出了“开源”的想法。
什么是“开源”?开源,就是开放源代码。也就是将原来内部保密的程序源代码开放给所有人,然后让大家一起参与进来,贡献代码和意见。
有的软件是一开始就开源的。也有的软件,是混不下去,创造者又不想放弃,所以选择开源。自己养不活,就吃“百家饭”嘛。
2013年3月,dotCloud公司的创始人之一,Docker之父,28岁的Solomon Hykes正式决定,将Docker项目开源。
不开则已,一开惊人。
越来越多的IT工程师发现了Docker的优点,然后蜂拥而至,加入Docker开源社区。
Docker的人气迅速攀升,速度之快,令人瞠目结舌。
开源当月,Docker 0.1 版本发布。此后的每一个月,Docker都会发布一个版本。到2014年6月9日,Docker 1.0 版本正式发布。
此时的Docker,已经成为行业里人气最火爆的开源技术,没有之一。甚至像Google、微软、Amazon、VMware这样的巨头,都对它青睐有加,表示将全力支持。
Docker火了之后,dotCloud公司干脆把公司名字也改成了Docker Inc. 。
Docker和容器技术为什么会这么火爆?说白了,就是因为它“轻”。
在容器技术之前,业界的网红是虚拟机。虚拟机技术的代表,是VMWare和OpenStack。
相信很多人都用过虚拟机。虚拟机,就是在你的操作系统里面,装一个软件,然后通过这个软件,再模拟一台甚至多台“子电脑”出来。
在“子电脑”里,你可以和正常电脑一样运行程序,例如开QQ。如果你愿意,你可以变出好几个“子电脑”,里面都开上QQ。“子电脑”和“子电脑”之间,是相互隔离的,互不影响。
虚拟机属于虚拟化技术。而Docker这样的容器技术,也是虚拟化技术,属于轻量级的虚拟化。
虚拟机虽然可以隔离出很多“子电脑”,但占用空间更大,启动更慢,虚拟机软件可能还要花钱(例如VMWare)。
而容器技术恰好没有这些缺点。它不需要虚拟出整个操作系统,只需要虚拟一个小规模的环境(类似“沙箱”)。
它启动时间很快,几秒钟就能完成。而且,它对资源的利用率很高(一台主机可以同时运行几千个Docker容器)。此外,它占的空间很小,虚拟机一般要几GB到几十GB的空间,而容器只需要MB级甚至KB级。
正因为如此,容器技术受到了热烈的欢迎和追捧,发展迅速。
我们具体来看看Docker。
大家需要注意,Docker本身并不是容器,它是创建容器的工具,是应用容器引擎。
想要搞懂Docker,其实看它的两句口号就行。
第一句,是“Build, Ship and Run”。
也就是,“搭建、发送、运行”,三板斧。
举个例子:
我来到一片空地,想建个房子,于是我搬石头、砍木头、画图纸,一顿操作,终于把这个房子盖好了。
结果,我住了一段时间,想搬到另一片空地去。这时候,按以往的办法,我只能再次搬石头、砍木头、画图纸、盖房子。
但是,跑来一个老巫婆,教会我一种魔法。
这种魔法,可以把我盖好的房子复制一份,做成“镜像”,放在我的背包里。
等我到了另一片空地,就用这个“镜像”,复制一套房子,摆在那边,拎包入住。
怎么样?是不是很神奇?
所以,Docker的第二句口号就是:“Build once,Run anywhere(搭建一次,到处能用)”。
Docker技术的三大核心概念,分别是:
我刚才例子里面,那个放在包里的“镜像”,就是Docker镜像。而我的背包,就是Docker仓库。我在空地上,用魔法造好的房子,就是一个Docker容器。
说白了,这个Docker镜像,是一个特殊的文件系统。它除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(例如环境变量)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
也就是说,每次变出房子,房子是一样的,但生活用品之类的,都是不管的。谁住谁负责添置。
每一个镜像可以变出一种房子。那么,我可以有多个镜像呀!
也就是说,我盖了一个欧式别墅,生成了镜像。另一个哥们可能盖了一个中国四合院,也生成了镜像。还有哥们,盖了一个非洲茅草屋,也生成了镜像。。。
这么一来,我们可以交换镜像,你用我的,我用你的,岂不是很爽?
于是乎,就变成了一个大的公共仓库。
负责对Docker镜像进行管理的,是Docker Registry服务(类似仓库管理员)。
不是任何人建的任何镜像都是合法的。万一有人盖了一个有问题的房子呢?
所以,Docker Registry服务对镜像的管理是非常严格的。
最常使用的Registry公开服务,是官方的Docker Hub,这也是默认的 Registry,并拥有大量的高质量的官方镜像。
完整文章: