假设现在有一个厨艺比赛,比赛的菜式是做鸡,但是选手们需要做不同的鸡,每个选手对鸡的要求都不一样,主办方为了选手们可以完美进行比赛,主办方为每个选手准备了独立的厨房。
但问题是如果选手只做白斩鸡,你却给了他做炸鸡的面粉和其它不用的材料,这样就浪费掉了。
上述问题其实就和虚拟机差不多,如果有些应用需要安装python2,有些要python3,虚拟机虽然可以创建独立的环境,使得每个环境都有各自的python版本,但是每个环境都有自己的客户机操作系统,占用非常大的资源和空间。例如,想要使用python2那么我们可能需要再Centos操作系统上使用,如果需要使用python3,那么我们可能需要在Windows操作系统上使用。
要解决这个问题,就要用到Docker了
上面的厨艺比赛中,选手们依旧会有独立的厨房,但现在的厨房并不会有全套的厨具和材料,除了最基本的水电是大家共用的,其他东西都是按照实际需求进行提供,Docker也是这样的。
Docker并不需要创建完整的虚拟操作系统,但还是会创建独立的环境,也就是容器(Container),容器里面也是有操作系统的,这样可以跑着各自的应用程序。容器之间共用的是主机的内核,但是容器不会直接访问内核,而是通过Docker引擎来访问。容器里面需要什么应用再根据实际增加。
现在每个选手都在自己的厨房做菜,完成以后会给菜拍照,在这特定厨房,根据特定步骤和材料做出来的菜,每个选手都是独一无二的。这张照片就相当于Docker里的镜像Image。
各种版本的应用就定格形成了镜像,如果其中有一个应用或者多个应用的版本不一样,就是另一个镜像了。镜像是一个相对静态的东西,要让镜像"动起来",也就是说我们可以根据不同的镜像,运行在不同的容器里面,做到相互隔离。
厨师根据特定步骤和材料做菜,也就是根据不同的菜谱,比如,第一步烧开水,第二步给鸡泡水,第三步给鸡去毛。
这个菜谱就相当于 制作镜像 的 Dockerfile 了
每个镜像的Image的形成需要特定步骤,因为我们需要指明用什么操作系统、应用版本、各种指令
如果你在特定的操作系统使用指定版本的应用以及各种依赖,那么我们就可以把这些给写入Dockerfile,也就像写进我们的菜谱里面。
要真正形成一个镜像,我们需要使用docker build 命令来构建,这个时候Docker 引擎就会构建镜像。但是这个时候这个镜像还是没有运行的,就如同给做好的菜拍了照片而已。要运行我们需要使用docker run 命令,这个命令让Docker引擎为我们分配一个新的容器。一个镜像分别可以在多个容器里面运行。