编者注:
本文根据有容云技术实施团队原创分享内容整理。对Docker技术感兴趣、或对本文中细节需继续探讨的朋友,欢迎加入我们参与讨论!
特别鸣谢中生代技术群分享支持。
注:本期分享由张朝潞原创,有容云整理发布,转载请注明出处
作者介绍:
张朝潞,有容云(Yourun Cloud)平台存储架构师。曾工作于UIT,华三,腾讯,专注分布式存储的研究和开发,对云计算存储解决方案方面有很深的技术造诣和行业理解。
本次交流将与大家分享Docker Volume plugin相关的内容。今日主题是窥探Docker中的Volume plugin内幕。
因为应用数据对安全,可用性,共享,性能等方面的要求和Root Image的要求完全不一样,所以Docker并不推荐采用Root Image的存储方式来存储应用数据,而是采用了Volume这样一个独立的数据访问接口。
应用通过Volume去访问相关的数据,Volume的实现和CoW的分层文件系统完全独立,通过Volume plugin机制可轻易驱动外部存储。
下面我们就围绕Volume Plugin Introduction、Container and Volume、Docker Volume Plugin、自定义Volume Plugin四个方面来展开。
一. Volume Plugin Introduction
通过Volume机制,Docker可以轻易地将主机目录挂载到容器中;通过Docker的Volume Plugin机制,使Docker能够方便地整合第三方存储,为Docker提供Volume。
出处链接:https://github.com/docker/docker/blob/master/docs/extend/plugins.md
二. Container and Volume
1 .Container如何使用Volume?
Volume机制可以使容器访问存储都使用统一的接口(文件接口),对于容器中的进程来说,Volume就是一个已挂载的目录,容器内进程使用该目录就与普通目录一样。
Docker使用Container结构管理容器,Container结构中有map类型的MountPoints变量,用于存储Container中所有已挂载的Volume即是MountPoint结构,MountPoint结构保存挂载目录和Volume结构的基本信息,并且管理目录的权限控制、挂载传播方式等特性。
Volume是个interface,Docker实现两种Volume:①基于主机文件系统。②基于Volume Plugin。
Container中的Volume
2.基于主机文件系统提供Volume
容器启动:docker run -i -v /data ubuntu:latest /bin/bash
容器内看到的挂载信息:
/etc/resolv.conf、/etc/hostname和/etc/hosts三个文件是为了解决每个Container都拥有自己的Hostname和DNS配置,使用了bind mount将主机的文件,挂载到Container内部。/data也是使用了同样的方式将主机的目录挂载到Container中。下面是主机挂载到Container的文件:
查看/dev/disk/by-uuid/88f22c9e-9d5d-4c7e-8984-eba8446361e6是链接文件指向/dev/sda2,这是主机的根目录文件系统。
3 .Container中的Volume
容器启动:
docker run -i -v cvol1:/data –volume-driver=convoy ubuntu:latest /bin/bash
将volume: dockervol挂载到容器目录/data
容器内看到的挂载信息:
此时挂载卷信息:
三. Docker Volume Plugin
1. Docker Volume Plugin框架
Docker volume框架
1.) Docker Daemon对Volume的管理
Docker Daemon中的Volume
如上图,Docker Daemon结构中有个成员Volumes,类型是VolumeStore类型,包含一组管理Volume的函数:Create、Remove、List、Get、Refs ...。通过两个变量,管理Container和Volume的关系。
Docker Daemon通过Volumes变量,就可以管理所有的Volume,提供如下命令:
2.) docker volume 管理
基于本地文件系统的volume框架
Docker提供两个接口Volume和Driver,所有提供给Docker使用的Volume必须实现Volume接口。后端驱动需要实现Driver接口。Driver是对提供出去的Volume进行管理。目前Docker实现了两种Volume &Driver。
① 基于本地文件系统的Volume
可以在执行Docker create或Docker run时,通过-v参数将主机的目录作为容器的数据卷。这部分功能便是基于本地文件系统的volume管理。上图中蓝色部分LocalVolume和Root。这两个结构就是对主机目录和文件进行管理,具体的对应关系如下图:
从上图可以看出,基于本地文件系统的卷管理,Driver便是卷的根目录/var/lib/docker/volumes。一个卷就是根目录下的一个子目录。
② 适配Plugin的Volume
Docker为了支持第三方存储方案,在1.8版本引入Volume Plugin机制,Volume Adapter和Volume Driver Adapter分别实现了接口Volume和Driver接口,用于表示由Plugin提供的Volume和Plugin driver。在下一小节详细描述。
基于本地文件系统的Volume框架中,全局变量drivers保存了所有注册到Docker Daemon的Driver。Docker Daemon需要对Volume进行管理操作时,通过GetDriver函数从drivers变量中获取指定名称的Driver,通过Driver可以通过Create,Remove,List,Get对Driver中Volume进行管理。通过Get函数获取Volume结构,可以对卷进行管理操作:Name,DriverName,Path,Mount,Unmount。
3 .) docker plugin 实现原理
Volume Plugin实现原理
① Docker Plugin机制
上一节已经说过Docker针对Volume Plugin实现了两个适配类型Volume Driver Adapter和Volume Adapter。
通过抽象,对于Plugin和其提供的Volume,Docker Daemon结构和Container结构使用上述两个适配类型,对Plugin和Volume进行管理和使用。
上述两个类型都有一个Volume Driver Proxy结构变量proxy,用于与Plugin进行通信。Volume Driver Proxy结构实现了与plugin通信的接口volume Driver,提供Create、Remove、Path、Mount、Unmount、List、Get接口与通信。Volume Driver Proxy结构的client变量,使用这个变量与Plugin Daemon进行通信。client变量是Plugin结构中的Client变量是Client结构类型,包含了http.Client类型对象。
上图中左下方,Plugins结构类型的全局变量Storage保存所有被Docker Daemon发现的Plugin结构,Plugin结构代表外部插件。
② Docker Plugin的发现过程
Docker Daemon通过Unix域套接字与Plugin Daemon进行通信。所以Plugin需要让Docker Daemon知道Plugin的Unix域套接字文件的路径。再执行命令:docker run ... -v volumename:/data --volume-driver=convoy
发现步骤:
③ Docker Volume Plugin的使用
执行docker run命令时,指定参数--volume-driver=convoy。Docker Daemon会先从storage.plugins中寻找Plugin结构,如果没有找到,就发起②的发现流程。找到则直接使用Client构建volume Driver Proxy。
④ Docker Daemon与Plugin Daemon通信的API
前面已经提到过,Docker Daemon和Plugin Daemon基于Unix域套接字,使用Restful API进行通信,下面是详细的API:
四. 自定义Volume Plugin
为了方便实现Volume Plugin,Docker提供go-plugins-helper包(https://github.com/docker/go-plugins-helpers),提供基础的功能,仅仅需要实现一个接口volume.Driver,并启动http server便可。
例子:GlusterFS就是使用这个包,基于GlusterFS提供Volume。https://github.com/calavera/docker-volume-glusterfs
关于Docker存储方面的内容,我们之前分享过一篇叫《Docker容器对存储的定义(Volume 与 Volume Plugin) 》的文章,感兴趣的朋友可以关注有容云搜索下。好的,我们今天的分享先告一个段落,谢谢大家!
温馨提示:
对Docker容器技术或容器生产实施感兴趣的朋友欢迎加群讨论。我们汇集了Docker容器技术落地实施团队精英及业内技术派高人,在线为您分享Docker技术干货。我们的宗旨是为了大家拥有更专业的平台交流Docker实战技术,我们将定期邀请嘉宾做各类话题分享及回顾,共同实践研究Docker容器生态圈。