容器存储接口(Container Storage Interface),简称 CSI,CSI试图建立一个行业标准接口的规范,借助CSI容器编排系统(CO)可以将任意存储系统暴露给自己的容器工作负载。
存储可分为临时存储、半持久存储、持久化存储。常见的临时存储主要是emptyDir卷,enptyDir最初是空的,当pod从节点上删除后,emptyDir卷中的数据也会被永久删除,如果pod因为某些原因重启,enptyDir卷内的数据不会丢失。emptyDir卷存储在支持该节点所使用的存储介质上,可以是本地磁盘或者网络存储。emptyDir的空间位于系统根盘,被所有容器共享,所以在磁盘的使用率较高时会触发Pod的eviction操作,故需要根据实际需要来使用emptyDir,一般情况下emptyDir存储中间数据,用于快速恢复。
半持久化存储主要是hostPath卷,hostPath卷将主机节点上文件系统上的文件或者目录挂载到指定pod中,对于需要获取节点系统信息的pod,需要挂载hostPath,例如Calico插件,需要将配置文件等存放到节点的目录上。在使用hostPath卷时需要注意的三个点
1.使用同一个目录的pod由于调度到不同的节点,导致目录中内容不同
2.Kubernetes在调度时无法顾及由hostPath使用的资源
3.pod被删除后,hostPath上的数据会遗留在节点上,会占用磁盘空间
支持持久化存储是所有分布式系统必备的特性,针对持久化存储,Kubernetest引入了StorageClass,Volume,PVC,PV的概念。Kubernetes支持的持久化存储包括主流的块存储和文件存储,在大类上又可以分成网络存储和本地存储两类。
StorageClass:用于指示存储的类型,不同的存储类型可以通过不同的StorageClass来为用户提供服务,StorageClass中主要包含存储插件、provisioner、卷创建和mount参数字段。以下就是定义一个StorageClass的yaml文件例子,每个 StorageClass 都有一个制备器(Provisioner),用来决定使用哪个卷插件制备 PV。
下图是一些常用的Provisioner,更多Provisioner的信息可以查看这里。
通过上面的信息描述,可以知道StorageClass对象本质上是创建PV的模板,StorageClass的定义涉及两部分:
第一:PV的属性。比如,存储类型、Volume的大小等。
第二:创建这种PV需要用到的存储插件,如Ceph等。
有了这两个信息之后,Kubernetes就能够根据用户提交的PVC,找到一个对应的StorageClass了。然后Kubernetes就会调用该StorageClass声明的存储插件创建出需要的PV,且把StorageClass相同的PVC和PV进行绑定。这种更具StorageClass自动创建PV且完成绑定的机制叫Dynamic Provisioning机制