任何应用程序都需要数据支撑,这也是我们商业存在基石。最初,容器应运而生的主要目的之一也是为了解决无状态服务。但短期时间内,随着技术的不断成熟,允许容器化应用程序直接访问数据的需求也在不断的增加。现代化的应用程序和传统的应用程序都需要诸如文件、块,或者工具化文件存储对象、关系型数据库、流媒体文件等这些不同类型的存储。
虚拟机也可以管理应用程序,但是这种方法对硬件仿真有一定的要求,容器可以保证应用程序的可移植性远大于虚拟化的实现。实际应用程序的可移植性的能力,还依赖于个容器编排工具的互操作性。对于当前的原生云应用程序,存储也是一个很关键的组件,因为应用程序可以利用持久存储平台以及围绕其特性进一步开发特性功能。
容器的协调者和运行时对存储服务发起特定的请求,可以实现诸如创建/删除、检查/清单、附加/分离、安装/卸载等操作。这是解决容器协调者之间存储问题的一种独特的尝试,不过在行业中也是有分歧的。对外存储编排请求API分为两种情况:首先,是in-tree驱动程序,它是直接将原生代码编译到容器协调器;第二,是out-of-tree,借助于外部插件驱动。每一种方式都有自己的优缺点:in-tree驱动器受制于容器协调器的发布周期;而out-of-tree插件式驱动可能无法提供与容器协调器绑定的增强特性集。
Docker
Docker是在1.7的实验版本中通过创建Docker Volume 驱动接口首次解决了外部存储的问题。1.13版本中Docker又引入了插件模型,也就是Docker Store(http://t.cn/RCvBExq)。通过查找目录/run/docker/plugins,Docker发现并可使用UNIX插件(.sock文件),这是一个使用out-of-tree模型的例子。
UNIX域套接字( Unix domain socket)文件必须在相同的Docker主机上运行。但如果指定了远程访问URL,插件也可以通过spec和json配置文件实现在不同的主机上运行。实现存储功能的集中化,这也是插件职责之一。该接口接受JSON、RPC类型的HTTP请求。out-of-tree模型公开的接口提供了完整的Volume生命周期,也为Docker CLI提供了编排功能。但是,如快照或复制等高级存储功能,还未提供暴露给Docker CLI。
Mesos
Mesos直到v0.23版本才开始支持本地存储。Mesos-Module-Dvdi(https://github.com/codedellemc/mesos-module-dvdi)就是为这个问题而提出的方案,随后它的特性被合并到Mesos,直到Mesos 1.0+版本方能使用。DVDCLI(https://github.com/codedellemc/dvdcli)是将Docker Volume Driver CLI打包封装到Mesos中,允许在所有的Mesos容器内使用任何Docker Volume驱动,Mesos-Module-Dvdi就是利用正在实施中的DVDCLI实现了本地存储。与Docker类似,框架与DVDCLI互联通信支持JSON格式,并且也提供使用JSON/RPC通过HTTP与Docker Volume Driver Interface通信。
正如前面所提及的,由于它使用了Docker Volume 驱动,因此它是一个out-of-tree插件,并且具有和Docker CLI相同的Volume生命周期和限制。
Kubernetes
Kubernetes的独特之处在于它既有in-tree又有out-of-tree驱动。我们已经在《Kubernetes存储说明》(http://t.cn/RCvBDnV)和《Kubernetes 1.6版本中关于存储的新功能》(http://t.cn/RCvrPrr)这两篇文章中详细说明,我们再次回顾下:
in-tree驱动来自于Kubernetes源码,也是其标准发行版的一部分。通过这些驱动,可以根据Kubernetes提供的接口(如Mount/Umount、Create/Delete等)向其存储平台暴露API,Kubernetes执行所有功能,并向驱动程序执行特定的API调用,从而执行所需的操作。这也可以充分利用Kubernetes的特性,比如:动态供应的存储类。这样也是有缺点的,如果系统BUG或增加需要新增一些平台特性,则依赖于Kubernetes的发布周期。发布周期可能意味着3-6个月的等待修复、持续维护、回合代码等流程。
Out-of-tree驱动使用Flexvolume接口。Flexvolume允许用户编写自己的驱动程序,并在Kubernetes中添加对其Volume的支持。供应商的驱动应该被安装在在每个Kubelet节点和主节点上,Volume插件的路径:usr/libexec/kubernetes/kubelet-plugins/volume/exec/<vendor~driver>/。这使得驱动程序可以在核心的Kubernetes代码之外运行,并且可以根据自己的时间节点表发布更新或者修复BUG。Flexvolume接口预期Volume的创建和删除可以基于外部插件进行。因此,Flexvolume只使用Attach/Detach 和 Mount/Unmount功能,而不是整个Volume的生命周期。
当前总概
把所有的存储功能结合在一起,我们可以看到这是一个非常碎片化的空间,以及三者之间各有千秋。
而所有这一切都意味着存储供应商需要创建多层次封装集成,从而支持整个容器生态系统。容器存储接口(CSI)项目处于早期阶段,但最终将会成为存储和容器成功的关键因素。
与此同时,我们已经将所有的功能整合,并且集成了针对每一种容器协调者功能的存储方法。我们深知当前和未来的容器化应用程序依赖存储,而且这个解决方案适应每一个场景:Docker和Mesos中的REX-Ray,FlexREX和Kubernetes,Docker中的REX-RAY插件,Kubernetes的本地ScaleIO驱动程序。