正文
从上面这组接口可以看出, Docker 容器是通过 mount 的方式将外部存储挂载到本地目录,尽量使内部应用程序对存储是无感知的,应用程序就像使用本地目录一样使用外部存储卷,而将外部存储的管理交给存储 Plugin 负责(如 Flocker、Rancher Convoy,REX-Ray 等)。
容器正逐渐成为云计算平台应用程序的标准部署单元,容器能轻易的将各式各样的应用程序及其 runtime 打包成统一的对象,于是编排调度系统能把各种应用程序当成统一的容器进行处理,大大简化编排调度系统的复杂度。结合 Docker 对存储插件的定义,不难看出
Docker 希望容器的运行环境独立而纯粹,不希望引入有状态和复杂的存储系统。
二、存储插件
Convoy 作为一个 Docker volume plugin,支持不同的后端存储,为 Docker 提供 MountPoint,也就是一个的目录,可能是挂载了后端存储、本地块设备或者就是本地目录。
Convoy 的代码从结构、风格和使用的库,都与 Docker 十分相似,并且比 Docker 简单很多。
(小编:下面展开介绍一下 convoy 源代码的部分模块,不需要了解细节的读者可以直接跳到第三部分:容器、应用程序、持久化存储。)
Convoy 在源码级别上值得留意的点,我认为有两点:①插件式结构与 interface 的运用。② 作者对事物的抽象能力与方法。
1、convoy daemon (convoy / daemon)
图 1 中黑色部分
daemon 是主要的功能模块,可以接收来自 convoy client 和 Docker 的命令,对 backend 存储进行了抽象,以便统一管理。下面先从 daemon 的启动开始。
1.1、daemon 进程启动
1)执行命令:
convoy daemon --drivers glusterfs --driver-opts glusterfs.servers=192.168.0.3 --driver-opts glusterfs.defaultvolumepool=vol2
2) convoy 程序解析参数,获得 daemon 子命令,调用到 daemon.Start 函数(convoy/daemon/daemon.go), Start 函数中主要围绕 daemon struct 建立所需要环境和配置。
3) Driver 初始化,优先从配置文件读取信息忽略命令行输入的参数,如果配置文件不存在则根据命令行参数初始化。
图 2. convoy 配置文件内容
遍历 DriverList,找到配置文件或命令行指定的 Driver,执行初始化函数 Init,并添加到 daemon.ConvoyDrivers 中。
4)根据 convoy 的工作目录的内容,更新管理元数据,图 1 中也有相应的模块。
图 3.convoy 工作目录和 volume 配置文件
5) Router 注册: Router 提供两部分的路由,并将 daemon 的 Router 指向该 Router。
(1) 处理 convoy client 的命令 Client Request Router,处理客户端发送的 HTTP request。
(2) 处理来自 Docker 的请求 Docker Volume Plugin Router, convoy 本身就是 Docker 的 volume plugin,提供了如下的接口。
6) HTTP server 启动,根据 sockFile = /var/run/convoy/convoy.sock 和 上一步骤的 Router,启动 HTTP server。
2.2、daemon 的请求处理逻辑
Daemon 启动后便可以处理请求( convoy client 或 Docker),主要处理逻辑 Router 收到 HTTP 请求,将请求分发给各个模块: Docker、 volume、 snapshot、 backup。这个 4 个逻辑模块根据 driver name( 指定的或者默认的 ) 从 daemon.ConvoyDrivers 中获取对应的 Driver。 ConvoyDrivers 中的 Driver 是实现了 ConvoyDriver interface 的结构。
图 4.convoy daemon 请求处理逻辑
从图 4 中可以看出 ConvoyDriver 接口规定了 3 组接口对应 volume, snapshot, backup 的操作,用于操作 backend storage。逻辑处理最终调用这些接口访问 Backend Storage。
2.3、ConvoyDriver implement
截止到 0.4.3 版本, convoy 支持 4 种后端存储(实现了 ConvoyDriver 接口),如下表。
下面来说说,convoy 是如何对后端存储进行抽象和管理,它使用了 4 种结构 Driver, Volume, Snapshot, Device。
-
Driver:主要实现了 ConvoyDriver 接口,提供对 Volume, Snapshot, Backup 等功能。
-
Volume:管理提供到 Docker 或者 convoy client 的 Volume。
-
Snapshot:用于管理 Volume 的快照。
-
Device:管理后端存储提供的存储空间,如: devicemapper 的 device ; glusterfs 的 volume ; vfs 的目录等。