文章根据 Juicedata 工程师朱唯唯,在云原生 Meetup 杭州站所作主题演讲《JuiceFS CSI Driver 的最佳实践》整理而成。
大家好,我是来自 Juicedata 的朱唯唯,现在主要负责 JuiceFS CSI Driver 方面的开发,很高兴今天有这个机会跟大家做一个分享和交流,我今天分享的题目是 “JuiceFS CSI Driver 的最佳实践”。主要会从以下几个方面给大家做一个分享:
Kubernetes 存储方案
如何在 Kubernetes 中使用 JuiceFS
JuiceFS CSI Driver 架构设计实践
Kubernetes 存储方案在 Kubernetes 里面对存储有三个概念,第一个是 PV,也就是持久卷,代表的是集群中的一份存储,可以定义存储的类型、大小等,比如指定它是哪一种类型, NFS 或 GlusterFS ,也可以指定它是 CSI 的。第二个概念是 PVC,持久卷申明,代表的是 Pod 使用存储的一份请求,Pod 不直接使用 PV 而是通过 PVC 来使用 PV。另一个是 StorageClass,持久卷类型,代表的是集群中的存储类型,它不定义存储的大小,只定义类型,在使用的时候 Kubernetes 会根据 StorageClass 自动创建 PV。以上就是 Kubernetes 对 Pod 使用存储所定义的三种资源。
apiVersion: v1 aversion: v1 apiVersion: v1 kind: PersistentVolume kind: PersistentVolumeClaim kind: Pod metadata: metadata: metadata: name: pv0001 name: myclaim name: pv-recycler labels: spec: spec: pv: pv0001 accessModes containers: spec: - ReadWriteMany - name: pv-recycler capacity: volumeMode: Filesystem image: "nginx" storage: 5Gi resources volumeMounts: volumeMode: Filesystem requests: - name: my-volume accessModes: storage: 5Gi mountPath: /root/data - ReadWriteMany selector: volumes: hostPath: matchLabels: - name: my-volume path: /root/data/test pv: pv0001 persistentVolumeClaim: claimName: myclaim我们再来看一下在 Kubernetes 中 Pod 怎样使用存储,主要有两种方式,第一种是静态存储,就是 PV 加 PVC 的方式,可以看上图的几个 yaml 文件,第一个就是 PV 的 yaml 文件。一般由系统管理员先在集群中创建一份 PV,然后在使用的时候创建一个 PVC ,指定使用哪个 PV,但是一个 PV 只能被一个 Pod 使用,每当有新的 Pod 需要使用存储时,系统管理员也要创建相应的 PV,并在 PV 里面是指定它有多大的存储量,用什么样的访问方式以及它是什么类型的,文中给出来的例子就是 hostPath,当然也可以在这里指定它为 Kubernetes 内置的一些存储类型,比如 NFS 、CSI,如果是 CSI 的话,那就需要我们第三方去实现关于 CSI 的一个插件。
PV 定义好了之后,在集群里面就代表有这么一份存储可以用,当 Pod 在使用该 PV 的时候,需要用户提前先去建立一个 PVC 的资源,然后在 PVC 中去指定用什么样的方式去访问存储,以及需要用多大的容量,当然这个容量不能超过 PV 中指定的已有容量。也可以用 label select 的方式去指定这个 PVC 使用哪个 PV ,以上就完成了一个 PVC 资源的创建。
当 PVC 创建好了之后 Pod 就可以直接使用了,使用的方式就是当挂载在 volume 的时候指定一下 Claim 是哪一个 PVC 就可以了。这是静态存储的方案,但是这种方案有一个问题,一个 PV 只能被一个 PVC 使用,当 Pod 被运行起来在使用 PV 的时候, PV 的状态也就会被 Kubernetes 改成 Bound 状态,它一旦是 Bound 状态,另一个 Pod 的 PVC 就不能使用了。那也就意味着每当有新的 Pod 需要使用存储时,系统管理员也要创建相应的 PV,可想而知系统管理员的工作量会很大。
apiVersion: storage.k8s.io/v1 aversion: v1 apiVersion: v1 kind: StorageClass kind: PersistentVolumeClaim kind: Pod metadata: metadata: metadata: name: example-nfs name: myclaim name: pv-recycler provisioner: example.com/external-nfs spec: spec: parameters: accessModes: containers: server: nfs-server.example.com - ReadWriteMany - name: pv-recycler path: /share volumeMode: Filesystem image: "nginx" readOnly: false resources: volumeMounts: requests: - name: my-volume storage: 5Gi mountPath: /root/data storageClassName: example-nfs volumes: - name: my-volume persistentVolumeClaim: claimName: myclaim另一种方式是动态存储,动态存储的方式就是 StorageClass + PVC 使用方式也类似,就是系统管理员先在集群中创建一份 StorageClass,只需指定存储类型,以及它的一些访问参数。在 Pod 在使用的时候依然是创建一个 PVC 指定它需要使用多大容量以及它的访问方式,再指定 StorageClass ,然后 Pod 里面使用和上文是一样的。但在该方案中当 Kubernetes 在创建 Pod 之前会根据 StorageClass 中指定的类型和 PVC 中指定的容量大小等参数,自动创建出对应的 PV,这种方式相比之下解放了系统管理员。
无论是 PV 还是 StorageClass,在指定存储类型的时候,可以使用 Kubernetes 内置的存储类型,比如 hostPath、NFS 等,还有一种方式就是 CSI,第三方云厂商通过实现 CSI 接口来为 Pod 提供存储服务。JuiceFS 也实现了自己的 CSI Driver。
什么是 JuiceFS