本文主要会介绍笔者在学习Docker基础架构时所总结的知识点,其中会涉及到Docker Client、Docker Daemon以及Docker Driver
等几个方面的相关内容。
笔者也会将自己的理解在文中进行阐述,这也算是在和大家交流心得的一个过程。若文中有错误的理解和概念,请大家及时纠正;吸纳大家的建议,对于我来说也是很重要的学习过程之一。
1.架构概览
Docker本身是一种 C/S 架构
,其架构包括3个核心部分: Docker Client、Host以及Docker Registry。
其中,Docker的核心功能都集中在Host这一部分中;容器镜像的相关操作则是由Docker Registry来进行提供;与真实用户的交互由Docker Client来负责完成。
2.Docker Client
Client负责的工作有两个方面:
-
接收用户的操作请求 Client负责
接收并解析用户的操作指令和执行参数
,收集所需要的配置信息。 并且还需要负责将请求的处理结果返回给用户。 -
与Docker daemon进行交互 根据相应的 Docker 命令通过 HTTP 或 REST API 等方式
与 Docker daemon(守护进程)进行交互
,从而实现 Docker 服务使用与管理。
3. Docker Registry
Docker Registry即是一个存储容器镜像的仓库
。
Client 在接受到用户的指令后转发给 Host 下的 Daemon,它会通过网络与 Registry 进行通信,例如查询镜像(search),下载镜像(pull),推送镜像(push)等操作。
4. Host
Host即容器引擎进程
。
容器引擎进程是 Docker 架构的核心,其中包括Docker Daemon(守护进程)、Image(镜像)、Driver(驱动)、Libcontainer(容器管理)等。
4.1 Docker Daemon
Docker Daemon 进程是系统守护进程
。
Docker Daemon 负责监听Client发送过来的请求
(该请求中保存了用户对容器的操作需求);在接收到请求后,然后会执行后续的对应逻辑;另外其还能够管理 Docker的相关对象
(容器、镜像、网络、磁盘等)。
Docker Daemon又可被拆分为两种对象:Server和Engine。
4.1.1 Server
Server会负责接收Client接收发来的请求
,并在收到请求以后通过路由与分发调度来调用相应的 Handler处理请求
。
Server同时还会负责与容器镜像仓库交互
(查询、拉取、推送),并将操作结果返回给 Docker Client。
Tips: Server是由Daemon在后台启动的。
4.1.2 Engine
Docker Engine是 Daemon 架构中的运行引擎,同时也是 Docker 运行的核心模块。 Docker Engine是一个开源的容器运行时引擎,它可以运行在Linux、Windows和macOS等操作系统上。Docker Engine利用Linux内核中的命名空间和控制组特性,创建隔离的容器环境,并在这些容器环境中运行应用程序。
Tips: Docker Engine内部最关键的组件为runC,而runC是一个基于Libcontainer的低级container runtime。
Engine 执行的每一项工作都可以拆解成多个最小动作: Job
,即Job为Engine最基本的工作执行单元。Job 不光能用在 Engine 内部,Docker 内部每一步操作都可以抽象为一个 Job。Job 负责执行各项操作时会使用下层的 Driver(驱动)来完成
,例如储存拉取的镜像,配置容器网络环境等。
4.2 Docker Driver
抽象出Docker Driver是为了解耦Daemon与容器操作/管理
,将容器管理的镜像、网络和隔离执行逻辑从 Docker Daemon的逻辑中剥离。这样的设计可以使得当需要修改对容器的相关操作时,无需对Docker Daemon进行任任何改动,从而增加了Docker Daemon的稳定性。
Tips: Docker Daemon中对容器的各类操作进行了抽象,即给出了容器操作的规范。而Driver实际上是实现了这些抽象概念/接口。可以理解为是Docker Daemon依赖的是Driver的抽象类,而每一种具体Driver为抽象类的具体实现类。
Docker Driver中分为以下几类驱动。
4.2.1 graph driver
graph driver负责容器镜像的管理
,主要就是镜像的存储和获取。当镜像下载的时候,会将镜像持久化存储到本地的指定目录。
4.2.2 network driver
network driver主要负责 Docker 容器网络环境的配置
。例如Docker 运行时进行 IP 分配端口映射以及启动时创建网桥和虚拟网卡。
4.2.3 exec driver
exec driver是Docker的执行驱动,通过操作 Lxc 或者 libcontainer 实现资源隔离。exec driver负责创建管理容器运行命名空间、管理分配资源和容器内部真实进程的运行
。
4.2.3.1 libcontainer
exec driver通过调用Libcontainer 来完成对容器的操作,例如通过加载容器配置来创建真正的 Docker 容器。
Libcontainer是一个开源的Linux容器管理库,它是由Docker团队开发的,用于支持Docker容器引擎的底层。Libcontainer提供了一个接口,使得应用程序可以直接访问Linux内核中的容器相关功能,例如命名空间、控制组、文件系统等。即Libcontainer 提供了访问linux内核中的容器相关API以来实现对容器进行具体操作
。
因此Libcontainer实际上是对底层容器的实现方式进行了抽象
。
4.2.4 stroge driver
stroge driver主要用来管理容器文件系统的镜像层和容器层,即容器文件系统的创建和管理都是由stroge driver负责的
。像是容器镜像中的写时复制功能,就是由stroge driver封装的相关linux文件系统调用接口来实现的。
Docker支持多种stroge driver,例如AUFS, Device Mapper, VFS, OverlayFS, ZFS, Btrfs等等。Docker官方的默认选择为:优先使用linux发行版默认的stroge driver。目前linux中最常见的默认选项是使用OverlayFS。
5.Docker架构中Container Runtime的相关实现
Container Runtime在实现上分为两大类:高级Runtime与低级Runtime,在Docker的架构中,这两个概念都有对应的组件来进行了实现。
集成在Docker Engine内部的runC就是低级Runtime
。
其主要负责对容器生命周期进行管理,这部分功能实际上是借助Libcontainer来实现的。
Docker Daemon则对应的是高级Runtime
。
其通过内部的sever对外提供容器操作的相关API;通过调用Engine来实现对容器的生命周期管理;通过调用graph driver来实现对容器镜像的管理。