docker介绍
之前在一个项目中接触到了docker,所以学习了下,最近看到之前的资料突发奇想整理一下,采用两个生活化的例子来描述。
1、docker诞生的背景
我们知道程序员开发出系统之后,并不能直接上线的,它需要经过测试人员的测试,运维人员的熟悉等等,最终才可以上线。那么一个大规模的系统,肯定需要各种各样复杂且庞大的环境做支撑,所以存在一个问题就是,程序员搭建环境后进行开发,开发结束后交付给测试人员,他们在测试之前自然也是需要搭建环境的,等测试结束后转到运维部分,他们还是需要搭建环境。这样一来,环境的搭建就是一个相当冗余,并且耗费时间精力人力的一件事情。
用过VMware的朋友自然会想到,开发人员部署一个虚拟机vm1,在开发完成后测试部分和运维部门直接克隆vm1不就行了吗?确实,这种方法的确可以解决。但仍然存在一个问题,就是内存资源的浪费与时间的开销,具体来讲:
首先我们要知道,VMware在宿主机、宿主机操作系统的基础上,创建虚拟层Hypervisor(用来为每个虚拟机动态分配计算资源),然后每个虚拟机(.vm)创建独立的操作系统、仓库、应用等。要知道,宿主机的硬盘空间与内存是由不同的虚拟机共享的,硬盘空间一般较大此处先不说,就拿内存来说。开头的例子暂且先不考虑是大型系统的部署,就拿日常学习使用的虚拟机来说,笔者的笔记本(加装了最大容量的内存条,32G)克隆2-3个虚拟机后就明显感觉网络较慢,应用启动较卡。因为内存是临时存储CPU计算所需的数据,并与硬盘等外存储器交换数据,内存性能的强弱会直接影响到计算机整体发挥的水平与用户的使用体验。那么问题就来了,我们要部署使用的是应用程序,而不是操作系统;
其次,一个虚拟机的开启,意味着重新开启了一台机器,也就是说从操作系统到应用层都要逐个加载,毕竟操作系统是很笨重的。
那么,能否避免内存浪费在操作系统的这一现象?以及快速启动,提升用户体验?容器技术就诞生了。
2、容器Container
感兴趣的朋友可以去看看Container的官方解释:什么是容器? - 中国 | IBM,此处为了便于理解笔者直接拿生活中的例子说明。
假设现在有3名厨师,客人点了3道菜,分别是法式牛排、红烧牛肉、牛肉串,餐厅分别为3名厨师提供了1间厨房。这家餐厅的老板只研究过VMware虚拟化技术,因此他采用VMware的经营模式,为3名厨师准备了一样的材料与工具,那为了确保满足每位厨师的需求,他需要准备的材料是3道菜所需材料的并集。这样一来,虽然确保每位厨师都能做出对应的菜,但会存在一个问题,可能法式牛排的某些材料或者工具,红烧牛肉与牛肉串的制作压根用不上,那对于后两位厨师来说,是不是就占用了多余的资源,对于老板来说,是不是付出了没必要的成本?
后来老板也发现了这个问题,所以他钻研了容器Container技术,并不会像之前一样直接给厨师提供所有的材料与工具,而是除了3名厨师要公用的水电、牛肉等材料外,其余的材料会放在一起,每位厨师根据自己的实际需求来获取,这样一来大大减少了费用与资源的使用。
现代开发的原则之一就是隔离,上述例子中每个厨师一间厨房就是隔离的体现,3名厨师各自工作互不影响。Container就是这样,与VMware最大区别就是,它只隔离应用程序的运行环境(运行环境指的就是程序运行时依赖的所有库以及各种配置),但容器之间可以共享一个操作系统。因此,容器被称为一种轻量级的虚拟化技术,占用的资源更少,与VMware数G的内存占用相比,容器技术只需数M空间,因此我们可以在同样规格的硬件上大量部署容器,这是虚拟机所不能比拟的,而且容器的启动时间几乎是瞬时启动。
而容器只是一种通用技术,要实际使用的话必须了解docker,docker是容器技术的一种实现方式。
3、Docker
docker会将程序以及程序所有的依赖项都打包到docker container中,这样程序就可以在任何的环境都有一致性的表现。另外,其具有快速部署的特点,对应于开篇的例子,开发人员只需要将开发的系统以及所有基于环境的配置都打包为一个docker,测试人员与运维人员可以用它直接完成部署,无需自己重新配置环境,而且其启动速度十分快,满足用户的使用体验。
在docker中,有3个概念是务必要清楚的:镜像制作文件dockerfile、镜像image、容器container。笔者继续拿2中厨师的例子进行描述:
现在,每个厨师根据自己的需求拿到对应的材料,然后在各自的厨房做菜,我们知道每道菜的制作都是有一定步骤的,按照菜谱的说明,首先要具备什么什么材料,什么什么工具,然后烧水等一步一步进行,那么此处的菜谱就相当于是镜像制作文件dockerfile。做好菜后每位厨师为了纪念自己的作品,会给菜拍照,此处的照片就相当于上述的镜像image,每个镜像都是独一无二的,并且镜像就是一个相对静态的文件。
4、Docker工作流程
综上所述,目前的image就是一件成品,在开篇的例子中就是程序员做好的可执行文件;dockerfile就是该文件的源代码;container就是将其运行起来的进程;而docker就是编译器,结合其工作流程是这样的:
(1)首先需要在dockerfile中指定需要哪些程序、依赖什么样的配置,之后把dockerfile交给“编译器”docker进行“编译”,也就是docker build命令,生成的可执行程序就是image;
(2)然后运行image了,这就是docker run命令,image执行起来就是所谓的container。
既然image是一种可执行程序,那么自然会有类似于应用商店的地方——Docker Hub,我们可以在这里下载别人编写好的image,下载命令就是docker pull。
具体的使用方法就不再这里赘述了,大家可以参考docker的官方文档(英文:Docker Docs: How to build, share, and run applications;中文:Docker中文网 官网 (p2hp.com))。