《容器技术系列》一1.4 Docker运行案例分析

1.4 Docker运行案例分析

1.3节着重介绍了Docker架构中各个模块的功能,学完后我们可以对Docker的架构有一个宏观的认识。熟悉一款软件,研究一个系统,从静态的角度认识架构的各个模块,仅仅是第一步;从动态的角度,掌握软件或者系统的运行原理,即熟知架构中模块间的通信逻辑,无疑会让自己对软件或系统的理解更上一层楼。本节将从实际的Docker运行案例出发,串联Docker各模块,从而学习Docker的运行流程。分析原型为Docker中的docker pull与docker run两个命令。

1.4.1 docker pull

1.3节中我们提到,用户可以为容器指定镜像,作为容器运行时的rootfs,既然如此,镜像从何而来则成为一个关键。答案很简单,一切都归功于docker pull命令。
docker pull命令的作用是:Docker Daemon从Docker Registry下载指定的容器镜像,并将镜像存储在本地的Graph中,以备后续创建Docker容器时使用。docker pull命令的执行流程如图1-10所示。
图1-10中有编号的箭头表示docker pull命令在发起后,Docker架构中相应模块所做的一系列运行操作。下面我们逐一分析这些步骤。
1)Docker Client处理用户发起的docker pull命令,解析完请求以及参数之后,发送一个HTTP请求给Docker Server,HTTP请求方法为POST,请求URL为"/images/create?"+"xxx",实际意义为下载相应的镜像。
2)Docker Server接收以上HTTP请求,并交给mux.Router,mux.Router通过URL以及请求方法类型来确定执行该请求的具体handler。
3)mux.Router将请求路由分发至相应的handler,具体为PostImagesCreate。
4)在PostImageCreate这个handler之中,创建并初始化一个名为"pull"的Job,之后触发执行该Job。
5)名为"pull"的Job在执行过程中执行pullRepository操作,即从Docker Registry中下载相应的一个或者多个Docker镜像。
6)名为"pull"的Job将下载的Docker镜像交给graphdriver管理。
7)graphdriver负责存储Docker镜像,一方面将实际镜像存储至本地文件系统中,另一方面为镜像创建对象,由Docker Daemon统一管理。

1.4.2 docker run

docker run命令的作用是创建一个全新的Docker容器,并在容器内部运行指定命令。Docker Daemon处理用户发起的这条命令时,所做工作可以分为两部分:第一,创建Docker容器对象,并为容器准备所需的rootfs;第二,创建容器的运行环境,如网络环境、资源限制等,最终真正运行用户指令。因此,在dockerrun命令的完整执行流程中,Docker Client给Docker Server发送了两次HTTP请求,第二次请求的发起取决于第一次请求的返回状态。docker run命令执行流程如图1-11所示。

图1-11中有编号的箭头表示dockerrun命令在发起后,Docker架构中相应模块所做的一系列运行。下面我们逐一分析这些步骤:
1)Docker Client处理用户发起的docker run命令,解析完请求与参数之后,向Docker Server发送一个HTTP请求,HTTP请求方法为POST,请求URL为"/containers/create?"+"xxx",实际意义为创建一个容器对象,即Docker Daemon程序逻辑中的容器对象,并非实际运行的容器。
2)Docker Server接收以上HTTP请求,并交给mux.Router,mux.Router通过URL以及请求方法来确定执行该请求的具体handler。
3)mux.Router将请求路由分发至相应的handler,具体为PostContainersCreate。
4)在PostContainersCreate这个handler之中,创建并初始化一个名为"create"的Job,之后触发执行该Job。
5)名为"create"的Job在运行过程中执行Container.Create操作,该操作需要获取容器镜像来为Docker容器准备rootfs,通过graphdriver完成。
6)graphdriver从Graph中获取创建Docker容器rootfs所需要的所有镜像。
7)graphdriver将rootfs的所有镜像通过某种联合文件系统的方式加载至Docker容器指定的文件目录下。
8)若以上操作全部正常执行,没有返回错误或异常,则Docker Client收到Docker Server返回状态之后,发起第二次HTTP请求。请求方法为"POST",请求URL为"/containers/"+container_ID+"/start",实际意义为启动时才创建完毕的容器对象,实现物理容器的真正运行。
9)Docker Server接收以上HTTP请求,并交给mux.Router,mux.Router通过URL以及请求方法来确定执行该请求的具体handler。
10)mux.Router将请求路由分发至相应的handler,具体为PostContainersStart。
11)在PostContainersStart这个handler之中,创建并初始化名为"start"的Job,之后触发执行该Job。
12)名为"start"的Job执行需要完成一系列与Docker容器相关的配置工作,其中之一是为Docker容器网络环境分配网络资源,如IP资源等,通过调用networkdriver完成。
13)networkdriver为指定的Docker容器分配网络资源,其中有IP、port等,另外为容器设置防火墙规则。
14)返回名为"start"的Job,执行完一些辅助性操作后,Job开始执行用户指令,调用execdriver。
15)execdriver被调用,开始初始化Docker容器内部的运行环境,如命名空间、资源控制与隔离,以及用户命令的执行,相应的操作转交至libcontainer来完成。
16)libcontainer被调用,完成Docker容器内部的运行环境初始化,并最终执行用户要求启动的命令。

时间: 2024-11-10 07:05:07

《容器技术系列》一1.4 Docker运行案例分析的相关文章

《容器技术系列》一导读

前 言 Docker是什么 Docker从2013年诞生,短短两年时间就在全球IT技术圈内迅速走红,实乃技术圈内不可忽视的一阵飓风.然而,Docker是什么,Docker带来了什么? Docker官方如此描述Docker:"Build, Ship, Run. An open platform for distributed applications for developers and sysadmins".换言之,Docker为开发者与系统管理者提供了分布式应用的开放平台,从而可以便

《容器技术系列》一1.3 Docker各模块功能与实现分析

1.3 Docker各模块功能与实现分析 下面我们将从Docker的总架构图入手,抽离出架构内的各个模块,并对各个模块进行更为细化的架构分析与功能阐述. 1.3.1 Docker Client Docker Client是Docker架构中用户与Docker Daemon建立通信的客户端.在一台安装有Docker的机器上,用户可以使用可执行文件docker作为Docker Client,发起众多Docker容器的管理请求. Docker Client可以通过以下三种方式和Docker Daemo

《容器技术系列》一2.2 创建Docker Client

2.2 创建Docker Client 对于Docker这样一个Client/Server的架构,客户端的存在意味着Docker相应任务的发起.用户首先需要创建一个DockerClient,随后将特定的请求类型与参数传递至Docker Client,最终由Docker Client转义成Docker Server能识别的形式,并发送至Docker Server. Docker Client的创建实质上是Docker用户通过二进制可执行文件docker,创建与Docker Server建立联系的客

《容器技术系列》一2.3 Docker命令执行

2.3 Docker命令执行 main函数执行到这个阶段,有以下内容需要为Docker命令的执行服务:创建完毕的Docker Client,docker命令中的请求参数(经flag解析后存放于flag.Arg()).也就是说,程序需要使用Docker Client来分析Docker命令中的请求参数,得出请求的类型,转义为Docker Server可以识别的请求之后,最终发送给Docker Server.Docker Client主要完成两方面的工作:解析请求命令,得出请求类型:执行具体类型的请求

《容器技术系列》一3.3 mainDaemon()的具体实现

3.3 mainDaemon()的具体实现 Docker Daemon的启动流程图展示了DockerDaemon的从无到有.通过分析流程图,我们可以得出一个这样的结论:区分Docker Daemon与Docker Client的关键在于flag参数flDaemon的值.一旦*flDaemon的值为真,则代表docker二进制需要启动的是Docker Daemon.有关Docker Daemon的所有的工作,都被包含在函数mainDaemon()的具体实现中.宏观来讲,mainDaemon()的使

《容器技术系列》一3.1 引言

3.1 引言 自Docker诞生以来,便引领了轻量级虚拟化容器领域的技术热潮.在这一潮流下,Google.IBM.Redhat等业界翘楚纷纷加入Docker阵营.虽然目前Docker仍主要基于Linux平台,但是Microsoft却多次宣布对Docker的支持,从先前宣布的Azure支持Docker与Kubernetes,到如今宣布的下一代Windows Server原生态支持Docker.Microsoft的这一系列举措多少喻示着向Linux世界的妥协,当然这也不得不让世人对Docker的巨大

《容器技术系列》一1.1 引言

1.1 引言 Docker是Linux平台上的一款轻量级虚拟化容器的管理引擎.在全球范围内,Docker还是一个开源项目,整个项目基于Go语言开发,代码托管于GitHub网站上,并遵从Apache 2.0协议.目前,Docker可以帮助用户在容器内部快速自动化部署应用,并利用Linux内核特性命名空间(namespaces)及控制组(cgroups)等为容器提供隔离的运行环境.Docker借助操作系统层的虚拟化实现资源的隔离,因此Docker容器在运行时与虚拟机(VM)的运行有很大的区别,Doc

《容器技术系列》一3.2 Docker Daemon的启动流程

3.2 Docker Daemon的启动流程 Docker Daemon和Docker Client的启动均通过可执行文件docker完成,因此两者的启动流程非常相似.Docker可执行文件运行时,程序运行通过不同的命令行flag参数,区分两者,并最终运行两者各自相应的部分.启动Docker Daemon时,一般可以使用以下命令:docker --daemon=true.docker –d; docker -d=true等.随后由Docker的main()函数来解析以上命令的相应flag参数,并

《容器技术系列》一2.1 引言

2.1 引言 如今,作为业界领先的轻量级虚拟化容器管理引擎,Docker给全球开发者提供了一种新颖.便捷的软件集成测试与部署之道.团队开发软件时,Docker可以提供可复用的运行环境.灵活的资源配置.便捷的集成测试方法,以及一键式的部署方式.可以说,Docker在简化持续集成.运维部署方面将其功能发挥得淋漓尽致,它让开发者从重复的持续集成.运维部署中完全解放出来,把精力真正地倾注在开发上.然而,要把Docker的功能发挥到极致,并非一件易事.在深刻理解Docker架构的情况下,熟练掌握Docke