一、Docker架构(摘自《Docker源码分析》)

1、Docker总体架构

Docker 是一个C/S模式的架构,后端是一个非常松耦合的架构,模块间各司其职并有机组合来支撑Docker的运行。

总体架构如下:

Docker总体架构.jpg

架构图解析

1.1、用户使用Docker Client 与 Docker Daemon建立通信,并发送请求给后者
1.2、Docker Daemon 作为Docker架构中的主体部分,首先提供Docker Server的功能使其可以接受Docker Client的请求。
1.3、Docker Engine 执行 Docker 内部的一系列工作,每一项工作都是以一个 Job 的形式的存在。
1.4、Job 的运行过程中,当需要容器镜像时,则从 Docker Registry 中下载镜像,并通过镜像管理驱动 Graphdriver 将下载镜像以 Graph 的形式存储。
1.5、当需要为 Docker 创建网络环境时,通过网络管理驱动 Networkdriver 创建并配置 Docker容器网络环境。
1.6、当需要限制 Docker 容器运行资源或执行用户指令等操作时,则通过 Execdriver 来完成。
1.7、Libcontainer 是一项独立的容器管理包,Networkdriver 以及 Execdriver 都是通过 Libcontainer 来实现具体对容器进行的操作。

2、Docker 各个模块组件分析

2.1、Docker Client(客户端发起请求)
2.1.1、Docker Client 是 和 Docker Daemon 建立通信的客户端。用户使用的可执行文件为 docker(一个命令行可执行文件),docker 命令使用后接参数的形式来实现一个完整的请求命令(例如:docker images,docker 为命令不可变,images 为参数可变)。
2.1.2、Docker Client 可以通过以下三种方式和 Docker Daemon 建立通信:tcp://host:portunix://pathtosocketfd://socketfd
2.1.3、Docker Client 发送容器管理请求后,由 Docker Daemon 接受并处理请求,当 Docker Client 接收到返回的请求相应并简单处理后,Docker Client 一次完整的生命周期就结束了。(一次完整的请求:发送请求→处理请求→返回结果),与传统的 C/S 架构请求流程并无不同。
2.2、Docker Daemon(后台守护进程)

Docker Daemon 是Docker架构中一个常驻在后台的系统进程,功能是:接受并处理Docker Client 发送的请求。该守护进程在后台启动了一个server,server负责接受Docker Client 发送的请求;接受请求后,server 通过路由与分发调度,找到相应的Handler来执行请求
Docker Daemon 启动所使用的可执行文件也为 docker,与 Docker Client 启动所使用的可执行文件 docker 相同。在 docker 命令执行时,通过传入的参数来判别 Docker Daemon 与 Docker Client。
Docker Daemon 的架构,大致可以分为以下三部分:Docker Server、Engine 和 Job

Docker Daemon 的架构如下:

Docker Daemon架构图.jpg
2.2.1、Docker Server

Docker Server 在 Docker 架构中是专门服务于 Docker Client 的 server。
Docker Server 的功能是:接受并调度分发 Docker Client 发送的请求

Docker Serve 的架构如下:

Docker Serve 架构.jpg

1)Docker Server 相当于 C/S 架构的服务端。功能为接受并调度分发 Docker Client 发送的请求。接受请求后,Docker Server 通过路由与分发调度,找到相应的 Handler 来执行请求。
2)在 Docker 的启动过程中,通过包 gorilla/mux 创建了一个 mux.Router 来提供请求的路由功能。在 Golang 中 gorilla/mux 是一个强大的 URL 路由器以及调度分发器。该 mux.Router 中添加了众多的路由项,每一个路由项由 HTTP 请求方法(PUT、POST、GET 或DELETE)、URL、Handler 三部分组成。
3)创建完 mux.Router 之后,Docker 将 Server 的监听地址以及 mux.Router 作为参数来创建一个 httpSrv=http.Server{},最终执行 httpSrv.Serve() 为请求服务。
4)在 Docker Server 的服务过程中,Docker Server 在 listener 上接受 Docker Client 的访问请求,并创建一个全新的 goroutine 来服务该请求。在 goroutine 中,首先读取请求内容并做解析工作,接着找到相应的路由项并调用相应的 Handler 来处理该请求,最后 Handler 处理完请求之后回复该请求。

2.3 Docker Engine(运行引擎)
2.3.1 Docker Engine 是 Docker 架构中的运行引擎,同时也 Docker 运行的核心模块。它扮演 Docker Container 存储仓库的角色,并且通过执行 Job 的方式来操纵管理这些容器。
2.3.2 在 Docker Engine 数据结构的设计与实现过程中,有一个 Handler 对象。该 Handler 对象存储的都是关于众多特定 Job 的 Handler 处理访问。举例说明: Docker Engine 的Handler 对象中有一项为:{“create”: daemon.ContainerCreate,},则说明当名为”create” 的 Job 在运行时,执行的是 daemon.ContainerCreate 的 Handler。
2.3.3 Job

1)一个 Job 可以认为是 Docker 架构中 Docker Engine 内部最基本的工作执行单元。Docker 可以做的每一项工作,都可以抽象为一个 Job。例如:在容器内部运行一个进程,这是一个 Job;创建一个新的容器,这是一个 Job。Docker Server 的运行过程也是一个 Job,名为 ServeApi。
2)Job 的设计者,把 Job 设计得与 Unix 进程相仿。比如说:Job 有一个名称、有参数、有环境变量、有标准的输入输出、有错误处理,有返回状态等。

2.4 Docker Registry(镜像注册中心)
2.4.1 Docker Registry 是一个存储容器镜像的仓库(注册中心),可理解为云端镜像仓库。按 Repository 来分类,docker pull 按照 [repository]:[tag] 来精确定义一个具体的 Image。
2.4.2 在 Docker 的运行过程中,Docker Daemon 会与 Docker Registry 通信,并实现搜索镜像、下载镜像、上传镜像三个功能,这三个功能对应的 Job 名称分别为:“search”、”pull” 与 “push”。
2.4.3 Docker Registry 可分为公有仓库( Docker Hub)和私有仓库。
2.5 Graph(Docker 内部数据库)

Graph 在 Docker 架构中扮演已下载容器镜像的保管者,以及已下载容器镜像之间关系的记录者。一方面,Graph 存储着本地具有版本信息的文件系统镜像,另一方面也通过 GraphDB 记录着所有文件系统镜像彼此之间的关系。

Graph架构图如下:

Graph架构图.jpg
2.5.1 Repository(仓储)

1)已下载镜像的保管者(包括下载的镜像和通过 Dockerfile 构建的镜像)。
2)一个 Repository 表示某类镜像的仓库(例如:Ubuntu),同一个 Repository 内的镜像用 Tag 来区分(表示同一类镜像的不同标签或版本)。一个 Registry 包含多个Repository,一个 Repository 包含同类型的多个 Image。
3)镜像的存储类型有 Aufs、Devicemapper、Btrfs、Vfs等。其中 CentOS 系统 7.x 以下版本使用 Devicemapper 的存储类型。
4)同时在 Graph 的本地目录中存储有关于每一个的容器镜像具体信息,包含有:该容器镜像的元数据、容器镜像的大小信息、以及该容器镜像所代表的具体 rootfs。

2.5.2 GraphDB

1)已下载容器镜像之间关系的记录者。
2) GraphDB 是一个构建在 SQLite 之上的小型数据库,实现了节点的命名以及节点之间关联关系的记录。

2.6 Driver(驱动执行部分)

Driver 是 Docker 架构中的驱动模块。通过 Driver 驱动,Docker 可以实现对 Docker 容器执行环境的定制。由于 Docker 运行的生命周期中,并非用户所有的操作都是针对 Docker 容器的管理,另外还有关于 Docker 运行信息的获取,Graph 的存储与记录等。因此,为了将 Docker 容器的管理从 Docker Daemon 内部业务逻辑中区分开来,设计了 Driver 层驱动来接管所有这部分请求。
Graph 负责镜像的存储,Driver 负责容器的执行。

在 Docker Driver 的实现中,可以分为以下三类驱动:graphdriver、networkdriver 和 execdriver。

2.6.1 graphdriver (容器镜像驱动)

1)Graphdriver 主要用于完成容器镜像的管理,包括存储与获取。
2)存储:docker pull 下载的镜像由 Graphdriver 存储到本地的指定目录( Graph 中 )。
3)获取:docker run(create)用镜像来创建容器的时候由 Graphdriver 到本地 Graph中获取镜像。
在 graphdriver 的初始化过程之前,有 4 种文件系统或类文件系统在其内部注册,它们分别是 aufs、btrfs、vfs 和 devmapper。而 Docker 在初始化之时,通过获取系统环境变量”DOCKER_DRIVER”来提取所使用 driver 的指定类型。而之后所有的 graph 操作,都使用该 driver 来执行。

graphdriver 架构图如下:

graphdriver 架构图.jpg
2.6.2 Networkdriver (网络配置驱动)

Networkdriver 的用途是完成 Docker 容器网络环境的配置,其中包括:
1)Docker 启动时为 Docker 环境创建网桥。
2)Docker 容器创建时为其创建专属虚拟网卡设备。
3)Docker 容器分配IP、端口并与宿主机做端口映射,设置容器防火墙策略等。

networkdriver 架构图如下:

networkdriver 架构图.jpg
2.6.3 Execdriver(管理执行驱动)

1)Execdriver 作为 Docker 容器的执行驱动,负责创建容器运行命名空间、容器资源使用的统计与限制、容器内部进程的真正运行等。
2)现在 Execdriver 默认使用 Native 驱动,不依赖于 LXC。

Execdriver 架构图如下:

Execdriver 架构图.jpg
2.7 Libcontainer(容器函数库)

1)Libcontainer 是 Docker 架构中一个使用 Go 语言设计实现的库,设计初衷是希望该库可以不依靠任何依赖,直接访问内核中与容器相关的 API。
2)Docker 可以直接调用 Libcontainer 来操纵容器的 Namespace、Cgroups、Apparmor、网络设备以及防火墙规则等。
3)Libcontainer 提供了一整套标准的接口来满足上层对容器管理的需求。或者说 Libcontainer 屏蔽了 Docker 上层对容器的直接管理。

Libcontainer 架构图如下:

Libcontainer 架构图.jpg
2.8 Docker Container(docker 容器-服务交付的最终形式)
2.8.1 Docker Container( Docker 容器 )是 Docker 架构中服务交付的最终体现形式。
2.8.2 Docker 按照用户的需求与指令,订制相应的 Docker 容器:

1)用户通过指定容器镜像,使得 Docker 容器可以自定义 rootfs 等文件系统。
2)用户通过指定计算资源的配额,使得 Docker 容器使用指定的计算资源。
3)用户通过配置网络及其安全策略,使得 Docker 容器拥有独立且安全的网络环境。
4)用户通过指定运行的命令,使得 Docker 容器执行指定的工作。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,980评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,422评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,130评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,553评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,408评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,326评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,720评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,373评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,678评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,722评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,486评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,335评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,738评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,283评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,692评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,893评论 2 335

推荐阅读更多精彩内容