看完这个,你就知道Docker是什么了

在开始谈docker容器以前,先须要清楚什么是虚拟化,什么是容器docker

虚拟化

若是要⽤简单的语句来阐述虚拟化技术的话,那么能够这么解释: 虚拟化技术是⼀种将计算机物理资源进⾏抽象、转换为虚拟的计算机资源提供给程序使⽤的技术。 这⾥所指的计算机资源,就包括了 CPU 提供的运算控制资源,硬盘提供的数据存储资源,⽹卡提供的⽹络传输资源等。 编程

在这里插入图片描述

为跨平台而生

计算机发展早期,各种计算机平台,计算资源所提供的接口都不同,调用十分混乱,没有像今天同样有相对统一的标准。因为为兼容不一样的平台写各类各样的兼容代码,因而虚拟技术运应而生。虚拟化技术经过自己适配不一样平台的硬件,抽象成统一的接口,从而实现程序的跨平台。安全

将虚拟化技术用于资源管理

在虚拟化技术发展的过程当中,人们又发现了虚拟化技术的另一个用途:资源管理。 由于虚拟化技术原本就是对计算机物理资源的抽象转换成虚拟的计算机资源,这样就很容易在这里对计算机资源进行修改,好比能够告诉程序这台计算机只有4G内存,而不管计算机是有16G仍是32G,程序都会按照虚拟机告诉它的4G内存来进行使用。 经过虚拟化技术管理计算机资源的方式,不当能让咱们对计算机资源的控制更加灵活,并且还能极大的提交计算机资源的使用率。 看到这可能会有些迷惑,虚拟化技术自己就要耗费部分的计算机资源,怎么还能产生1+1>2的效果? 其实这里指的是计算机的使用率,而非计算机的占用率,这二者看似很相近,其实并不是一个概念。虚拟化技术可以提升计算机资源的使用率,是指利用虚拟化技术,将本来程序使用不到的资源分配给其余程序使用,从而提高计算机资源的总体利用率。 例如,这⾥咱们有⼀台运⾏ Nginx 的机器,因为 Nginx 运⾏对系统资源的消耗并不⾼,这就让系统⼏乎 95% 以上的资源处于闲置状态。这时候咱们经过虚拟化技术,把其余的⼀些程序放到这台机器上来 运⾏,它们就可以充分利⽤闲置的资源。这带来的好处就是咱们不须要再为这些程序单独部署机器,从⽽节约很多的成本。 服务器

在这里插入图片描述
部分读者读到这⾥就会产⽣疑惑了,我本⾝就能够在操做系统⾥安装这些程序而且同时运⾏,为何还要把它们分别装到不一样的虚拟环境中去呢? 其实道理很简单,虽然咱们可以在操做系统⾥同时运⾏多个程序,但前提得是这些程序本⾝不存在冲突。这⾥的冲突体如今不少的⽅⾯,例如不一样的程序同时使⽤了同⼀个端⼜;不一样程序依赖于同⼀个 ⼯具库的不一样版本;程序本⾝限制了同时开启的进程数等。虚拟化技术经过资源隔离的⽅式,⽆形地也能够把这些程序隔离在不一样的虚拟环境中,既然虚拟环境不一样,⾃然运⾏在不一样环境中的程序就不 会互相⼲扰或争抢资源了。

虚拟化的分类
  • 硬件虚拟化
  • 软件虚拟化

所谓硬件虚拟化,指的是物理硬件本⾝就提供虚拟化的⽀持。举个例⼦来讲,某个平台的 CPU,可以将另外⼀个平台的指令集转换为⾃⾝的指令集执⾏,并给程序彻底运⾏在那个平台上的感受。又或者 说,CPU 可以⾃⾝模拟裂变,让程序或者操做系统认为存在多个 CPU,进⽽可以同时运⾏多个程序或者操做系统。这些都是硬件虚拟化的体现。 ⽽软件虚拟化则指的是经过软件的⽅式来实现虚拟化中关键的指令转换部分。依然⽤ CPU 的例⼦来讲话,在软件虚拟化实现中,经过⼀层夹杂在应⽤程序和硬件平台上的虚拟化实现软件来进⾏指令的转换。也就是说,虽然应⽤程序向操做系统或者物理硬件发出的指令不是当前硬件平台所⽀持的指令,这个实现虚拟化的软件也会将之转换为当前硬件平台所能识别的架构

在实际场景中,虚拟化还能进⾏更加细化的分类,例如:运维

  • 平台虚拟化:在操做系统和硬件平台间搭建虚拟化设施,使得整个操做系统都运⾏在虚拟后的环境中。
  • 应⽤程序虚拟化:在操做系统和应⽤程序间实现虚拟化,只让应⽤程序运⾏在虚拟化环境中。
  • 内存虚拟化:将不相邻的内存区,甚⾄硬盘空间虚拟成统⼀连续的内存地址,即咱们常说的虚拟内存。
  • 桌⾯虚拟化:让本地桌⾯程序利⽤远程计算机资源运⾏,达到控制远程计算机的⽬的。

虚拟机

虚拟机 ( Virtual Machine )。所谓虚拟机,一般来讲就是经过⼀个虚拟机监视器 ( Virtual Machine Monitor ) 的设施来隔离操做系统与硬件或者应⽤程序与操做系统,以此达到虚拟化的⽬的。这个夹在其中的虚拟机监视器,经常被称为 Hypervisor。 分布式

在这里插入图片描述
从咱们习惯⽤来搭建虚拟操做系统环境的 VMware Workstation、Xen 等软件,到 Java 虚拟机 JVM,PHP 虚拟 机 HHVM 等等,都充活跃在咱们程序开发到程序运⾏的过程当中。 这个时候可能聪明的大家会发现,发现原来 JVM、HHVM 等特定语⾔运⾏环境中的核⼼部分,也是虚拟化的⼀种实实在在的实现。没错,只要⼤家仔细分析和思考⼀下就会发现,它们正是基于虚拟化的思想来实现的。它们经过隔离程序和操做系统,将程序的指令转换为当前所在操做系统平台所能执⾏的指令,达到了不⽤对程序进⾏任何修改便可执⾏的⽬的。也正是这个缘由,这些语⾔的程序都具备⾮常强的跨平台性。 虽然虚拟机技术得益于 Hypervisor 的加持,使得应⽤程序或者操做系统能够在⽆任何修改的状况下运⾏在另⼀平台上,但⼤家很容易发现,其有⼀个致命的缺陷,就是全部的指令都必须通过虚拟机监视器的处理。这也就意味着,虚拟机的性能是低下的,例如运⾏在 ZendVM 或者 HHVM 中的 PHP 程序,全部代码虽然编译成了 Opcode 码,但其依然是经过虚拟机才最终转换为机器所能识别的机器码去执⾏。 这种效率的低下有时候是⽆法容忍的,为了解决这个问题,真实的虚拟机程序经常不彻底遵循 Hypervisor 的设计结构,⽽是引⼊⼀些其余技术来解决效率问题。 例如,在 VMware Workstation、Xen 中咱们可以看到硬件辅助虚拟化的使⽤,经过让指令直达⽀持虚拟化的硬件,以此避开了效率低下的 Hypervisor。⽽如 JRE、HPHP 中,除了基于 Hypervisor 实现的解 释执⾏机制外,还有即时编译 ( Just In Time ) 运⾏机制,让程序代码在运⾏前编译成符合当前硬件平台的机器码。

容器技术

容器技术是⼀种全新意义上的虚拟化技术,按分类或者实现⽅式来讲,其应该属于操做系统虚拟化的范畴,也就是在由操做系统提供虚拟化的⽀持。 所谓容器技术,指的是操做系统⾃⾝⽀持⼀些接⼜,可以让应⽤程序间能够互不⼲扰的独⽴运⾏,而且可以对其在运⾏中所使⽤的资源进⾏⼲预。 因为应⽤程序的运⾏被隔离在了⼀个独⽴的运⾏环境之中,这个独⽴的运⾏环境就好似⼀个容器,包裹住了应⽤程序,这就是容器技术名字的由来。 虚拟机VS容器 模块化

在这里插入图片描述
因为没有了虚拟操做系统和虚拟机监视器这两个层次,从而省略了指令转换这一操做,⼤幅减小了应⽤程序运⾏带来的额外消耗。 更准确的来讲,全部在容器中的应⽤程序其实彻底运⾏在了宿主操做系统中,与其余真实运⾏在其中的应⽤程序在指令运⾏层⾯是彻底没有任何区别的。

什么是Docker

Docker是由 dotCloud 在2013年开源的一个由Go实现的容器引擎。微服务

Docker带来什么

利⽤它的全⾯性和易⽤性带来的提高咱们的⼯做效率,能够将开发人员或者运维人员从重复且容易出错的服务搭建中解放出来,特别是在微服务的浪潮下,项目多模块化和服务化,一个完整的项目由不少小服务组成,这对于搭建来讲也是一个不小的挑战。 docker技术实现 Docker 的实现,主要归结于三⼤技术:命名空间 ( Namespaces ) 、控制组 ( Control Groups ) 和联合⽂件系统 ( Union File System ) 。 性能

在这里插入图片描述

Namespace

命名空间是 Linux 核⼼在 2.4 版本后逐渐引⼊的⼀项⽤于运⾏隔离的模块。Linux 内核的命名空间,就是可以将计算机资源进⾏切割划分,造成各⾃独⽴的空间。 就实现⽽⾔,Linux Namespaces 能够分为不少具体的⼦系统,如 User Namespace、Net Namespace、PID Namespace、Mount Namespace 等等。 这⾥咱们以进程为例,经过 PID Namespace,咱们能够造就⼀个独⽴的进程运⾏空间,在其中进程的编号又会从 1 开始。在这个空间中运⾏的进程,彻底感知不到外界系统中的其余进程或是其余进程命名空间中运⾏的进程。

在这里插入图片描述
利⽤ PID Namespace,Docker 就实现了容器中隔离程序运⾏中进程隔离这⼀⽬标。

Control Groups

资源控制组 ( 常缩写为 CGroups ) 是 Linux 内核在 2.6 版本后逐渐引⼊的⼀项对计算机资源控制的模块。 顾名思义,资源控制组的做⽤就是控制计算机资源的。与隔离进程、⽹络、⽂件系统等虚拟资源为⽬的 Namespace 不一样,CGroups 主要作的是硬件资源的隔离。 以前咱们提到了,虚拟化除了制造出虚拟的环境隔离同⼀物理平台运⾏的不一样程序以外,另⼀⼤做⽤就是控制硬件资源的分配,CGroups 的使⽤正是为了这样的⽬的。 须要再强调⼀次的是,CGroups 除了资源的隔离,还有资源分配这个关键性的做⽤。经过 CGroups,咱们能够指定任意⼀个隔离环境对任意资源的占⽤值或占⽤率,这对于不少分布式使⽤场景来讲是⾮ 常有⽤的功能。

Union File System

联合⽂件系统 ( Union File System ) 是⼀种可以同时挂载不一样实际⽂件或⽂件夹到同⼀⽬录,造成⼀种联合⽂件结构的⽂件系统。联合⽂件系统本⾝与虚拟化并⽆太⼤的关系,但 Docker 却创新的将其引⼊ 到容器实现中,⽤它解决虚拟环境对⽂件系统占⽤过量,实现虚拟环境快速启停等问题。 在 Docker 中,提供了⼀种对 UnionFS 的改进实现,也就是 AUFS ( Advanced Union File System )。

AUFS
AUFS 将⽂件的更新挂载到⽼的⽂件之上,⽽不去修改那些不更新的内容,这就意味着即便虚拟的⽂件系统被反复修改,也能保证对真实⽂件系统的空间占⽤保持⼀个较低⽔平。 也许这个表述还不够形象,那么咱们来⽤ Git 进⾏⽐较,会让⼤家会更容易理解。⼤家知道,咱们在 Git 中每进⾏⼀次提交,Git 并非将咱们全部的内容打包成⼀个版本,⽽只是将修改的部分进⾏记 录,这样即便咱们提交不少次后,代码库的空间占⽤也不会倍数增长。 一样的,经过 AUFS,Docker ⼤幅减小了虚拟⽂件系统对物理存储空间的占⽤。由此,Docker 也开创出了虚拟化领域不少新的轻量级解决⽅案,这在以后的⼩节⾥咱们会提到。 Docker 的理念 在对 Docker 及其背后的⼀些技术有了⼀个初步了解以后,咱们还要着重说⼀下 Docker 本⾝的⼀些设计理念。若是说熟悉 Docker 背后的技术可以更好的帮助你正确使⽤ Docker,那么理解 Docker 的理念 将更好的指导你如何搭配 Docker 容器间的关系。 让咱们先来从⼀张 Docker 官⽅提供的架构图来看看 Docker 对容器结构的设计。
在这里插入图片描述
与其余虚拟化实现甚⾄其余容器引擎不一样的是,Docker 推崇⼀种轻量级容器的结构,即⼀个应⽤⼀个容器。 举个具体的例⼦,在常见的虚拟机实现中,咱们要搭建⼀套 LAMP 结构的服务,咱们一般会建⽴⼀个虚拟机,在虚拟机中安装上 Linux 系统,以后分别安装 Apache、MySQL 和 PHP。⽽在 Docker ⾥,最佳的实践是分别基于 Apache、MySQL 和 PHP 的镜像建⽴三个容器,分别运⾏ Apache、MySQL 和 PHP ,⽽它们所在的虚拟操做系统也直接共享于宿主机的操做系统。 若是咱们将 Docker 的轻量级容器实现和虚拟机的⼀些参数进⾏对⽐,更容易获得结果。

属性 Docker 虚拟机
启动速度 秒级 分钟级
硬盘使⽤ MB 级 GB 级
性能 接近原⽣ 较低
普通机器⽀撑量 数百个 ⼏个
Docker 能作什么

从理论上咱们已经知道 Docker 可以为咱们的⼯做带来巨⼤的便利,那么将其放于实践中,咱们应该如何正确的使⽤它呢?这⾥我摘录整理了⼀段来⾃ Docker 官⽅⽂档的指导意见,但愿可以对⼤家的实 践提供参考。

更快、更⼀致的交付你的应⽤程序

使⽤ Docker 后,开发者可以在本地容器中获得⼀套标准的应⽤或服务的运⾏环境,由此能够简化开发的⽣命周期 ( 减小在不一样环境间进⾏适配、调整所形成的额外消耗 )。对于整个应⽤迭代来讲,加⼊ Docker 的⼯做流程将更加适合持续集成 ( Continuous Integration ) 和持续交付 ( Continuous Delivery )。 举个具体的例⼦: 开发者可以使⽤ Docker 在本地编写代码并经过容器与其余同事共享他们的⼯做。 他们可以使⽤ Docker 将编写好的程序推送⾄测试环境进⾏⾃动化测试或是⼈⼯测试。 当出现 Bugs 时,开发者能够在开发环境中修复它们,并很快的从新部署到测试环境中。 在测试完成后,部署装有应⽤程序的镜像就能完成⽣产环境的发布。

跨平台部署和动态伸缩

基于容器技术的 Docker 拥有很⾼的跨平台性,Docker 的容器可以很轻松的运⾏在开发者本地的电脑,数据中⼼的物理机或虚拟机,云服务商提供的云服务器,甚⾄是混合环境中。 同时,Docker 的轻量性和⾼可移植性可以很好的帮助咱们完成应⽤的动态伸缩,咱们能够经过⼀些⼿段近实时的对基于 Docker 运⾏的应⽤进⾏弹性伸缩,这可以⼤幅提⾼应⽤的健壮性。

让一样的硬件提供更多的产出能⼒

Docker 的⾼效和轻量等特征,为替代基于 Hypervisor 的虚拟机提供了⼀个经济、⾼效、可⾏的⽅案。在 Docker 下,你能节约出更多的资源投⼊到业务中去,让应⽤程序产⽣更⾼的效益。同时,如此低的 资源消耗也说明了 Docker ⾮常适合在⾼密度的中⼩型部署场景中使⽤。

Docker核心组成

在 Docker 体系⾥,有四个对象 ( Object ) 是咱们不得不进⾏介绍的,由于⼏乎全部 Docker 以及周边⽣态的功能,都是围绕着它们所展开的。它们分别是:镜像 ( Image )、容器 ( Container )、⽹络 ( Network )、数据卷 ( Volume )。

镜像

镜像,能够理解为⼀个只读的⽂件包,其中包含了虚拟环境运⾏最原始⽂件系统的 内容。 固然,Docker 的镜像与虚拟机中的镜像仍是有⼀定区别的。⾸先,以前咱们谈到了 Docker 中的⼀个创新是利⽤了 AUFS 做为底层⽂件系统实现,经过这种⽅式,Docker 实现了⼀种增量式的镜像结构。

在这里插入图片描述
每次对镜像内容的修改,Docker 都会将这些修改铸形成⼀个镜像层,⽽⼀个镜像其实就是由其下层全部的镜像层所组成的。固然,每⼀个镜像层单独拿出来,与它之下的镜像层均可以组成⼀个镜像。 另外,因为这种结构,Docker 的镜像实质上是⽆法被修改的,由于全部对镜像的修改只会产⽣新的镜像,⽽不是更新原有的镜像。

容器

容器 ( Container ) 就更好理解了,在容器技术中,容器就是⽤来隔离虚拟环境的基础设施,⽽在 Docker ⾥,它也被引伸为隔离出来的虚拟环境。 若是把镜像理解为编程中的类,那么容器就能够理解为类的实例。镜像内存放的是不可变化的东西,当以它们为基础的容器启动后,容器内也就成为了⼀个“活”的空间。 ⽤更官⽅的定义,Docker 的容器应该有三项内容组成:

  • ⼀个 Docker 镜像
  • ⼀个程序运⾏环境
  • ⼀个指令集合
⽹络

在 Docker 中,实现了强⼤的⽹络功能,咱们不但可以⼗分轻松的对每一个容器的⽹络进⾏配置,还能在容器间建⽴虚拟⽹络,将数个容器包裹其中,同时与其余⽹络环境隔离。

在这里插入图片描述
另外,利⽤⼀些技术,Docker 可以在容器中营造独⽴的域名解析环境,这使得咱们能够在不修改代码和配置的前提下直接迁移容器,Docker 会为咱们完成新环境的⽹络适配。对于这个功能,咱们甚⾄能 够在不一样的物理服务器间实现,让处在两台物理机上的两个 Docker 所提供的容器,加⼊到同⼀个虚拟⽹络中,造成彻底屏蔽硬件的效果。

数据卷

除了⽹络以外,⽂件也是重要的进⾏数据交互的资源。在以往的虚拟机中,咱们一般直接采⽤虚拟机的⽂件系统做为应⽤数据等⽂件的存储位置。然⽽这种⽅式其实并⾮彻底安全的,当虚拟机或者容器 出现问题致使⽂件系统⽆法使⽤时,虽然咱们能够很快的经过镜像重置⽂件系统使得应⽤快速恢复运⾏,可是以前存放的数据也就消失了。 为了保证数据的独⽴性,咱们一般会单独挂载⼀个⽂件系统来存放数据。这种操做在虚拟机中是繁琐的,由于咱们不但要搞定挂载在不一样宿主机中实现的⽅法,还要考虑挂载⽂件系统兼容性,虚拟操做 系统配置等问题。值得庆幸的是,这些在 Docker ⾥都已经为咱们轻松的实现了,咱们只须要简单的⼀两个命令或参数,就能完成⽂件系统⽬录的挂载。 可以这么简单的实现挂载,主要仍是得益于 Docker 底层的 Union File System 技术。在 UnionFS 的加持下,除了可以从宿主操做系统中挂载⽬录外,还可以建⽴独⽴的⽬录持久存放数据,或者在容器间共 享。 在 Docker 中,经过这⼏种⽅式进⾏数据共享或持久化的⽂件或⽬录,咱们都称为数据卷 ( Volume )。

Docker Engine

时⾄今⽇,Docker ⽣态已经远⽐它诞⽣之初要庞⼤许多,虽然咱们仍然习惯使⽤ Docker 这个名字去指代实现容器技术⽀持的软件,但显然更加容易与其余的概念产⽣混淆。这⾥咱们颇有必要对这个 Docker 中最核⼼的软件进⾏介绍,不只由于它在 Docker ⽣态中扮演着中⼼的地位,也由于它是咱们在开发中实实在在接触最多的东西。 ⽬前这款实现容器化的⼯具是由 Docker 官⽅进⾏维护的,Docker 官⽅将其命名为 Docker Engine,同时定义其为⼯业级的容器引擎 ( Industry-standard Container Engine )。在 Docker Engine 中,实现了 Docker 技术中最核⼼的部分,也就是容器引擎这⼀部分。

docker daemon 和 docker CLI

虽然咱们说 Docker Engine 是⼀款软件,但实实在在去深究的话,它其实算是由多个独⽴软件所组成的软件包。在这些程序中,最核⼼的就是 docker daemon 和 docker CLI 这俩了。 全部咱们一般认为的 Docker 所能提供的容器管理、应⽤编排、镜像分发等功能,都集中在了 docker daemon 中,⽽咱们以前所提到的镜像模块、容器模块、数据卷模块和⽹络模块也都实如今其中。在操 做系统⾥,docker daemon 一般以服务的形式运⾏以便静默的提供这些功能,因此咱们也一般称之为 Docker 服务。

在这里插入图片描述
在 docker daemon 管理容器等相关资源的同时,它也向外暴露了⼀套 RESTful API,咱们可以经过这套接⼜对 docker daemon 进⾏操做。或者更确切的说,是经过这套 RESTful API 对 docker daemon 中运 ⾏的容器和其余资源进⾏管理。 一般来讲,咱们是采⽤在控制台或者命令⾏输⼊命令来控制 docker daemon 的,由于这样很酷也更容易适应那些有或者没有图形界⾯的操做系统。 若是咱们在控制台中编写⼀个 HTTP 请求以借助 docker daemon 提供的 RESTful API 来操控它,那显然是个费脑、费⼿又费时间的活⼉。因此在 Docker Engine ⾥还直接附带了 docker CLI 这个控制台程序。
在这里插入图片描述
熟悉程序结构的朋友们⽐较容易看出来,docker daemon 和 docker CLI 所组成的,正是⼀个标准 C/S ( Client-Server ) 结构的应⽤程序。衔接这二者的,正是 docker daemon 所提供的这套 RESTful API。
相关文章
相关标签/搜索