Docker源码学习笔记一、系统架构

Docker源码学习笔记一、系统架构

  2010年一家名为dotCloud的创业公司,主要做一些Paas的云计算服务,即提供一些容器化技术,他们将这些容器化技术命名为Docker。Docker刚诞生时并没有引起行业的注意,2013年Docker技术开源,2014年Docker1.0发布。
  在Docker技术出现之前,一直使用虚拟机技术,事实上,Docker容器技术本身就是一种轻量级虚拟化技术。Docker在云计算领域和分布式系统大放异彩,在DevOps大背景下,完成云计算时代分布式应用的第一需求-------“隔离”。

1. 引言

  Docker是Linux平台上一款轻量级虚拟化容器的管理引擎,是一款开源项目,遵从Apache2.0协议。Docker可以帮助用户在容器内部快速自动化部署应用,并利用Linux内核特性命名空间及控制组等为容器提供隔离的运行环境。Docker借助操作系统层的虚拟化实现资源的隔离,因此Docker容器在运行时与虚拟机的运行有很大的区别,Docker容器与宿主机共享同一个操作系统,不会有额外的操作系统开销。

  Docker提供轻量级的资源分配方式,解决应用运行与环境的依赖,弥合应用跨节点迁移的鸿沟,可以说Docker就是为“云计算”而生。

1.1. Docker和虚拟机

  容器本质上就是加了namespace和croup的一个进程,可以实现对资源的隔离和限制。Docker就是基于容器的这个思想,在Linux Container基础上实现的虚拟化容器管理引擎。事实上,Linux操作系统本身从操作系统层面就支持虚拟化技术,称为Linux Container(LXC)。

  LXC有三大基本特性:cgroup、namespace和unionFS

  cgroup:全称Control Group,用来限定一个进程中资源的使用,可以限制和隔离Linux进程组(process group)所使用的物理资源(cpu、内存、磁盘)

  namespace是Linux内核提供的一种资源隔离方案。主要用来隔离PID、IPC、Network等系统资源。每个namespace中的资源,相对其他namespace都是透明的,不同container内的进程属于不同的namespace。

  unionFS可以把文件系统中多个目录内容联合挂载到同一个目录下。
  https://blog.csdn.net/RA681t58CJxsgCkJ31/article/details/104707642

2. 总体架构

  Docker采用C/S架构,客户端和服务器通过http协议进行通信。架构中主要模块有:DockerClient、DockerDaemon、Docker Registry、Graph、Driver、libcontainer以及Docker Container。

2.1. Docker Client

  Docker Client将命令解析为后端可以识别的格式,发送给Docker Daemon,后端各个模块根据命令执行相应的操作。Docker Client可以通过三种方式和Docker Daemon建立通信:1. tcp://host:port 2.unix://path_to_socker 3. fd://socketfd,笔记中都是采用第一种方式进行通信,Docker Client可以通过命令行flag参数的形式,设置安全传输层协议(TLS)的有关参数,保证传输的安全性。

  用户需要先通过可执行文件docker创建Docker Client,Docker Client发送请求后,由Docker Daemon接收并处理,当Docker Client接收到返回的请求响应并做简单处理后,Docker Client一次完整的声明周期就此结束。如果需要继续发送命令,用户必须再次通过可执行文件docker创建Docker Client。

2.2. Docker Daemon

  Docker Daemon是Docker架构中的主体部分,具备服务端功能(接收Docker Client的请求),同时能够对接收的请求进行处理。Docker Daemon内部所有任务均由Engine完成,每一项工作以Job形式存在(如pull工作)。

  Docker Daemon是Docker架构中一个运行在后台的常驻进程,"运行Docker"即代表运行Docker Daemon。Docker Daemon作用主要分为如下两个方面:1. 接收并处理Docker Client发送的请求(服务器职能) 2. 管理所有的Docker容器。

  启动Docker Daemon所使用的可执行文件docker,与Docker Client启动所使用的可执行文件docker相同,docker -d代表Docker Daemon的启动,docker ps表示创建Docker Client并发送ps请求

  • Docker Daemon架构分为三个部分
  1. DockerServer:专门服务于Docker Client,功能是接收并调度分发Docker Client发送的请求。

      Docker Server通过gorilla/mux创建一个mux.Router路由器,提供请求的路由功能(Golang中gorilla/mux是一个强大的URL路由器以及调度分发器)。
      Docker Client通过http协议访问Docker Daemon,对于每一个Docker Client请求,DockerServe均会创建一个全新的goroutine来服务。

  2. Engine:Engine是Docker架构中的运行引擎,同时也是Docker运行的核心模块。 Engine存储着大量的容器信息,管理Docker大部分Job的执行。
  3. Job:Job是Docker架构中Engine内部最基本的工作执行单元。如Docker容器内部运行一个进程,是一个Job;创建一个新容器,这是一个Job;在网上下载一个文档,这是一个Job。

    Job接口的设计与UNIX进程类似。如,Job有一个名称,有运行时参数,有环境变量,有标准输入输出,有标准错误,返回状态等。

2.3. Docker Registry,Graph和Driver

  1. DockerRegistry是一个image仓库,镜像是容器创建时用来初始化容器rootfs的文件系统内容。

      Docker Registry将大量的容器镜像汇集在一起,并为分散的Docker Daemon提供镜像服务,Docker Hub就是全球范围内最大的公有Registry。
      Docker运行过程中,有三种情况会与Docker Registry通信,即上传,下载,搜索镜像时(push,pull,search)。

  2. Graph在Docker架构中扮演的角色时容器镜像的保管者。Graph对镜像的存储会因为镜像存储方式的不同(aufs、devicemapper、Btrfs)而存在一些差异。
  3. Driver是Docker架构中的驱动模块。

2.4. libcontainer

  libcontainer是一套独立的容器管理解决方案,这套解决方案涉及大量Linux内核方面的特性。libcontainer对Linux内核特性进行了抽象。libcontainer是Docker架构中一个Golang实现的库,目的是不依靠任何依赖,直接访问与容器相关的系统调用。

2.5. Docker Container

  Docker Container是Docker架构中服务交付的最终体现形式。

3. 创建运行容器

3.1. docker pull

  docker pull命令的作用是:Docker Daemon从Docker Registry下载指定的容器镜像,并将镜像存储在本地的Graph中。

具体步骤如下:

  1. Docker Client处理用户发起的docker pull命令,解析完请求和参数之后,发送http请求到Docker Server,请求方法为POST,请求URL为/images/create?+xxx
  2. Docker Server接收到HTTP请求,交给mux.Routermux.Router通过URL以及请求方法类型来确定执行该请求的具体handler(PostImagesCreate)。
  3. handler创建并初始化一个名为pull的Job
  4. pull Job在执行过程中执行pullRepository操作,即从Docker Registry中下载相应的一个或者多个Docker镜像。
  5. 将下载的镜像交给graphdriver管理
  6. graphdriver复制存储Docker镜像,一方面将实际镜像存储到本地文件系统,另一方面为镜像创建对象,由Docker Daemon统一管理

3.2. docker run

  docker run的作用是:创建一个全新的Docker容器,并在容器内部运行指定命令。docker run 命令完整执行流程中,Docker Client给Docker Server发送了两次HTTP请求,第二次请求的发起取决于第一次请求的返回状态。

具体步骤如下:

  1. Docker Client处理用户发起的docker pull命令,解析完请求和参数之后,发送http请求到Docker Server,请求方法为POST,请求URL为/containers/create?+xxx
  2. Docker Server接收到HTTP请求,交给mux.Routermux.Router通过URL以及请求方法类型来确定执行该请求的具体handler(PostContainersCreate)。
  3. handler创建并初始化一个名为create的Job。
  4. create Job在执行过程中执行Container.Create操作,该操作需要获取容器镜像来为Docker容器准备rootfs。
  5. graphdriver将rootfs的所有镜像通过某种联合文件系统的方式加载至Docker容器指定的文件目录下。

如果上述操作全部完成,并且没有返回错误或异常,发送第二次HTTP请求。

  1. Docker Client收到Docker Server返回状态之后,发起第二次HTTP请求,请求方法为POST,请求URL为/containers/+ container_ID + /start ,用来启动创建的容器对象。
  2. Docker Server接收到HTTP请求,交给mux.Routermux.Router通过URL以及请求方法类型来确定执行该请求的具体handler(PostContainersStart)。
  3. handler创建并初始化一个名为start的Job。
  4. start Job执行需要完成一系列与Docker容器相关的配置工作,包括分配网络资源等。
  5. networkdriver为指定的Docker容器分配网络资源,包括IP、port等,另外为容器设置防火墙规则。
  6. 返回名为start的Job,执行完一些辅助性操作后,Job开始执行用户指令,调用execdriver
  7. 调用execdriver,初始化Docker容器内部的运行环境,如命名空间、资源控制与隔离、用户命令执行等。
  8. 调用libcontainer,完成Docker容器内部的运行环境初始化,并最终执行用户要求启动的命令。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值