Docker容器化引擎

摘自《Java微服务分布式架构企业实战》

   如今Docker在一线互联网公司的应用已经非常普遍,使用Docker技术可以给企业带来极大的好处,使企业的业务水平扩展更快速,从而到达弹性部署业务的能力。在云服务概念兴起之后,Docker的使用场景和范围得到了进一步发展,如今在微服务架构越来越流行的情况下,微服务+Docker的组合方式,更加方便微服务架构运维部署落地,使应用部署、测试和请求都变得前所未有的便捷和轻松。

1 Docker与传统虚拟化方式的区别
  百度百科中对Docker的解释是“Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。”它是谷歌公司基于Linux内核,通过GO语言开发的。Docker技术与虚拟机技术相比,前者更加轻便、快捷。之前在安装Ubuntu时就已经使用过虚拟机技术VMware,接下来,把Docker技术与传统虚拟化技术进行比较,了解Docker的优点。

  传统的基础服务设施是由硬件和操作系统组成的,然后在操作系统上再安装QQ、微信、浏览器等软件,如图3. 1所示。

 

  传统的虚拟化技术可以将众多的计算机结合在一起统一管理,在这个过程中需要用到虚拟化技术(Hypervisor).基于硬件,通过虚拟化技术将多台主机连接在一起,共同进行管理,如图3.2所示

 

  图3. 2类似一个云服务平台,假设该平台有四台Service(计算机),这四台机器通过Hypervisor(虚拟化技术),整体虚拟化操作系统,最终组成一个超级计算机。该超级计算机能够统一调度资源,统一进行管理,能够分配给用户一定量的空间供用户使用,然后每个用户可以操作自己所分配的那块空间,且与其他用户得到的空间中存储的信息和分配的资源互不相干。

  虚拟机也是同样的道理,先是在硬件之上安装宿主机,在宿主机之上使用Hypervisor实现虚拟化技术,然后再安装客户机。以通常使用的计算机为例,在最底层的硬件之上安装Windows操作系统,然后在操作系统之上使用虚拟化技术(安装VMware),最后再安装Ubuntu,用户可以根据自己的需求,在Ubuntu之上安装应用程序,如图3. 3(a)所示。

 

  然而,从图3. 3(b)中可以发现,有了Docker技术后将不再使用虚拟机,Ubuntu直接安装在Docker之上即可。虽然图3. 3(a)和图3. 3(b)两部分看似差别不大,只是用Docker取代虚拟机而已,但是,在使用Docker时可以发现,Docker直接利用的是宿主机(图3. 3中安装了Windows的机器)的内核与资源。安装在Docker之上的Linux的所有资源都来自于底层设备,这个时候它的资源是共享状态的,即Windows中的资源与Docker之上安装的Ubuntu的资源之间可以共享,而虚拟机安装后则会从宿主机中占用部分资源,而且这部分资源与主机之间是不能够共享的。如有一台宿主机,CPU参数为3. 0GHz4核,内存16GB,当在该宿主机中安装虚拟机(VMware)后,一个虚拟机开启后将被分配2GB内存,此时宿主机能够使用的内存只剩14GB,如果在虚拟机上安装一个App,当App的使用资源超出2GB时,还会发生内存溢出,当App的使用资源只有1GB时,宿主机分配给它的资源将会浪费掉一半,假如不安装虚拟机,使用Docker的情况时,宿主机不需要单独为Docker分

配任何资源,Docker可以直接使用宿主机的内存,届时不必担心为Docker分配的资源大小是否合适、资源是否因为分配不均而导致浪费问题,只要是宿主机的资源即可全部拿来使用。

2.Docker 容器化引擎

  简单来说,Docker就是使用客户端-服务器(C/S)架构模式,通过远程API管理和创建容器的。Docker在容器的基础之上,会进一步地封装,把文件系统、网络互联、进程隔离等都封装在不同的层面之上,这些都极大地简化了Docker容器的创建与维护。Docker容器化引擎也是一种服务器,这种服务器可以长时间地运行,可以通过REST API和守护进程完成通信,如图3. 4所示。

 

  图3. 4中 Server Docker Daemon 即为Docker的守护进程,Client Docker CLI是客户端命令行工具。请求会通过命令行工具去调用Docker提供的REST API,将命令发送给守护进程。通过API可以对镜像(Image)、容器(Container)、网络(Network)、数据卷(DataVolumes进行管理,守护进程最后会把命令的执行结果返回给客户端。

3.Docker 镜像、容器、仓库

  Docker镜像是Docker容器运行的前提,容器是镜像运行的实例,有了镜像才能够启动容器。Docker镜像是一个特殊的文件系统,它的内部除了包含提供容器运行时所需要的程序、库、资源、配置等文件外,还包含了容器在运行时需要准备的一些配置参数信息(如匿名卷、环境变量、用户等)。Docker镜像里面不会包含任何动态数据,它的内容在构建之后也不会被改变,而且,Docker镜像是分层构建的,前一层是后一层的基础,每一层在构建完成后都不会再发生改变,后一层上的任何改变都只发生在当前这一层上,并不会影响到之前已经构建好的层。例如,在当前层中删除前一层的文件时,实际上并不是真删除了前一层的文件,只是在当前层标记该文件被删除,最终容器运行的时候,虽然看不到该文件,但是实际上该文件会一直跟随镜像。因此,在构建Docker镜像时需要特别注意,每一层都要尽量只包含该层所必须添加的东西,其他额外的东西都应该在该层构建结束前清理掉。通常在构建Docker镜像时会把之前构建好的镜像用来作为基础层,然后进一步添加新的层,在新层中定制自己所需要的内容,构建新的镜像,如图3. 5所示。

 

  从图3. 5可以看出,Docker引擎之上,安装了操作系统(OS),这时就相当于封装了一层镜像,该层将不再发生变化。在OS的基础上再添加一层,第二层当中装载了Java,由于该层是在第一层OS的基础上新加的,因此,该层不仅包含了Java也继承了第一层OS的Linux,这时的镜像又再一次进行了封装,当添加到第三层时,可以发现,在构建的新镜像中,不仅包含新安装的MySQL,还包含了前两层中的Linux和Java.

  镜像(Image)和容器(Container)的关系,就像是面向对象编程思想中的类和实例一样,容器是镜像运行时的实体。容器同样也能够被创建、启动、停止、删除、暂停等。每一个容器都是一个进程,但它与宿主机中的进程之间的区别就是容器拥有自己的命名空间。

  前面讲过镜像使用的是分层存储,容器也是如此,每一个容器在运行时,都是以镜像为基础层,在基础层的上面会再创建一个存储层用来为容器运行时的读和写做准备。该存储层的生命周期会伴随着容器的消亡而消亡,所以保存在存储层中的信息都会有丢失的风险。因此,所有的文件在写入时,都应该使用数据卷(数据卷是一个可以供一个或多个容器使用的特殊目录)或者绑定宿主目录,这样文件的读写操作会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。
  数据卷的生存周期并不会因为容器的消亡而消亡。因此,使用数据卷后,容器无论是被删除还是被重新运行,数据都不会丢失。
  镜像构建完成后,可以很容易地在当前宿主机上运行,但是,如果需要在其他服务器上使用这个镜像,就需要一个集中的存储、分发镜像的服务-Docker Registry服务,如图3. 6所示。

 

 

  在Docker Registry服务中包含有多个Repository(集中存放镜像文件的仓库),每个Repository又包含了多个Tag(标签),标签和镜像是一一对应的关系,可以通过<仓库名>:<标签>的格式指定具体的镜像文件。Docker Registry服务又分为公有的和私有的,公有的Docker Registry服务是开放给用户使用、允许用户管理镜像的Registry服务,可以满足用户上传和下载镜像的需求,最常使用的Registry公有的服务是官方的 Docker Hub,这也是默认的Registry,并且拥有大量高质量的官方镜像,但是由于种种原因在国内访问这些服务可能会比较慢,国内不少云服务提供商(如时速云、阿里云等)也提供了仓库的本地源,可以提供稳定的国内访问。当然,用户如果不希望公开分享自己的镜像文件,Docker也支持用户在本地网络内创建一个只能自己访问的私有仓库。当用户创建了自己的镜像之后就可以使用push命令将它上传到指定的公有或者私有仓库。这样用户下次在另外一台机器上使用该镜像时,将其从仓库上使用pull命令拉下来就可以了。

5.Docker Compose官方容器

  Compose项目是Docker官方的开源项目,它负责实现对 Docker 容器集群的快速编排。通过前面的介绍,可以了解 Dockerfile模板文件,让用户很方便地定义一个单独的应用容器。但是,在日常工作中,经常会遇到需要多个容器相互配合完成某项任务的情况。例如,当需要实现一个Web项目时,除了Web服务容器本身之外,往往还需要再配置与之相关的后端数据库服务容器,甚至包括负载均衡容器等,在这种情况下,使用Docker Compose技术,就能够很简单地满足这些需求。
  定义和运行多个容器的Docker应用程序,在Compose中可以使用YML文件配置应用服务。然后,只需要一个简单的命令,就可以创建并启动配置的所有服务。
  使用Compose基本有如下三步流程。

  (1)在Dockfile中定义应用环境,使其可以在任何地方复制。

  (2)在docker-compose.yml中定义组成应用程序的服务,以便它们可以在隔离的环境中一起运行。

  (3)运行 dcoker-compose up,Compose将启动并运行整个应用程序。

  Compose中还有两个重要的概念:服务和项目。

  服务(Service):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。

  项目(Project):由一组关联的应用容器组成的一个完整业务单元,在docker-compose.yml文件中定义。
  Compose的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷的生命周期管理。
  Compose项目用Python编写,调用Docker服务提供的API实现对容器的管理。因此,只要所操作的平台支持Docker API,就可以在其上利用Compose进行编排管理。

 

posted @ 2022-04-14 16:17  嘉禾世兴  阅读(66)  评论(0编辑  收藏  举报