目录
Docker 核心架构(二)
一、Docker 总架构
二、Docker各模块组件分析
2.1. Docker Client [发起请求]
2.2. Docker Daemon [后台守护进程]
2.2.1. Docker Server [调度分发请求]
2.2.2. Engine
2.2.3. Job
2.3. Docker Registry [镜像注册中心]
2.4. Graph [Docker内部数据库]
2.4.1. Repository
2.5. Driver [执行部分]
2.4.2. GraphDB
2.5.1. graphdriver
2.5.2. networkdriver
2.5.3. execdriver
2.6. libcontainer[函数库]
2.7. docker container [服务交付的最终形式]
Docker 核心架构(二)
这篇文章介绍了Docker的核心架构及各模块组件分析。Docker采用C/S模式架构,后端是一个松耦合架构,模块各司其职。具体分析了Docker Client、Docker Daemon、Docker Registry、Graph、Driver、libcontainer、docker container等各模块。其中,Driver是Docker架构中的驱动模块,负责容器的执行环境的定制。文章附有多幅架构图进行解析。
Docker 核心架构(二)
一、Docker 总架构
Docker 是一个 C/S 模式的架构,后端是一个松耦合架构,模块各司其职。
- 用户是使用 Docker Client 与 Docker Daemon 建立通信,并发送请求给后者。
- Docker Daemon 作为 Docker架 构中的主体部分,首先提供 Server 的功能使其可以接受 Docker Client 的请求;
- Engine 执行 Docker 内部的一系列工作,每一项工作都是以一个Job的形式的存在。
- Job 的运行过程中,当需要容器镜像时,则从 Docker Registry 中下载镜像,并通过镜像管理驱动 graphdriver 将下载镜像以Graph 的形式存储;
- 当需要为 Docker 创建网络环境时,通过网络管理驱动 networkdriver 创建并配置 Docker 容器网络环境;
- 当需要限制 Docker 容器运行资源或执行用户指令等操作时,则通过 execdriver 来完成。
- libcontainer 是一项独立的容器管理包,networkdriver 以及 execdriver 都是通过 libcontainer 来实现具体对容器进行的操作。
二、Docker各模块组件分析
2.1. Docker Client [发起请求]
- Docker Client 是和 Docker Daemon 建立通信的客户端。用户使用的可执行文件为 docker(类似可执行脚本的命令),docke r命令后接参数的形式来实现一个完整的请求命令(例如 docker images,docker为命令不可变,images为参数可变)。
- Docker Client 可以通过以下三种方式和 Docker Daemon 建立通信:tcp://host,unix://path_to_socket 和 fd://socketfd。
- Docker Client 发送容器管理请求后,由 Docker Daemon 接受并处理请求,当 Docker Client 接收到返回的请求相应并简单处理后,Docker Client 一次完整的生命周期就结束了。[一次完整的请求:发送请求→处理请求→返回结果],与传统的 C/S 架构请求流程并无不同。
2.2. Docker Daemon [后台守护进程]
Docker Daemon的架构图
2.2.1. Docker Server [调度分发请求]
Docker Server的架构图
- Docker Server 相当于 C/S 架构的服务端。功能为接受并调度分发 Docker Client 发送的请求。接受请求后,Server 通过路由与分发调度,找到相应的 Handler 来执行请求。
- 在 Docker 的启动过程中,通过包 gorilla/mux,创建了一个 mux.Router,提供请求的路由功能。在 Golang 中,gorilla/mux 是一个强大的 URL 路由器以及调度分发器。该 mux.Router 中添加了众多的路由项,每一个路由项由 HTTP 请求方法(PUT、POST、GET 或 DELETE 等)、URL、Handler三部分组成。
- 创建完 mux.Router 之后,Docker 将 Server 的监听地址以及 mux.Router 作为参数,创建一个 httpSrv=http.Server{},最终执行httpSrv.Serve() 为请求服务。
- 在 Server 的服务过程中,Server 在 listener 上接受 Docker Client 的访问请求,并创建一个全新的 goroutine 来服务该请求。在goroutine 中,首先读取请求内容,然后做解析工作,接着找到相应的路由项,随后调用相应的 Handler 来处理该请求,最后Handler 处理完请求之后回复该请求。
2.2.2. Engine
- Engine 是 Docker 架构中的运行引擎,同时也 Docker 运行的核心模块。它扮演 Docker container 存储仓库的角色,并且通过执行 job 的方式来操纵管理这些容器。
- 在 Engine 数据结构的设计与实现过程中,有一个 handler 对象。该 handler 对象存储的都是关于众多特定 job 的 handler 处理访问。举例说明,Engine 的 handler 对象中有一项为:{“create”: daemon.ContainerCreate,},则说明当名为“create”的 job 在运行时,执行的是 daemon.ContainerCreate 的 handler。
2.2.3. Job
- 一个 Job 可以认为是 Docker 架构中 Engine 内部最基本的工作执行单元。Docker 可以做的每一项工作,都可以抽象为一个job。例如:在容器内部运行一个进程,这是一个 job;创建一个新的容器,这是一个 job。Docker Server 的运行过程也是一个job,名为 serveapi。
- Job 的设计者,把 Job 设计得与Unix进程相仿。比如说:Job 有一个名称,有参数,有环境变量,有标准的输入输出,有错误处理,有返回状态等。
2.3. Docker Registry [镜像注册中心]
- Docker Registry 是一个存储容器镜像的仓库(注册中心),可理解为云端镜像仓库,按 repository 来分类,docker pull 按照[repository]:[tag] 来精确定义一个 image。
- 在 Docker 的运行过程中,Docker Daemon 会与 Docker Registry 通信,并实现搜索镜像、下载镜像、上传镜像三个功能,这三个功能对应的job名称分别为”search”,”pull” 与 “push”。
- 可分为公有仓库(docker hub)和私有仓库。
2.4. Graph [Docker内部数据库]
Graph的架构图
2.4.1. Repository
- 已下载镜像的保管者(包括下载镜像和 dockerfile 构建的镜像)。
- 一个repository表示某类镜像的仓库(例如 Ubuntu ),同一个 repository 内的镜像用tag来区分(表示同一类镜像的不同标签或版本)。一个 registry 包含多个 repository ,一个 repository 包含同类型的多个 image 。
- 镜像的存储类型有 aufs,devicemapper , Btrfs,Vfs等。其中 centos 系统使用 devicemapper 的存储类型。
- 同时在 Graph 的本地目录中,关于每一个的容器镜像,具体存储的信息有:该容器镜像的元数据,容器镜像的大小信息,以及该容器镜像所代表的具体 rootfs 。
Driver 是 Docker 架构中的驱动模块。通过 Driver 驱动,Docker 可以实现对 Docker 容器执行环境的定制。即 Graph 负责镜像的存储,Driver 负责容器的执行。
2.5. Driver [执行部分]
- GraphDB 是一个构建在 SQLite 之上的小型图数据库,实现了节点的命名以及节点之间关联关系的记录
- 已下载容器镜像之间关系的记录者。
2.4.2. GraphDB
2.5.1. graphdriver
graphdriver架构图
- graphdriver 主要用于完成容器镜像的管理,包括存储与获取。
- 存储:docker pull 下载的镜像由 graphdriver 存储到本地的指定目录( Graph 中)。
- 获取:docker run(create)用镜像来创建容器的时候由 graphdriver 到本地 Graph 中获取镜像。
2.5.2. networkdriver
networkdriver的架构图
- networkdriver 的用途是完成 Docker 容器网络环境的配置,其中包括
- Docker 启动时为 Docker 环境创建网桥;
- Docker 容器创建时为其创建专属虚拟网卡设备;
- Docker 容器分配 IP、端口并与宿主机做端口映射,设置容器防火墙策略等。
2.5.3. execdriver
execdriver的架构图
- execdriver 作为 Docker 容器的执行驱动,负责创建容器运行命名空间,负责容器资源使用的统计与限制,负责容器内部进程的真正运行等。
- 现在 execdriver 默认使用 native 驱动,不依赖于LXC。
2.6. libcontainer[函数库]
libcontainer的架构图
- libcontainer 是 Docker 架构中一个使用 Go 语言设计实现的库,设计初衷是希望该库可以不依靠任何依赖,直接访问内核中与容器相关的 API。
- Docker 可以直接调用 libcontainer ,而最终操纵容器的 namespace、cgroups、apparmor、网络设备以及防火墙规则等。
- libcontainer 提供了一整套标准的接口来满足上层对容器管理的需求。或者说,libcontainer 屏蔽了 Docker 上层对容器的直接管理。
2.7. docker container [服务交付的最终形式]
container架构
- Docker container( Docker 容器)是 Docker 架构中服务交付的最终体现形式。
- Docker 按照用户的需求与指令,订制相应的 Docker 容器:
- 用户通过指定容器镜像,使得 Docker 容器可以自定义 rootfs 等文件系统;用户通过指定计算资源的配额,使得 Docker 容器使用指定的计算资源;用户通过配置网络及其安全策略,使得 Docker 容器拥有独立且安全的网络环境;用户通过指定运行的命令,使得 Docker 容器执行指定的工作。
本文作者:LiuXueChao
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA
许可协议。转载请注明出处!