云容器引擎 CCE云容器引擎 CCE

计算
弹性云服务器 ECS
裸金属服务器 BMS
弹性伸缩 AS
镜像服务 IMS
专属主机 DeH
函数工作流 FunctionGraph
网络
虚拟私有云 VPC
弹性公网IP EIP
虚拟专用网络 VPN
弹性负载均衡 ELB
NAT网关 NAT
云专线 DC
云解析服务 DNS
VPC终端节点 VPCEP
云连接 CC
企业交换机 ESW
安全与合规
Anti-DDoS 流量清洗
Web应用防火墙 WAF
企业主机安全 HSS
数据加密服务 DEW
数据库安全服务 DBSS
DDoS高防 AAD
数据安全中心 DSC
容器安全服务 CGS
态势感知 SA
威胁检测服务 MTD
安全治理云图 Compass
云证书管理服务 CCM
DDoS防护 ADS
数据库
云数据库 RDS
文档数据库服务 DDS
数据管理服务 DAS
数据复制服务 DRS
云数据库GaussDB NoSQL
云数据库 GaussDB(for MySQL)
分布式数据库中间件 DDM
云数据库 GaussDB(for openGauss)
人工智能
MapReduce服务 MRS
数据仓库服务 GaussDB(DWS)
人脸识别服务 FRS
图引擎服务 GES
数据湖探索 DLI
云搜索服务 CSS
图像识别 Image
内容审核 Moderation
文字识别 OCR
数据湖工厂 DLF
AI开发平台ModelArts
数据接入服务 DIS
图像搜索 ImageSearch
对话机器人服务 CBS
语音交互服务 SIS
华为HiLens
数据可视化 DLV
数据湖治理中心 DGC
自然语言处理 NLP
开发与运维
软件开发平台 DevCloud
项目管理 ProjectMan
代码托管 CodeHub
部署 CloudDeploy
编译构建 CloudBuild
流水线 CloudPipeline
发布 CloudRelease
专属云
专属计算集群 DCC
专属分布式存储服务 DSS
视频
视频直播 Live
媒体处理 MPC
云生态
合作伙伴中心
用户服务
帐号中心
费用中心
成本中心
资源中心
企业管理
工单管理
国际站常见问题
备案中心
支持计划
客户运营能力
合作伙伴支持计划
专业服务
开发者工具
SDK开发指南
API签名指南
Terraform
华为云命令行工具服务 KooCLI
更新时间:2022-02-22 GMT+08:00

PV、PVC和StorageClass

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

执行如下命令即可查询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

使用StorageClassName创建PVC。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  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的名称

文档是否有解决您的问题?

提交成功!

非常感谢您的反馈,我们会继续努力做到更好!

反馈提交失败,请稍后再试!

在文档使用中是否遇到以下问题







请至少选择或填写一项反馈信息

字符长度不能超过200

反馈内容不能为空!

提交反馈 取消