更新时间:2025-08-19 GMT+08:00

存储基础知识

Volume(卷)

容器中的文件在磁盘上是临时存放的,这给容器中运行的较重要的应用程序带来如下两个问题:

  1. 当容器重建时,容器中的文件将会丢失。
  2. 当在一个Pod中同时运行多个容器时,容器间需要共享文件。

Kubernetes抽象出了Volume(卷)来解决以上两个问题。Kubernetes的Volume是Pod的一部分,Volume不是单独的对象,不能独立创建,只能在Pod中定义。Pod中的所有容器都可以使用Volume,但需要将Volume挂载到容器中的目录下。

实际中使用容器存储如下图所示,可将同一个Volume挂载到不同的容器中,实现不同容器间的存储共享。

存储卷的基本使用原则如下:

  • 一个Pod可以挂载多个Volume。虽然单Pod可以挂载多个Volume,但是并不建议给一个Pod挂载过多卷。
  • 一个Pod可以挂载多种类型的Volume。
  • 每个被Pod挂载的Volume卷,可以在不同的容器间共享。
  • Kubernetes环境推荐使用PVC和PV方式挂载Volume。

卷(Volume)的生命周期与挂载它的Pod相同,即Pod被删除的时候,Volume也一起被删除。但是Volume里面的文件可能在Volume消失后仍然存在,这取决于Volume的类型。

Kubernetes提供了非常丰富的Volume类型,主要可分为In-Tree和Out-of-Tree两个大类:

卷(Volume)分类

描述

In-Tree

In-Tree卷是通过Kubernetes代码仓库维护的,与Kubernetes二进制文件一起构建、编译、发布,当前Kubernetes已不再接受这种模式的卷类型。

例如HostPath、EmptyDir、Secret和ConfigMap等Kubernetes原生支持的卷都属于这个类型。

而PVC(PersistentVolumeClaim)可以说是一种特殊的In-Tree卷,Kubernetes使用这种类型的卷从In-Tree模式向Out-of-Tree模式进行转换,这种类型的卷允许使用者在不同的存储供应商环境中“申请”使用底层存储创建的PV(PersistentVolume)。

Out-of-Tree

Out-of-Tree卷包括容器存储接口(CSI)和FlexVolume(已弃用),存储供应商只需遵循一定的规范即可创建自定义存储插件,创建可供Kubernetes使用的PV,而无需将插件源码添加到Kubernetes代码仓库。例如SFS、OBS等云存储都是通过在集群中安装存储驱动的形式使用的,需要在集群中创建对应的PV,然后使用PVC挂载到Pod中。

PV与PVC

Kubernetes抽象了PV(PersistentVolume)和PVC(PersistentVolumeClaim)来定义和使用存储,从而让使用者不用关心具体的基础设施,当需要存储资源的时候,只要像CPU和内存一样,声明要多少即可。

  • PV:PV是PersistentVolume的缩写,译为持久化存储卷,描述的是一个集群里的持久化存储卷,它和节点一样,属于集群级别资源,其对象作用范围是整个Kubernetes集群。PV可以有自己的独立生命周期,不依附于Pod。
  • PVC:PVC是PersistentVolumeClaim的缩写,译为持久化存储卷声明,描述的是负载对存储的申领。为应用配置存储时,需要声明一个存储需求(即PVC),Kubernetes会通过最佳匹配的方式选择一个满足需求的PV,并与PVC绑定。PVC与PV是一一对应关系,在创建PVC时,需描述请求的持久化存储的属性,比如,存储的大小、可读写权限等等。

在Pod中可以使用Volume关联PVC,即可让Pod使用到存储资源,它们之间的关系如下图所示。

图1 PVC绑定PV

CSI

CSI(Container Storage Interface,容器存储接口)是容器标准存储接口规范,也是Kubernetes社区推荐的存储插件实现方案。CCE容器存储(Everest)是CCE基于CSI开发的存储插件,能够为容器提供不同类型的持久化存储功能。

存储卷访问模式

存储卷只能以底层存储资源所支持的方式挂载到宿主系统上。例如,文件存储可以支持多个节点读写,云硬盘只能被一个节点读写。

  • ReadWriteOnce:存储卷可以被一个节点以读写方式挂载。
  • ReadWriteMany:存储卷可以被多个节点以读写方式挂载。
表1 存储卷支持的访问模式

存储类型

ReadWriteOnce

ReadWriteMany

云硬盘EVS

×

文件存储SFS

×

对象存储OBS

×

极速文件存储SFS Turbo

×

本地持久卷LocalPV

×

专属存储DSS

×

存储卷挂载方式

通常在使用存储卷时,可以通过以下方式挂载:

可以使用PV描述已有的存储资源,然后通过创建PVC在Pod中使用存储资源。也可以使用动态创建的方式,在PVC中指定存储类(StorageClass),利用StorageClass中的Provisioner自动创建PV来绑定PVC。

表2 挂载存储卷的方式

挂载方式

说明

支持的存储卷类型

其他限制

静态创建存储卷(使用已有存储)

指基于已有的存储资源(例如云硬盘、文件存储等),手动创建PV和PVC。Kubernetes会根据PVC的资源需求,自动将其与匹配的PV绑定。绑定完成后,PVC可挂载至工作负载,使工作负载获得访问存储资源的能力,进而实现业务数据的持久化存储。

若存储卷的访问模式为ReadWriteOnce,则创建工作负载时,工作负载的Pod实例数量只能设置为1

所有存储卷均支持

动态创建存储卷(自动创建存储)

指在PVC中指定存储类(StorageClass),由存储Provisioner根据PVC中声明的资源需求动态创建底层存储资源和对应的PV,并自动完成该PV与PVC的绑定,从而实现存储资源的自动化供给。

若存储卷的访问模式为ReadWriteOnce,则创建工作负载时,工作负载的Pod实例数量只能设置为1

云硬盘存储、对象存储、文件存储、本地持久卷、专属存储

动态挂载(VolumeClaimTemplate

动态挂载能力通过卷申领模板(volumeClaimTemplates字段)实现,并依赖于StorageClass的动态创建PV能力。动态挂载可以为每一个Pod关联一个独有的PVC及PV,当Pod被重新调度后,仍然能够根据该PVC名称挂载原有的数据。

即使存储卷的访问模式为ReadWriteOnce,工作负载的Pod实例数量也可以设置为多个。

仅云硬盘存储、本地持久卷、专属存储支持

仅有状态工作负载支持

PV回收策略

PV回收策略用于指定删除PVC时,底层卷的回收策略,支持设定Delete、Retain回收策略。

  • Delete:删除PVC的动作会将PV对象从Kubernetes中移除,同时也会从外部基础设施中移除所关联的底层存储资产。

    包周期云硬盘资源支持通过Delete回收策略进行级联删除,而其他类型的包周期资源则无法通过Delete回收策略实现级联删除。

  • Retain:当PVC对象被删除时,PV对象与底层存储资源均不会被删除,需要手动删除回收。PVC删除后PV资源状态为“已释放(Released)”,且不能直接再次被PVC绑定使用。

    您可以通过以下步骤来手动删除回收:

    1. 手动删除PersistentVolume对象。
    2. 根据情况,手动清除所关联的底层存储资源上的数据。
    3. 手动删除所关联的底层存储资源。

    如果您希望重用该底层存储资源,可以重新创建新的PersistentVolume对象。

CCE还支持一种删除PVC时不删除底层存储资源的使用方法,当前仅支持使用YAML创建:PV回收策略设置为Delete,并添加annotations“everest.io/reclaim-policy: retain-volume-only”。这样在删除PVC时,PV会被删除,但底层存储资源会保留。

以云硬盘为例,YAML示例如下:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test
  namespace: default
  annotations:
    volume.beta.kubernetes.io/storage-provisioner: everest-csi-provisioner
    everest.io/disk-volume-type: SAS
  labels:
    failure-domain.beta.kubernetes.io/region: <your_region>   # 替换为您待部署应用的节点所在的区域
    failure-domain.beta.kubernetes.io/zone: <your_zone>       # 替换为您待部署应用的节点所在的可用区
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: csi-disk
  volumeName: pv-evs-test

---
apiVersion: v1
kind: PersistentVolume
metadata:
  annotations:
    pv.kubernetes.io/provisioned-by: everest-csi-provisioner
    everest.io/reclaim-policy: retain-volume-only
  name: pv-evs-test
  labels:
    failure-domain.beta.kubernetes.io/region: <your_region>   # 替换为您待部署应用的节点所在的区域
    failure-domain.beta.kubernetes.io/zone: <your_zone>       # 替换为您待部署应用的节点所在的可用区
spec:
  accessModes:
    - ReadWriteOnce
  capacity:
    storage: 10Gi
  csi:
    driver: disk.csi.everest.io
    fsType: ext4
    volumeHandle: 2af98016-6082-4ad6-bedc-1a9c673aef20
    volumeAttributes:
      storage.kubernetes.io/csiProvisionerIdentity: everest-csi-provisioner
      everest.io/disk-mode: SCSI
      everest.io/disk-volume-type: SAS
  persistentVolumeReclaimPolicy: Delete
  storageClassName: csi-disk

存储类(StorageClass)

StorageClass是Kubernetes中用于定义存储类别的资源对象,提供动态分配存储卷的能力。通过设置不同的参数,StorageClass能够根据业务需求自动供应和调整存储资源。在PVC中指定StorageClassName字段后,若在集群中未找到匹配的PV,Kubernetes将根据所引用的StorageClass调用对应的Provisioner动态创建符合要求的PV及底层存储资源,从而简化了手动创建和维护PV的流程。StorageClass中的参数作为默认配置项使用,当PVC中存在与之冲突的配置时,以PVC中的设置为准

CCE集群中默认提供以下StorageClass供您使用,默认StorageClass不支持修改。如果默认的StorageClass无法满足业务需求,您可以自定义创建新的StorageClass,设置回收策略、绑定模式等参数,具体请参见自定义存储类(StorageClass)

表3 默认StorageClass

StorageClass名称

对应存储类型

Provisioner

回收策略

绑定模式

是否支持扩容

csi-disk

云硬盘

everest-csi-provisioner

Delete

Immediate

支持

csi-disk-topology

延迟创建的云硬盘

everest-csi-provisioner

Delete

WaitForFirstConsumer

支持

csi-nas

SFS容量型文件存储

everest-csi-provisioner

Delete

Immediate

支持

csi-sfs

通用文件系统(原SFS 3.0 容量型)

everest-csi-provisioner

Delete

Immediate

不支持

csi-sfsturbo

极速文件存储

everest-csi-provisioner

Delete

Immediate

支持

csi-obs

对象存储

everest-csi-provisioner

Delete

Immediate

不支持

csi-disk-dss

专属存储

everest-csi-provisioner

Delete

Immediate

支持

csi-local

本地持久卷

everest-csi-provisioner

Delete

Immediate

不支持

csi-local-topology

延时创建的本地持久卷

everest-csi-provisioner

Delete

WaitForFirstConsumer

支持

表3 默认存储类中参数介绍如下:

  • 对应存储类型:表示该存储类创建的底层存储类型。
  • Provisioner:表示存储资源提供商。
  • 回收策略:用于指定删除PVC时底层存储的回收策略,详情请参见PV回收策略
  • 绑定模式:表示卷绑定模式,即动态创建PV的时间,分为立即创建(Immediate)和延迟创建(WaitForFirstConsumer)。
    • Immediate:PVC创建后,会立即创建底层存储资源及存储卷PV,并与PVC绑定。
    • WaitForFirstConsumer:PVC创建后,不会立即与存储卷PV绑定,而是等需要挂载该PVC的Pod被调度后,再创建底层存储资源及存储卷PV,并与PVC绑定。
  • 是否支持扩容:表示由该存储类创建的PV是否支持动态扩容。

如果需要了解默认StorageClass的更多信息,请通过kubectl连接集群,并执行kubectl describe sc <storageclass-name>命令查询详细信息。

相关文档

  • 更多关于Kubernetes存储的信息,请参见Storage
  • 更多关于CCE容器存储的信息,请参见存储概述