刚接触docker的时候难免陷入术语和概念的泥潭,对boot2docker、docker machine、docker toolbox这些概念傻傻分不清楚。尤其是docker for windows和docker for mac出来后,更是遭遇老技术还未完全理解,又被新技术砸晕的连环打击。

摸索一段时间后,总算对这些概念建立了结构框架,大致理解如下:

  • host: 宿主机器,也可指宿主系统,直接安装在裸机上的操作系统,比如我们的开发机win10或mac,服务器则一般是linux
  • docker image: 一个打包文件,里面其实是一整套文件系统,这个文件系统中安装着某个linux发布版,但不包括内核(因为内核还是用host的内核)
  • docker container: 把docker image加载到内存里,使其中的程序运行起来,就成了一个docker container。image和container的关系,就像文件和进程的关系。
  • docker engine(daemon): 这就是docker的核心程序,其功能就是加载image为container并运行之,可同时运行多个container并维护其与host的交互(文件、网络)
  • docker client: 也就是我们平时执行的docker命令,它负责收集用户输入并发送给daemon程序去执行,docker client可以连接到不同的daemon,命令是发送给当前正在连接的daemon执行的。具体连接的是哪一个daemon,是由DOCKER_HOST这一环境变量决定的。

docker engine本身只能在linux上运行,它运行的container中的程序也都是linux程序。(现在似乎也出现了windows版的docker engine,其container中自然也都是windows程序)
docker engine并不是虚拟机,每个container并不是一个独立系统,container中的进程是直接运行在host中的,但是docker engine为其设置了namespace属性,使其默认对host不可见,不同container间的进程也互不可见,从而达到隔离效果,这主要是linux内核提供的namespace特性,docker利用此特性,对进程及各种资源做了一些综合管理,就成了container。

到此为止,docker自身算是理清了,那么docker machine又是什么呢?

docker machine的本来目的很简单,是安装管理多台host上的docker engine,将这些host取一个简短的名字方便后续操作。是一个辅助类的自动化小工具。
但docker machine又是最令初学者(我)迷惑的,原因就在于它的某一项子功能,与另一种技术产生了重叠,导致极大的迷惑性。

上面提到,docker engine只能在linux上运行(依赖于linux内核的namespace特性),但我们的开发机多是windows或mac这类桌面系统,docker为了在这些系统上也能运行,就采用了一个极其“没节操”的方法:跑一个虚拟机,虚拟机上运行linux系统,然后再在这个虚拟linux上运行docker engine!为什么说这叫“没节操”呢?因为docker技术本身就是以“踩”虚拟机而出名上位的呀!结果现在倒好,docker在不能原生运行的系统上,反倒要借助虚拟机来当垫脚石了。(以上说辞都是开玩笑,没有贬低docker的意思)

而docker machine,在创建及初始化虚拟机这件事上,恰恰扮演了急先锋的角色。前面说了docker machine的作用是在别的host上安装docker,那这个别的host可以是物理机,自然也可以是虚拟机,反正只要能连上去,又运行的是linux系统,管它是什么机呢?

docker machine的工作流程就是先连上目标机器,然后在上面执行安装配置操作。它通过driver机制来支持多种不同的目标机器连法,比如可以通过ssh连到一台常规linux host上,也可以通过相关sdk连到一些docker云平台上,更有甚者,它还有一种叫vm的driver,是直接在本地创建一个虚拟机,然后连上这个虚拟机,在上面安装docker engine。而这也正是在windows/mac上运行docker的传统做法。

既然要创建虚拟机,那总要有一个安装盘(iso文件),而且还得是一个linux系统的iso,这个东西,就是所谓的boot2docker.iso啦,也就是说boot2docker其实是一个专为虚拟机环境定制的linux系统,相比一般linux发行版来说极尽简化,一切只为保障能运行docker engine而已。所以我们在windows上看到、用到的docker machine,其实只是docker machine全部中的一小部份,但是这一小部份做的事也够多了:

  • 利用virtualbox去创建一个虚拟机(也可以选择其它虚拟机驱动,比如hyperkit等等)
  • 在这个虚拟机上安装boot2docker.iso,得到一个精简的linux系统
  • 在这个linux系统上安装docker engine

因为仅仅一小部份的功能就如此强大,连虚拟机安装都一手包办,难免是会让人心生误解,以为它就是一个专门的虚拟机软件,毕竟名字里都还有machine这个词哇。而且最要命的是,之所以去学docker明明就是因为docker宣称自己跟虚拟机不一样,性能比虚拟机强,结果给初学者的第一个见面礼居然就是把自己装在虚拟机里,这简直就是对人理解能力的致命打击。

好在现在已经从这个坑里爬上来了,也知道了docker machine究竟为何物,那么docker toolbox又是什么?就更简单了,它就是docker、docker-machine、boot2docker和virtualbox的一个套装!接着看docker for windows/mac又有什么不一样呢?差别就在于虚拟机的创建方式,docker toolbox是打包了一个virtualbox来建虚拟机,用docker machine去连接管理虚拟机,而windows和mac系统现在都有自己的原生虚拟机API,如win10上的hyperV和mac上的Hypervisor,所以就没有必要再用virtualbox这种第三方虚拟机软件了,而是通过系统API直接操作虚拟机,想必性能高不少,而且依赖也少了使用起来更方便。但总的来说,因为docker的主战场是linux,且实际项目里host并非虚拟机(云主机也许也是虚拟机,但不是这个意义上的虚拟机了),所以用docker machine来管理多台host仍是首选,而docker for windows/mac看似是新推出的技术,但主要是为了开发者在本地调试的方便,并不能取代docker machine。

因此,我现在即使在开发机上使用docker,仍然倾向于用“老式”的docker machine来安装管理,理由是:
1、要管理多个docker daemon,只能用docker machine
2、以后在线上环境管理,也是用docker machine,不如早在开发过程中熟悉它
3、真要用docker for windows的话,要打开hyperV功能,而很多其它软件跟这个功能冲突,比如androidstudio的模拟器,要想在一台机器同时开发前后端,只能用回virtualbox了