2万字长文:Kubernetes云原生开源分布式存储( 二 )

因此从1.8开始 , Kubernetes停止往Kubernetes代码中增加新的存储支持 ,并推出了一种新的插件形式支持外部存储系统 , 即FlexVolume , 不过FlexVolume其实在1.2就提出了 。
FlexVolume类似于CNI插件 , 通过外部脚本集成外部存储接口 , 这些脚本默认放在 /usr/libexec/kubernetes/kubelet-plugins/volume/exec/, 需要安装到所有Node节点上 。
这样每个存储插件只需要通过外部脚本(out-of-tree)实现 attach 、 detach 、 mount 、 umount 等接口即可集成第三方存储 , 不需要动Kubernetes源码 , 可以参考官方的一个 LVM FlexVolume Demo [1]。
但是这种方法也有问题:

  • 脚本文件放在host主机上 , 因此驱动不得不通过访问宿主机的根文件系统去运行脚本 。
  • 这些插件如果还有第三方程序依赖或者OS兼容性要求 , 还需要在所有的Node节点安装这些依赖并解决兼容问题 。
因此这种方式虽然解决了in-tree的问题 , 但显然这种方式用起来不太优雅 , 不太原生 。
因此Kubernetes从1.9开始又引入了Container Storage Interface (CSI)容器存储接口 , 并于1.13版本正式GA 。
CSI的实现方案和CRI类似通过gRPC与volume driver进行通信 , 存储厂商需要实现三个服务接口Identity Service、Controller Service、Node Service ,
  • Identity Service用于返回一些插件信息;
  • Controller Service实现Volume的CURD操作 ,
  • Node Service运行在所有的Node节点 , 用于实现把volume挂载在当前Node节点的指定目录 , 该服务会监听一个Socket , controller通过这个Socket进行通信 , 可以参考官方提供的样例 CSI Hostpath driver Sample [2]。
更多有关CSI介绍可以参考官方的设计文档 CSI Volume Plugins in Kubernetes Design Doc [3]。
通过CSI基本解决了如上in-tree以及FlexVolume的大多数问题 , 未来Kubernetes会把in-tree的存储插件都迁移到CSI 。
当然Flex Volume Plugin也会与新的CSI Volume Plugin并存以便兼容现有的第三方FlexVolume存储插件 。
1.3 为什么需要云原生分布式存储通过CSI接口或者Flex Volume Plugin解决了Kubernetes集成外部存储的问题 , 目前Kubernetes已经能够支持非常多的外部存储系统了 , 如NFS、GlusterFS、Ceph、OpenStack Cinder等 , 这些存储系统目前主流的部署方式还是运行在Kubernetes集群之外单独部署和维护 , 这不符合All In Kubernetes的原则 。
如果已经有分布式存储系统还好 , 可以直接对接 。 但如果没有现成分布式存储 , 则不得不单独部署一套分布式存储 。
很多分布式存储部署相对还是比较复杂的 , 比如Ceph 。 而Kubernetes天生就具有快速部署和编排应用的能力 , 如果能把分布式存储的部署也通过Kubernetes编排管理起来 , 则显然能够大大降低分布式存储的部署和维护成本 , 甚至可以使用一条apply命令就可以轻松部署一个Ceph集群 。
这主要有两种实现思路:
  • 第一种思路就是重新针对云原生平台设计一个分布式存储 , 这个分布式存储系统组件是微服务化的 , 能够复用Kubernetes的调度、故障恢复和编排等能力 , 如后面要介绍的Longhorn、OpenEBS 。
  • 另一种思路就是设计微服务组件把已有的分布式存储系统包装管理起来 , 使原来的分布式存储可以适配运行在Kubernetes平台上 , 实现通过Kubernetes管理原有的分布式存储系统 , 如后面要介绍的Rook 。
1.4 Container Attached Storage , 容器存储的未来?我们知道组成云计算的三大基石为计算、存储和网络 , Kubernetes计算(Runtime)、存储(PV/PVC)和网络(Subnet/DNS/Service/Ingress)的设计都是开放的 , 可以集成不同的方案 , 比如网络通过CNI接口支持集成Flannel、Calico等网络方案 , 运行时(Runtime)通过CRI支持Docker、Rkt、Kata等运行时方案 , 存储通过volume plugin支持集成如AWS EBS、Ceph、OpenStack Cinder等存储系统 。
但是我们发现目前主流的方案中存储与计算、网络稍有不同 , 计算和网络都是以微服务的形式通过Kubernetes统一编排管理的 , 即Kubernetes既是计算和网络的消费者 , 同时也是计算和网络的编排者和管理者 。
而存储则不一样 , 虽然Kubernetes已经设计了PV/PVC机制来管理外部存储 , 但只是弄了一个标准接口集成 , 存储本身还是通过独立的存储系统来管理 , Kubernetes根本不知道底层存储是如何编排和调度的 。
社区认为既然计算和网络都由我Kubernetes统一编排了 , 是不是存储也考虑下?
于是社区提出了Container Attached Storage(CAS)理念 , 这个理念的目标就是利用Kubernetes来编排存储 , 从而实现我Kubernetes编排一切 , 这里的一切包括计算、存储、网络 , 当然更高一层的还包括应用、服务、软件等 。