PV、PVC和StorageClass

yixiaoer 发表于 2020/11/02 19:43:45 2020/11/02
【摘要】 上一章节介绍的HostPath是一种持久化存储,但是HostPath的内容是存储在节点上,导致只适合读取。如果要求Pod重新调度后仍然能使用之前读写过的数据,就只能使用网络存储了,网络存储种类非常多且有不同的使用方法,通常一个云服务提供商至少有块存储、文件存储、对象存储三种,如华为云的EVS、SFS和OBS。Kubernetes解决这个问题的方式是抽象了PV(PersistentVolume...

上一章节介绍的HostPath是一种持久化存储,但是HostPath的内容是存储在节点上,导致只适合读取。

如果要求Pod重新调度后仍然能使用之前读写过的数据,就只能使用网络存储了,网络存储种类非常多且有不同的使用方法,通常一个云服务提供商至少有块存储、文件存储、对象存储三种,如华为云的EVS、SFS和OBS。Kubernetes解决这个问题的方式是抽象了PV(PersistentVolume)和PVC(PersistentVolumeClaim)来解耦这个问题,从而让使用者不用关心具体的基础设施,当需要存储资源的时候,只要像CPU和内存一样,声明要多少即可。

  • PV:PV描述的是持久化存储卷,主要定义的是一个持久化存储在宿主机上的目录,比如一个NFS的挂载目录。

  • PVC:PVC描述的是Pod所希望使用的持久化存储的属性,比如,Volume存储的大小、可读写权限等等。

Kubernetes管理员设置好网络存储的类型,提供对应的PV描述符配置到Kubernetes,使用者需要存储的时候只需要创建PVC,然后在Pod中使用Volume关联PVC,即可让Pod使用到存储资源,它们之间的关系如下图所示。

图1 PVC绑定PV

CSI

Kubernetes提供了CSI接口(Container Storage Interface,容器存储接口),基于CSI这套接口,可以开发定制出CSI插件,从而支持特定的存储,达到解耦的目的。例如在Namespace:资源分组中看到的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: PersistentVolumemetadata:
  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: PersistentVolumeClaimmetadata:
  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资源绑定。

图2 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 1.15及以上版本集群使用方法举例,1.13以及之前版本集群上使用方法有差异,具体请参见使用kubectl创建文件存储

apiVersion: v1
kind: PersistentVolumeClaimmetadata:
  name:  pvc-sfs-auto-example
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 10Gi  storageClassName: csi-nas        # StorageClass

创建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,详情请参见StatefulSet

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的名称


了解更多Kubernetes集群相关知识和使用方法请猛击这里

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区),文章链接,文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:cloudbbs@huaweicloud.com进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。