一、PV PVC StorageClass介绍

1.1 什么是PV
PV全称叫做Persistent Volume,持久化存储卷。它是用来描述或者说用来定义一个存储卷的。PV一般由运维来创建。 PV有2个重要的参数accessModes和persistentVolumeReclaimPolicy。

  • accessModes:支持三种类型ReadWriteMany多路读写,卷能被集群多个节点挂载并读写ReadWriteOnce单路读写,卷只能被单一集群节点挂载读写ReadOnlyMany多路只读,卷能被多个集群节点挂载且只能读

  • persistentVolumeReclaimPolicy:也有三种策略,这个策略是当与之关联的PVC被删除以后,这个PV中的数据如何被处理
    Retain 当删除与之绑定的PVC时候,这个PV被标记为released(PVC与PV解绑但还没有执行回收策略)且之前的数据依然保存在该PV上,但是该PV不可用,需要手动来处理这些数据并删除该PV。
    Delete 当删除与之绑定的PVC时候

1.2 什么是PVC
PVC是用来描述希望使用什么样的或者说是满足什么条件的存储,它的全称是Persistent Volume Claim,也就是持久化存储声明。开发人员使用这个来描述该容器需要一个什么存储。比如下面使用NFS的PVC:PV是已有存储,PVC是需要的存储,
两者要形成配对需要下面2个条件:

  • PV和PVC中的spec关键字段要匹配,比如存储(storage)大小。
  • PV和PVC中的storageClassName字段必须一致。

1.3 什么是storageclass
PV是运维人员来创建的,用户操作PVC,可是大规模集群中可能会有很多PV,如果这些PV都需要运维手动来处理这也是一件很繁琐的事情,所以就有了动态供给(Dynamic Provisioning)概念。而手动创建的PV都是静态供给方式(Static Provisioning)是。而动态供给的关键就是StorageClass,它的作用就是创建PV模板。
创建StorageClass里面需要定义PV属性比如存储类型、大小等;另外创建这种PV需要用到存储插件。最终效果是,用户提交PVC,里面指定存储类型,如果符合我们定义的StorageClass,则会为其自动创建PV并进行绑定。

二、CSI介绍

2.1 什么是CSI
CSI ,Container Storage Interface,CSI是将任意块和文件存储系统公开给Kubernetes等容器编排系统(COs)上的容器化工作负载的标准。 使用CSI第三方存储提供商可以编写和部署插件,在Kubernetes中公开新的存储系统,而无需接触Kubernetes的核心代码。
K8S的V1.13版本已经支持了GA版本的CSI组件。

2.2 CSI驱动PVC
在pod创建过程中,通过指定创建外部卷存储,PVC通过storageclass的动态供给生成对应绑定的PV,PV的创建与绑定由CSI来进行。这时候CSI就可以自己定义如何加载一个卷,如何挂载一个卷。

在这里插入图片描述

2.3 in-tree 与 out-tree
Volume的插件分为in-tree和out-tree两种。
in-tree是与核心k8s二进制文件一起链接、编译、构建和发布的。它的开发紧密耦合并依赖于K8S的版本。in-tree的volume插件中的bug会导致关键的k8s组件崩溃,而不仅仅是插件本身 。
out-tree的volume插件不侵入K8S的核心源码,更加灵活。存储供应商可以自己定制适配于自己产品volume插件。CSI就是属于out-tree的volume插件。

2.4 需要的服务

在这里插入图片描述

和kube-apiserver直接进行交互的是K8S官方直接提供的一些sidecar容器,这些sidecar直接部署即可。这些sidecar容器(主要是上图的三个主要部件)监听自己对应的CRD,触发对应的操作,通过UDS接口直接调用CSI driver的接口(例如CreateVolume() 、NodePublishVolme()等)来实现对卷的操作。

要开发CSI Drivers一般来说实现以下几个服务:
CSI Identity service
允许调用者(Kubernetes组件和CSI sidecar容器)识别驱动程序及其支持的可选功能。
CSI Node service
NodePublishVolume, NodeUnpublishVolume 和 NodeGetCapabilities 是必须的。
所需的方法使调用者能够使卷在指定的路径上可用,并发现驱动程序支持哪些可选功能。
CSI Controller Service
实现CreateVolume、DeleteVolume接口

三、CSI sidecar容器介绍

3.1 external-provisioner(CSI-provisioner)
在启动时通过–provisioner指定自身provisioner名称,与StorageClass中的provisioner字段对应。
(1)watch PVC对象,判断PVC是否需要动态创建存储卷
若需要调用CSI Plugin的CreateVolume接口,同时创建名为 P r o v i s i o n e r 指 定 的 P V 前 缀 − {Provisioner指定的PV前缀}- ProvisionerPV{PVC uuid}的PV
(2)watch PV对象,判断其是否需要删除,
若需要,则调用CSI Plugin的DeleteVolume接口,同时删除PV对象
3.2 external-attacher(CSI-attacher)
(1)watch VolumeAttachment对象,获得PV的所有信息
(2)在attacher时为相关PV打上Finalizer;当PV处于删除状态(DeletionTimestamp非空)时,删除Finalizer

3.3 其他sidecar容器
external-resizer:watchPVC, 参与实现卷扩容
external-snapshotter:watch VolumeSnapshot,参与实现卷快照
node-driver-registrar:调用CSI Plugin的接口获取插件信息,通过Kubelet的插件注册机制将CSI Plugin注册到kubelet
livenessprobe:调用CSI Plugin的Probe接口,同时在/healthz暴露HTTP健康检查探针

四、Ceph-CSI预研与使用

4.1 为什么需要预研ceph-csi
通过CSI可以自定义第三方存储组件的行为,例如,Ceph就推出了基于K8S的CSI组件,对于Ceph RBD以及cephfs,其实K8S自身已经提供了支持ceph的in-tree插件了。但是对于天炉的业务来讲,RBD的大小需要达到5T的大小,直接通过K8S去实现的格式化操作需要耗费大量的时间。 并且对于IO速度需要自定义ceph client的参数来达到优化效果,如果介入in-tree plugin的开发风险太大,而基于官方的CSI 插件进行修改则是更合适的手段。

4.2 Ceph-CSI 创建卷的流程图解

在这里插入图片描述

4.3 部署Ceph-CSI
Ceph-CSI是开源的,官网:https://github.com/ceph/ceph-csi。
部署Ceph CSI,要注意版本要匹配,对于ceph集群基本都要求要N版以上,目前天炉环境部署的ceph集群版本是L版,暂时无法达到版本的适配。
具体部署流程可以参考:https://zhuanlan.zhihu.com/p/267347779。
在部署过程对于K8S官方的sidecar镜像(k8s.gcr.io无法访问)无法下载,可以替换为阿里云,手动修改csi-rbdplugin-provisioner.yaml 和 csi-rbdplugin.yaml修改镜像地址。

# 例如
k8s.gcr.io/csi-provisioner:v3.0.0
# 可以代理为:
registry.cn-hangzhou.aliyuncs.com/google_containers/csi-provisioner:v3.0.0

四、参考资料

  1. Kubenetes CSI 官方参考文档

https://kubernetes-csi.github.io/docs/#kubernetes-container-storage-interface-csi-documentation

  1. kubernetes/k8s CSI分析-容器存储接口分析
    https://www.cnblogs.com/lianngkyle/p/15055552.html

  2. PV、PVC、StorageClass讲解
    https://www.cnblogs.com/rexcheny/p/10925464.html

4.Kubernetes使用ceph-csi消费RBD作为持久化存储
https://zhuanlan.zhihu.com/p/267347779

5.K8S容器存储接口(CSI)介绍
https://www.cnblogs.com/yangyuliufeng/p/14360558.html

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐