更新时间:2024-01-16 gmt 08:00

pv、pvc和storageclass-凯发k8国际娱乐官网入口

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

如果要求pod重新调度后仍然能使用之前读写过的数据,就只能使用网络存储了,网络存储种类非常多且有不同的使用方法,通常一个云服务提供商至少有块存储、文件存储、对象存储三种。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插件,从而支持特定的存储,达到解耦的目的。例如在中看到的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资源绑定。

图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提供的默认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的名称
分享:
网站地图