JuiceFS 是一款面向云环境设计的高性能共享文件系统,可以被多台主机同时挂载读写,使用对象存储来作为底层的存储层,我们没有重复造轮子,而是选择了站在对象存储的肩膀上。对象存储大家都知道它有很多好处,一个是低价排量、高吞吐、高可用性,但是它同时也有很多缺点,比如很重要的一点就是它没有目录的管理能力,对于文件系统来说,用户访问起来不是很方便,同时它就只有HTTP接口,并且是按照调用次数收费的。
针对对象存储的这种问题,我们引入了元数据服务,通过这方式我们可以在对象存储的基础上提供完备的 POSIX 兼容性。我们对外提供各种各样的接口,包括 POSIX 接口,各种网络存储协议以及各种各样的 SDK,通过这样的一种架构,我们可以将海量低价的云存储作为本地磁盘使用成为了一种可能。
如何在 Kubernetes 中使用 JuiceFS?Kubernetes 是目前最流行的一种应用编排引擎,将资源池化,使得用户不再需要关心底层的基础设施和基础资源,这一点 JuiceFS 的设计理念是相同的。同时 Kubernetes 也提供了一些声明式 API 并且它的可拓展性很强,它提供了一种 CSI 的一种接入方式,让 JuiceFS 可以很方便的接入进来,
在 Kubernetes 中使用 JuiceFS 十分简单,我们提供了两种安装方式,helm chart 安装和 Kubernetes yaml 直接 apply,任意一种方式都可以做到一键安装部署。然后再准备一个元数据引擎和对象存储服务就可以直接通过 Kubernetes 原生方式,在 Pod 里直接使用 Juicefs 类型的存储了。
在 KubeSphere 中使用 JuiceFS 就更简单了。在界面上通过「应用模板」上传 chart 包或者在「应用仓库」中添加 JuiceFS 的官网 chart 仓库地址,就可以直接安装 Juicefs CSI Driver 了,然后在 KubeSphere 中使用和原生的 Kubernetes 使用方式是一样的,后续我们会把 JuiceFS 做为 Kubesphere 的原生插件,在部署 Kubesphere 之后即可直接使用,大家可以期待一下。
CSI 工作原理如果大家平时使用过 CSI 或者接触过它的一些原理的话,我们会知道它其实很复杂,CSI 的官方提供了很多插件,主要有两种方式,一种是 CSI 内部的组件,另一种是外部的,内部的话我们在这里就不介绍了,我们只介绍外部的两类插件,一类是需要我们自己去实现的插件,CSI Controller,CSI Node 和 CSI Identity ,还有一类就是官方提供的一些 SideCar,这些 SideCar 全部都是配合以上三个插件去完成存储的所有功能。
CSI Controller,它是以 deployment 的形式运行在集群里面,主要负责 provision 和 attach 工作。当然 attach 不是每一个存储都会用到的,而 provision 就是在使用 StorageClass 的时候会动态创建 PV 的过程,所以 CSI Controller 在实现 provision 这个功能的时候,是 external-provisioner 这个 SideCar 去配合实现的,在实现 attach 功能的时候是 external-attacher 配合它一起完成的。
CSI Node 和 CSI Identity 通常是部署在一个容器里面的,它们是以 daemonset 的形式运行在集群里面,保证每一个节点会有一个 Pod 部署出来,这两个组件会和 CSI Controller 一起完成 volume 的 mount 操作。CSI Identity 是用来告诉 Controller,我现在是哪一个 CSI 插件,它实现的接口会被 node-driver-registrar 调用给 Controller 去注册自己。CSI Node 会实现一些 publish volume 和 unpublished volume 的接口,Controller 会去调用来完成 volume 的 mount 的操作,我们只需要实现这几个插件的接口就可以了。
Provision 过程上文介绍的 Kubernetes 中的动态存储方案,是管理员只需要创建 StorageClass,然后用户创建 PVC,由 Kubernetes 自动的帮你创建 PV 的这么一个过程,其中具体的流程如上图所示,首先是 PVController 会去向 API Server 监听 PVC 资源的创建,它监听到 PVC 资源的创建会给 PVC 打上一个注解,注解里告诉 Kubernetes 是现在 PVC 使用的是哪一个 CSI 然后同时 external-provisioner 这个 SideCar 也会去监听 PVC 的资源,如果注解信息和自己的 CSI 是一样的话,它就会去调用 CSI controller 的接口去实现创建 volume 的逻辑,这个接口调用成功之后,external-provisioner 就会认为 volume 已经创建好了,然后就会去对应的创建 PV。
Mount 过程