pv、pvc和storageclass-九游平台
上一章节介绍的hostpath是一种持久化存储,但是hostpath的内容是存储在节点上,导致只适合读取。
如果要求pod重新调度后仍然能使用之前读写过的数据,就只能使用网络存储了,网络存储种类非常多且有不同的使用方法,通常一个云服务提供商至少有块存储、文件存储、对象存储三种。kubernetes解决这个问题的方式是抽象了pv(persistentvolume)和pvc(persistentvolumeclaim)来解耦这个问题,从而让使用者不用关心具体的基础设施,当需要存储资源的时候,只要像cpu和内存一样,声明要多少即可。
- pv:pv描述的是持久化存储卷,主要定义的是一个持久化存储在宿主机上的目录,比如一个nfs的挂载目录。
- pvc:pvc描述的是pod所希望使用的持久化存储的属性,比如,volume存储的大小、可读写权限等等。
kubernetes管理员设置好网络存储的类型,提供对应的pv描述符配置到kubernetes,使用者需要存储的时候只需要创建pvc,然后在pod中使用volume关联pvc,即可让pod使用到存储资源,它们之间的关系如下图所示。
csi
kubernetes提供了csi接口(container storage interface,容器存储接口),基于csi这套接口,可以开发定制出csi插件,从而支持特定的存储,达到解耦的目的。例如在中看到的kube-system命名空间下everest-csi-controller和everest-csi-driver就是cce开发存储控制器和驱动。有了这些驱动就可以使用evs、sfs、obs存储。
$ kubectl get po --namespace=kube-system name ready status restarts age everest-csi-controller-6d796fb9c5-v22df 2/2 running 0 9m11s everest-csi-driver-snzrr 1/1 running 0 12m everest-csi-driver-ttj28 1/1 running 0 12m everest-csi-driver-wtrk6 1/1 running 0 12m
pv
来看一下pv是如何描述持久化存储,例如在sfs中创建了一个文件存储,这个文件存储id为68e4a4fd-d759-444b-8265-20dc66c8c502,挂载地址为sfs-nas01.cn-north-4b.myhuaweicloud.com:/share-96314776。如果想在cce中使用这个文件存储,则需要先创建一个pv来描述这个存储,如下所示。
apiversion: v1 kind: persistentvolume metadata: name: pv-example spec: accessmodes: - readwritemany # 读写模式 capacity: storage: 10gi # 定义pv的大小 csi: driver: nas.csi.everest.io # 声明使用的驱动 fstype: nfs # 存储类型 volumeattributes: everest.io/share-export-location: sfs-nas01.cn-north-4b.myhuaweicloud.com:/share-96314776 # 挂载地址 volumehandle: 68e4a4fd-d759-444b-8265-20dc66c8c502 # 存储id
这里csi下面的内容就是cce中特定的字段,在其他地方无法使用。
下面创建这个pv并查看。
$ kubectl create -f pv.yaml persistentvolume/pv-example created $ kubectl get pv name capacity access modes reclaim policy status claim storageclass reason age pv-example 10gi rwx retain available 4s
reclaim policy是指pv的回收策略,retain表示pvc被释放后pv继续保留。status值为available,表示pv处于可用的状态。
pvc
pvc可以绑定一个pv,示例如下。
apiversion: v1 kind: persistentvolumeclaim metadata: name: pvc-example spec: accessmodes: - readwritemany resources: requests: storage: 10gi # 声明存储的大小 volumename: pv-example # pv的名称
创建pvc并查看。
$ kubectl create -f pvc.yaml persistentvolumeclaim/pvc-example created $ kubectl get pvc name status volume capacity access modes storageclass age pvc-example bound pv-example 10gi rwx 9s
这里可以看到状态是bound,volume是pv-example,表示pvc已经绑定了pv。
再来看下pv。
$ kubectl get pv name capacity access modes reclaim policy status claim storageclass reason age pv-example 10gi rwx retain bound default/pvc-example 50s
可以看到状态也变成了bound,claim是default/pvc-example,表示这个pv绑定了default命名空间下的pvc-example这个pvc。
这里一个比较有意思的地方是claim是default/pvc-example,为什么要显示default呢,这是因为pv是集群级别的资源,并不属于某个命名空间,而pvc是命名空间级别的资源,pv可以与任何命名空间的pvc资源绑定。
storageclass
上节说的pv和pvc方法虽然能实现屏蔽底层存储,但是pv创建比较复杂(可以看到pv中csi字段的配置很麻烦),通常都是由集群管理员管理,这非常不方便。
kubernetes解决这个问题的方法是提供动态配置pv的方法,可以自动创pv。管理员可以部署pv配置器(provisioner),然后定义对应的storageclass,这样开发者在创建pvc的时候就可以选择需要创建存储的类型,pvc会把storageclass传递给pv provisioner,由provisioner自动创建pv。如cce就提供csi-disk、csi-nas、csi-obs等storageclass,在声明pvc时加上storageclassname,就可以自动创建pv,并自动创建底层的存储资源。
执行如下命令即可查询cce提供的默认storageclass。您可以使用cce提供的csi插件自定义创建storageclass,但从功能角度与cce提供的默认storageclass并无区别,这里不做过多描述。
# kubectl get sc name provisioner age csi-disk everest-csi-provisioner 17d # 云硬盘 storageclass csi-disk-topology everest-csi-provisioner 17d # 延迟绑定的云硬盘 storageclass csi-nas everest-csi-provisioner 17d # 文件存储 storageclass csi-obs everest-csi-provisioner 17d # 对象存储 storageclass csi-sfsturbo everest-csi-provisioner 17d # 极速文件存储 storageclass
使用storageclass创建pvc。
apiversion: v1 kind: persistentvolumeclaim metadata: name: pvc-sfs-auto-example spec: accessmodes: - readwritemany resources: requests: storage: 10gi storageclassname: csi-nas # storageclass
当前不支持使用csi-sfsturbo类型storageclass直接创建pvc。如需使用sfs turbo类型的存储,请提前创建sfs turbo实例并通过静态存储卷的方式创建pv和pvc,详情请参见。
创建pvc并查看pvc和pv。
$ kubectl create -f pvc2.yaml persistentvolumeclaim/pvc-sfs-auto-example created $ kubectl get pvc name status volume capacity access modes storageclass age pvc-sfs-auto-example bound pvc-1f1c1812-f85f-41a6-a3b4-785d21063ff3 10gi rwx csi-nas 29s $ kubectl get pv name capacity access modes reclaim policy status claim storageclass reason age pvc-1f1c1812-f85f-41a6-a3b4-785d21063ff3 10gi rwo delete bound default/pvc-sfs-auto-example csi-nas 20s
这可以看到使用storageclass后,不仅创建了pvc,而且创建了pv,并且将二者绑定了。
定义了storageclass后,就可以减少创建并维护pv的工作,pv变成了自动创建,作为使用者,只需要在声明pvc时指定storageclassname即可,这就大大减少工作量。
再次说明,storageclassname的类型在不同厂商的产品上各不相同,这里只是使用了文件存储作为示例。
在pod中使用pvc
有了pvc后,在pod中使用持久化存储就非常方便了,在pod template中的volume直接关联pvc的名称,然后挂载到容器之中即可,如下所示。甚至在statefulset中还可以直接声明pvc,详情请参见。
apiversion: apps/v1 kind: deployment metadata: name: nginx-deployment spec: selector: matchlabels: app: nginx replicas: 2 template: metadata: labels: app: nginx spec: containers: - image: nginx:alpine name: container-0 volumemounts: - mountpath: /tmp # 挂载路径 name: pvc-sfs-example restartpolicy: always volumes: - name: pvc-sfs-example persistentvolumeclaim: claimname: pvc-example # pvc的名称
相关文档
意见反馈
文档内容是否对您有帮助?
如您有其它疑问,您也可以通过华为云社区问答频道来与我们联系探讨