在开始谈docker容器以前,先须要清楚什么是虚拟化,什么是容器docker
若是要⽤简单的语句来阐述虚拟化技术的话,那么能够这么解释: 虚拟化技术是⼀种将计算机物理资源进⾏抽象、转换为虚拟的计算机资源提供给程序使⽤的技术。 这⾥所指的计算机资源,就包括了 CPU 提供的运算控制资源,硬盘提供的数据存储资源,⽹卡提供的⽹络传输资源等。 编程
计算机发展早期,各种计算机平台,计算资源所提供的接口都不同,调用十分混乱,没有像今天同样有相对统一的标准。因为为兼容不一样的平台写各类各样的兼容代码,因而虚拟技术运应而生。虚拟化技术经过自己适配不一样平台的硬件,抽象成统一的接口,从而实现程序的跨平台。安全
在虚拟化技术发展的过程当中,人们又发现了虚拟化技术的另一个用途:资源管理。 由于虚拟化技术原本就是对计算机物理资源的抽象转换成虚拟的计算机资源,这样就很容易在这里对计算机资源进行修改,好比能够告诉程序这台计算机只有4G内存,而不管计算机是有16G仍是32G,程序都会按照虚拟机告诉它的4G内存来进行使用。 经过虚拟化技术管理计算机资源的方式,不当能让咱们对计算机资源的控制更加灵活,并且还能极大的提交计算机资源的使用率。 看到这可能会有些迷惑,虚拟化技术自己就要耗费部分的计算机资源,怎么还能产生1+1>2的效果? 其实这里指的是计算机的使用率,而非计算机的占用率,这二者看似很相近,其实并不是一个概念。虚拟化技术可以提升计算机资源的使用率,是指利用虚拟化技术,将本来程序使用不到的资源分配给其余程序使用,从而提高计算机资源的总体利用率。 例如,这⾥咱们有⼀台运⾏ Nginx 的机器,因为 Nginx 运⾏对系统资源的消耗并不⾼,这就让系统⼏乎 95% 以上的资源处于闲置状态。这时候咱们经过虚拟化技术,把其余的⼀些程序放到这台机器上来 运⾏,它们就可以充分利⽤闲置的资源。这带来的好处就是咱们不须要再为这些程序单独部署机器,从⽽节约很多的成本。 服务器
所谓硬件虚拟化,指的是物理硬件本⾝就提供虚拟化的⽀持。举个例⼦来讲,某个平台的 CPU,可以将另外⼀个平台的指令集转换为⾃⾝的指令集执⾏,并给程序彻底运⾏在那个平台上的感受。又或者 说,CPU 可以⾃⾝模拟裂变,让程序或者操做系统认为存在多个 CPU,进⽽可以同时运⾏多个程序或者操做系统。这些都是硬件虚拟化的体现。 ⽽软件虚拟化则指的是经过软件的⽅式来实现虚拟化中关键的指令转换部分。依然⽤ CPU 的例⼦来讲话,在软件虚拟化实现中,经过⼀层夹杂在应⽤程序和硬件平台上的虚拟化实现软件来进⾏指令的转换。也就是说,虽然应⽤程序向操做系统或者物理硬件发出的指令不是当前硬件平台所⽀持的指令,这个实现虚拟化的软件也会将之转换为当前硬件平台所能识别的架构
在实际场景中,虚拟化还能进⾏更加细化的分类,例如:运维
虚拟机 ( Virtual Machine )。所谓虚拟机,一般来讲就是经过⼀个虚拟机监视器 ( Virtual Machine Monitor ) 的设施来隔离操做系统与硬件或者应⽤程序与操做系统,以此达到虚拟化的⽬的。这个夹在其中的虚拟机监视器,经常被称为 Hypervisor。 分布式
容器技术是⼀种全新意义上的虚拟化技术,按分类或者实现⽅式来讲,其应该属于操做系统虚拟化的范畴,也就是在由操做系统提供虚拟化的⽀持。 所谓容器技术,指的是操做系统⾃⾝⽀持⼀些接⼜,可以让应⽤程序间能够互不⼲扰的独⽴运⾏,而且可以对其在运⾏中所使⽤的资源进⾏⼲预。 因为应⽤程序的运⾏被隔离在了⼀个独⽴的运⾏环境之中,这个独⽴的运⾏环境就好似⼀个容器,包裹住了应⽤程序,这就是容器技术名字的由来。 虚拟机VS容器 模块化
Docker是由 dotCloud 在2013年开源的一个由Go实现的容器引擎。微服务
利⽤它的全⾯性和易⽤性带来的提高咱们的⼯做效率,能够将开发人员或者运维人员从重复且容易出错的服务搭建中解放出来,特别是在微服务的浪潮下,项目多模块化和服务化,一个完整的项目由不少小服务组成,这对于搭建来讲也是一个不小的挑战。 docker技术实现 Docker 的实现,主要归结于三⼤技术:命名空间 ( Namespaces ) 、控制组 ( Control Groups ) 和联合⽂件系统 ( Union File System ) 。 性能
命名空间是 Linux 核⼼在 2.4 版本后逐渐引⼊的⼀项⽤于运⾏隔离的模块。Linux 内核的命名空间,就是可以将计算机资源进⾏切割划分,造成各⾃独⽴的空间。 就实现⽽⾔,Linux Namespaces 能够分为不少具体的⼦系统,如 User Namespace、Net Namespace、PID Namespace、Mount Namespace 等等。 这⾥咱们以进程为例,经过 PID Namespace,咱们能够造就⼀个独⽴的进程运⾏空间,在其中进程的编号又会从 1 开始。在这个空间中运⾏的进程,彻底感知不到外界系统中的其余进程或是其余进程命名空间中运⾏的进程。
资源控制组 ( 常缩写为 CGroups ) 是 Linux 内核在 2.6 版本后逐渐引⼊的⼀项对计算机资源控制的模块。 顾名思义,资源控制组的做⽤就是控制计算机资源的。与隔离进程、⽹络、⽂件系统等虚拟资源为⽬的 Namespace 不一样,CGroups 主要作的是硬件资源的隔离。 以前咱们提到了,虚拟化除了制造出虚拟的环境隔离同⼀物理平台运⾏的不一样程序以外,另⼀⼤做⽤就是控制硬件资源的分配,CGroups 的使⽤正是为了这样的⽬的。 须要再强调⼀次的是,CGroups 除了资源的隔离,还有资源分配这个关键性的做⽤。经过 CGroups,咱们能够指定任意⼀个隔离环境对任意资源的占⽤值或占⽤率,这对于不少分布式使⽤场景来讲是⾮ 常有⽤的功能。
联合⽂件系统 ( Union File System ) 是⼀种可以同时挂载不一样实际⽂件或⽂件夹到同⼀⽬录,造成⼀种联合⽂件结构的⽂件系统。联合⽂件系统本⾝与虚拟化并⽆太⼤的关系,但 Docker 却创新的将其引⼊ 到容器实现中,⽤它解决虚拟环境对⽂件系统占⽤过量,实现虚拟环境快速启停等问题。 在 Docker 中,提供了⼀种对 UnionFS 的改进实现,也就是 AUFS ( Advanced Union File System )。
属性 | Docker | 虚拟机 |
---|---|---|
启动速度 | 秒级 | 分钟级 |
硬盘使⽤ | MB 级 | GB 级 |
性能 | 接近原⽣ | 较低 |
普通机器⽀撑量 | 数百个 | ⼏个 |
从理论上咱们已经知道 Docker 可以为咱们的⼯做带来巨⼤的便利,那么将其放于实践中,咱们应该如何正确的使⽤它呢?这⾥我摘录整理了⼀段来⾃ Docker 官⽅⽂档的指导意见,但愿可以对⼤家的实 践提供参考。
使⽤ Docker 后,开发者可以在本地容器中获得⼀套标准的应⽤或服务的运⾏环境,由此能够简化开发的⽣命周期 ( 减小在不一样环境间进⾏适配、调整所形成的额外消耗 )。对于整个应⽤迭代来讲,加⼊ Docker 的⼯做流程将更加适合持续集成 ( Continuous Integration ) 和持续交付 ( Continuous Delivery )。 举个具体的例⼦: 开发者可以使⽤ Docker 在本地编写代码并经过容器与其余同事共享他们的⼯做。 他们可以使⽤ Docker 将编写好的程序推送⾄测试环境进⾏⾃动化测试或是⼈⼯测试。 当出现 Bugs 时,开发者能够在开发环境中修复它们,并很快的从新部署到测试环境中。 在测试完成后,部署装有应⽤程序的镜像就能完成⽣产环境的发布。
基于容器技术的 Docker 拥有很⾼的跨平台性,Docker 的容器可以很轻松的运⾏在开发者本地的电脑,数据中⼼的物理机或虚拟机,云服务商提供的云服务器,甚⾄是混合环境中。 同时,Docker 的轻量性和⾼可移植性可以很好的帮助咱们完成应⽤的动态伸缩,咱们能够经过⼀些⼿段近实时的对基于 Docker 运⾏的应⽤进⾏弹性伸缩,这可以⼤幅提⾼应⽤的健壮性。
Docker 的⾼效和轻量等特征,为替代基于 Hypervisor 的虚拟机提供了⼀个经济、⾼效、可⾏的⽅案。在 Docker 下,你能节约出更多的资源投⼊到业务中去,让应⽤程序产⽣更⾼的效益。同时,如此低的 资源消耗也说明了 Docker ⾮常适合在⾼密度的中⼩型部署场景中使⽤。
在 Docker 体系⾥,有四个对象 ( Object ) 是咱们不得不进⾏介绍的,由于⼏乎全部 Docker 以及周边⽣态的功能,都是围绕着它们所展开的。它们分别是:镜像 ( Image )、容器 ( Container )、⽹络 ( Network )、数据卷 ( Volume )。
镜像,能够理解为⼀个只读的⽂件包,其中包含了虚拟环境运⾏最原始⽂件系统的 内容。 固然,Docker 的镜像与虚拟机中的镜像仍是有⼀定区别的。⾸先,以前咱们谈到了 Docker 中的⼀个创新是利⽤了 AUFS 做为底层⽂件系统实现,经过这种⽅式,Docker 实现了⼀种增量式的镜像结构。
容器 ( Container ) 就更好理解了,在容器技术中,容器就是⽤来隔离虚拟环境的基础设施,⽽在 Docker ⾥,它也被引伸为隔离出来的虚拟环境。 若是把镜像理解为编程中的类,那么容器就能够理解为类的实例。镜像内存放的是不可变化的东西,当以它们为基础的容器启动后,容器内也就成为了⼀个“活”的空间。 ⽤更官⽅的定义,Docker 的容器应该有三项内容组成:
在 Docker 中,实现了强⼤的⽹络功能,咱们不但可以⼗分轻松的对每一个容器的⽹络进⾏配置,还能在容器间建⽴虚拟⽹络,将数个容器包裹其中,同时与其余⽹络环境隔离。
除了⽹络以外,⽂件也是重要的进⾏数据交互的资源。在以往的虚拟机中,咱们一般直接采⽤虚拟机的⽂件系统做为应⽤数据等⽂件的存储位置。然⽽这种⽅式其实并⾮彻底安全的,当虚拟机或者容器 出现问题致使⽂件系统⽆法使⽤时,虽然咱们能够很快的经过镜像重置⽂件系统使得应⽤快速恢复运⾏,可是以前存放的数据也就消失了。 为了保证数据的独⽴性,咱们一般会单独挂载⼀个⽂件系统来存放数据。这种操做在虚拟机中是繁琐的,由于咱们不但要搞定挂载在不一样宿主机中实现的⽅法,还要考虑挂载⽂件系统兼容性,虚拟操做 系统配置等问题。值得庆幸的是,这些在 Docker ⾥都已经为咱们轻松的实现了,咱们只须要简单的⼀两个命令或参数,就能完成⽂件系统⽬录的挂载。 可以这么简单的实现挂载,主要仍是得益于 Docker 底层的 Union File System 技术。在 UnionFS 的加持下,除了可以从宿主操做系统中挂载⽬录外,还可以建⽴独⽴的⽬录持久存放数据,或者在容器间共 享。 在 Docker 中,经过这⼏种⽅式进⾏数据共享或持久化的⽂件或⽬录,咱们都称为数据卷 ( Volume )。
时⾄今⽇,Docker ⽣态已经远⽐它诞⽣之初要庞⼤许多,虽然咱们仍然习惯使⽤ Docker 这个名字去指代实现容器技术⽀持的软件,但显然更加容易与其余的概念产⽣混淆。这⾥咱们颇有必要对这个 Docker 中最核⼼的软件进⾏介绍,不只由于它在 Docker ⽣态中扮演着中⼼的地位,也由于它是咱们在开发中实实在在接触最多的东西。 ⽬前这款实现容器化的⼯具是由 Docker 官⽅进⾏维护的,Docker 官⽅将其命名为 Docker Engine,同时定义其为⼯业级的容器引擎 ( Industry-standard Container Engine )。在 Docker Engine 中,实现了 Docker 技术中最核⼼的部分,也就是容器引擎这⼀部分。
虽然咱们说 Docker Engine 是⼀款软件,但实实在在去深究的话,它其实算是由多个独⽴软件所组成的软件包。在这些程序中,最核⼼的就是 docker daemon 和 docker CLI 这俩了。 全部咱们一般认为的 Docker 所能提供的容器管理、应⽤编排、镜像分发等功能,都集中在了 docker daemon 中,⽽咱们以前所提到的镜像模块、容器模块、数据卷模块和⽹络模块也都实如今其中。在操 做系统⾥,docker daemon 一般以服务的形式运⾏以便静默的提供这些功能,因此咱们也一般称之为 Docker 服务。