《循序渐进学Docker》——1.2 Docker的结构与特性-阿里云开发者社区

开发者社区> 华章出版社> 正文

《循序渐进学Docker》——1.2 Docker的结构与特性

简介: 本节书摘来自华章出版社《循序渐进学Docker》一书中的第1章,第1.2节,作者李金榜 尹烨 刘天斯 陈纯,更多章节内容可以访问云栖社区“华章计算机”公众号查看。 1.2 Docker的结构与特性 通过上一小节的介绍,大家对Docker有一个初步的了解。

本节书摘来自华章出版社《循序渐进学Docker》一书中的第1章,第1.2节,作者李金榜 尹烨 刘天斯 陈纯,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

1.2 Docker的结构与特性

通过上一小节的介绍,大家对Docker有一个初步的了解。这一节,再来聊一下Docker的组织结构。

1.2.1 Docker构成

如果把Docker当作一个独立的软件来看,它就是用Golang写的开源程序,采用C/S架构,包含Docker Server和Docker Client, 源代码托管在https://github.com/docker/docker上。

如果把Docker看作一个生态的话,它主要由两部分组成:Docker仓库和Docker自身程序。拿iPhone做类比的话,Docker仓库相当于iPhone的Appstore(应用商店),Docker相当于iPhone的iOS手机操作系统。

1.Docker仓库

官方Docker仓库地址为https://hub.docker.com, 上面的应用非常丰富,既有各大公司打包的应用,也有大量个人开发者提供的应用,如图1-1所示。


cb1430ec40e39b780cff698db5abcf9ed4b69399

2.Docker自身程序

Docker本身是一个单机版的程序,它运行在Linux操作系统之上,属于用户态程序,通过一些接口和内核交互。它在机器上的位置如图1-2所示。


5d012ebf7a3a6ee10c93551c053bc3102d01da47

由于Docker需要用到Linux的cgroups、namespaces等特性,所以目前只能运行在Linux环境下,当然,通过虚拟机,也可以在Windows和Mac上使用Docker。

Docker是一个C/S的架构,它的Docker Daemon作为Server端,在宿主机上以后台守护进程的形式运行。Docker Client使用比较灵活,既可以在本机上以bin命令的形式(如Docker info、Docker start)发送指令,也可以在远端通过RESTful API的形式发送指令;Docker的Server端接收指令并把指令分解为一系列任务去执行。

3.工作流程

我们知道了Docker的构成,那么该如何使用Docker呢?

首先,要在Linux服务器上安装Docker软件包,并启动Docker Daemon守护进程。然后,就可以通过Docker Client端发送各种指令,Docker Daemon守护进程执行完指令,向Client端返回结果。

假如要启动一个新的Docker应用app1(名字是随便起的),它的工作流程大致如图1-3所示。

1)Docker Client向Daemon发送启动app1指令。

2)因为我们的Linux服务器只装有Docker软件包,根本没有app1相关软件或服务,Docker Daemon就发请求给Docker的官方仓库,在仓库中搜索app1。

3)如果找到app1这个应用,就把它下载到我们的服务器上。

4)Docker Daemon启动app1这个应用。

5)把启动app1应用是否成功的结果返回给Docker Client。


189db7d7162ab4116f536e71c76ce753eab0c1bf

Docker的其他操作,比如停止或删除Docker应用和启动的流程差不多,这里就不再一一介绍了。

1.2.2 Docker化应用的存在形式

我们知道,经过20多年的发展,Linux下应用软件已经不计其数,不但种类繁多,而且安装部署方式也千奇百怪、不一而足,如有些软件依赖特定操作系统、有些依赖特定内核版本、有些依赖一些第三方软件和共享库等。另外,不同操作系统,不同的系统版本软件的配置和启动方式也存在很大差异。

既然软件安装部署方式没有一个统一的标准,那么Docker的官方仓库该如何做呢?总不能针对每个软件,写一个安装说明书吧。

换个角度想一下,用户的需求是什么——把软件运行起来,至于怎么安装软件、软件运行在什么操作系统下用户不太关心。那么,就把软件和它依赖的环境(包括操作系统和共享库等)、依赖的配置文件打包在一起,以虚拟机的形式放到官方仓库,供大家使用。只要有虚拟机的运行环境,就可以不做任何修改把软件轻松地运行起来。这种方式甚至不需要大家重复安装和配置软件,只要有一个人把软件安装和配置好,提交到官方仓库,其他人下载后就可以直接以虚拟机的形式运行起来。我们以这种方式解决了软件安装部署方式没有一个统一标准的问题,如图1-4所示。


0e03f1a048f1a6032628c7e03143ea8ab4e37985

但这种软件部署方式却存在很多问题,一般一个软件包大小也就几兆到几十兆不等,但一个操作系统却有好几个G。如果每个软件都带上它依赖的操作系统,那么每个软件都有几个G,不要说运行,仅仅下载1个软件都要数小时,是不是有“捡了芝麻丢了西瓜”的感觉?

Docker为了解决这个问题,引入分层的概念。把一个应用分为任意多个层,比如操作系统是第一层,依赖的库和第三方软件是第二层,应用的软件包和配置文件是第三层。如果两个应用有相同的底层,就可以共享这些层。

以图1-4为例,假如应用A和应用B操作系统版本是一样的,它们就可以使用共享这一层,安装应用A时需要下载操作系统层,安装B应用就不用下载操作系统层,只需要下载它的依赖包和自身的软件包。因为主流的操作系统也就那么几个,最差情况下,也就把常用的操作系统都安装一遍,然后,包含操作系统的软件包就和传统的软件包一样大小了,如图1-5所示。


0a2381da4b53fafe760895f6852588f13e393d88

但这种共享层存在冲突问题,比如,应用A需要修改操作系统的某个配置,应用B不需要修改。如何解决这个冲突呢?我们规定层次是有优先级的,上层和下层有相同的文件和配置时,上层覆盖下层,数据以上层的数据为准。我们给每个应用一个优先级最高的空白层,如果需要修改下层的文件,就把这个文件拷贝到这个优先级最高的空白层进行修改,保证下层的文件不做任何改变。这样,从应用A的角度来看,文件已经修改成功了,而从应用B的角度来看,文件没发生任何改变,如图1-6所示。


ec8dea28475e7a825814521c001630539d2c02b2

Docker的分层和写时拷贝策略,解决了包含操作系统的应用程序比较大的问题。但我们知道,主流的虚拟机(KVM、Xen、VMWare、VirtualBox等)一般比较笨重,除了虚拟机本身运行要消耗大量的系统资源(CPU、内存等)外,启动一个虚拟机也需要花费数分钟,如何把虚拟机做到轻量化呢?

以OpenVZ、VServer、LXC为代表的容器类虚拟机,是一种内核虚拟化技术,与宿主机运行在相同Linux内核,不需要指令级模拟,性能消耗非常小,是非常轻量级的虚拟化容器,虚拟容器的系统资源消耗和一个普通的进程差不多。Docker就是使用LXC(后来又推出libcontainer)让虚拟机变得轻量化。

在Docker的官方仓库里,只需它有完整的文件系统和程序包,没有动态生成新文件的需求;当把它下载到宿主机上运行对外提供服务时,有可能修改文件(比如输出新日志到日志文件中),需要有空白层用于写时拷贝。Docker把这两种不同状态做了区分,分别叫作镜像(image)和容器(container),如图1-7所示。


5f1f6ec1d656d1948f360b073877fc7a4407a953

在仓库中的应用都是以镜像的形式存在的,把镜像从Docker仓库中下拉到本机,以这个镜像为模板启动应用,就叫容器。

综上所述,镜像指的是以分层的、可以被LXC/libcontainer理解的文件存储格式。Docker的应用都是以这种格式发布到Docker仓库中,供大家使用。把应用镜像从Docker仓库下载到本地机器上,以镜像为模板,在一个容器类虚拟机中把这个应用启动,这个虚拟机叫作容器。

在Docker的世界里,镜像和容器是它的两大核心概念,几乎所有的指令和文档都是围绕这两个概念展开的。

1.2.3 Docker对变更的管理

对于软件开发来说,版本迭代、版本回退是常态,Docker对变更管理又有什么特别之处呢?

假若有一个应用的Docker镜像,它的V1.0版本有三层,每层文件的大小如图1-8所示。


d491579bd246dae87f78440e835729d7fb8f1850

接下来,我们需要对它做如下修改:

修改位于第一层的文件A。

删除位于第二层的文件B。

添加一个新文件C。

Docker会新增一个第四层,针对上面的修改需求,它处理方法如下:

把第一层的文件A拷贝到第四层,修改文件A的内容。

在第四层,把名称为B的文件设置为不存在。

在第四层,创建一个新文件C。

通过增加一个第四层,我们的版本变更为V1.1,如图1-9所示。


9cd618763c61a6c189555ff0d9ae492658c867e2

我们想把应用的V1.1版本发布到Docker仓库,供其他宿主机使用。Docker的仓库已经存在这个应用镜像的V1.0版本,也就存储有这个应用的第一层、第二层和第三层,我们上传V1.1版本时,不需要重复上传前三层,只需要把第四层(只有3M大小)上传到Docker仓库就可以了。

有一台远程服务器,正在运行这个应用的V1.0版,它想升级到V1.1版。因为它本机已经有这个应用的前三层,所以只需要从Docker仓库把第四层下载下来,就可以运行V1.1版,如图1-10所示。


92392e6d112b25b88d85c419538f2f92928907bc

综上所述,Docker不仅具有版本控制功能,并且还能够利用分层特性做到增量更新。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:

华章出版社

官方博客
官网链接