全部产品
Search
文档中心

容器服务 Kubernetes 版 ACK:存储基础知识

更新时间:May 08, 2025

本文为您介绍Kubernetes容器存储相关的基础知识,方便您全面地认识和运用容器服务的存储功能。

Volume

容器中的文件在磁盘上是临时存放的,当容器重建时,容器中的文件将会丢失,所以Kubernetes定义了存储卷Volume以解决容器中的文件因容器重启而丢失的问题。Volume是Pod与外部存储设备进行数据传递的通道,也是Pod与内部容器间、Pod与Pod间、Pod与外部环境进行数据共享的方式。

Volume定义了外置存储的细节,并内嵌到Pod中作为Pod的一部分。其本质是外置存储在Kubernetes系统的一个资源映射,当负载需要使用外置存储时,可以从Volume中查到相关信息并进行挂载操作。

说明

Volume生命周期和Pod一致,即Pod被删除时,Volume本身可能会被删除,但Volume中的数据是否保留,取决于Volume的类型以及配置。

您在ACK可以使用的常用Volume类型如下:

类型

描述

本地存储

适用于本地存储的存储卷,例如hostPath、emptyDir等。本地存储卷的数据保存在集群特定节点上,并且不能随着应用迁移,节点停机时,数据将不再可用。

网络存储

适用于网络存储的存储卷,例如Ceph、GlusterFS、NFS、iSCSI等。网络存储卷的数据不在集群的某个节点上,而是在远端的存储服务上,使用存储卷时需将存储服务挂载至本地使用。

Secret和ConfigMap

Secret和ConfigMap是特殊的存储卷,其数据是集群的一些对象信息,该对象数据以卷的形式被挂载到节点上供应用使用。

PVC

一种存储卷定义方式,将存储卷抽象成一个独立于Pod的对象,这个对象定义(关联)的存储信息即存储卷对应的真正存储信息,供Kubernetes负载挂载使用。

Volume使用说明

  • 一个Pod可以挂载多个Volume,但不建议给一个Pod挂载过多的Volume存储卷。

  • 一个Pod可以挂载多种类型的Volume。

  • 每个被Pod挂载的Volume,可以在不同的容器间共享。

  • 对于需要持久化的数据,Kubernetes环境推荐使用PVC和PV方式挂载Volume。

PV和PVC

并非所有Volume都具有持久化特性,为了实现持久化的存储,容器存储需依赖于一个远程存储服务。Kubernetes引入了PV和PVC两个资源对象,将存储实现的细节从其如何被使用中抽象出来,从而让使用者不用关心具体的基础设施,当需要存储资源时,声明所需的存储需求即可。

PV(PersistentVolume)

PV持久化存储卷,表示具体存储类型的卷,用于定义存储实现的细节,例如,具体存储类型、存储卷参数,目标存储资源所有相关的信息都保存在PV中,Kubernetes引用PV中的存储信息进行挂载。您可以直接创建PV,通过静态卷的方式挂载,也可以创建StorageClass,由CSI的Provisioner组件动态创建PV进行挂载。

说明

PV是一个集群级别的概念,其对象作用范围是整个Kubernetes集群,而不是一个节点。PV拥有独立的生命周期,不依附于Pod。

apiVersion: v1
kind: PersistentVolume
metadata:
  namespace: default
  name: pv-example
spec:
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  csi:
    driver: diskplugin.csi.alibabacloud.com
    volumeHandle: <云盘ID>
  volumeMode: Filesystem

PVC(PersistentVolumeClaim)

PVC存储声明,表示Pod所需使用的持久化存储请求。例如,Volume存储大小、可读写权限等。PVC申请会消耗PV存储资源。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-example
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
  volumeName: pv-example

PV和PVC使用说明

PVC与PV是一一对应关系,不能一个PVC挂载多个PV,也不能一个PV挂载多个PVC。为应用配置存储时,需要声明一个存储需求声明(PVC),而Kubernetes会通过最佳匹配的方式选择一个满足PVC需求的PV,并与之绑定。PVC只有绑定了PV之后才能被Pod使用。满足以下规则的PV才能被PVC绑定:

  • VolumeMode:被消费PV的VolumeMode需要和PVC一致。

  • AccessMode:被消费PV的AccessMode需要和PVC一致。

  • StorageClassName:如果PVC定义了此参数,PV必须有相关的参数定义才能进行绑定。

  • LabelSelector:通过标签(Labels)匹配的方式从PV列表中选择合适的PV绑定。

  • storage:被消费PV的capacity必须大于或者等于PVC的存储容量需求才能被绑定。

PV和PVC中定义storage的作用:

  • PVC、PV绑定时,会根据各自的storage进行筛选。

  • 通过PVC、StorageClass动态创建PV时,例如,云盘会参考PVC的storage创建相应大小的PV和后端存储。

  • 对于支持Resize操作的存储类型,PVC的storage作为扩容后PV、后端存储的容量值。

真正的存储卷数据流写数据时,不会参考PVC和PV的storage字段,而是依赖底层存储介质的实际容量。

Volume访问模式

您可以通过accessModes来定义Volume存储卷的访问模式。

ReadWriteOnce(RWO)

Volume可以被一个节点以读写方式挂载,例如阿里云云盘。

ReadOnlyMany(ROX)

Volume可以被多个节点以只读方式挂载,例如阿里云OSS。

ReadWriteMany(RWX)

Volume可以被多个节点以读写方式挂载,例如阿里云NAS文件系统。

如何在Pod中挂载Volume

静态存储卷

image

静态存储卷是由管理员创建的PV,阿里云云盘、NAS和OSS存储介质都支持通过静态存储卷的方式使用。

  1. 静态存储卷由集群管理员分析集群中存储需求,并预先分配一些存储介质(例如云盘、NAS等)。

  2. 管理员根据存储实际情况,手工预先创建若干个PV对象,并定义好每个PV可以提供的具体存储能力,等待PVC来消费。

  3. 用户根据业务实际情况,创建PVC用于声明Pod运行所需的存储能力。

  4. 如果工作负载中定义了PVC需求,Pod在创建过程中,Kubernetes会通过相关规则完成PVC和匹配的PV进行绑定,实现应用对存储服务的访问。

动态存储卷

image

动态存储卷是指通过存储插件Provisioner自动创建的PV,阿里云云盘、NAS和OSS存储介质都支持通过动态存储卷的方式使用。

  1. 动态存储卷由集群管理员配置好后端的存储池,选择不同的Provisioner,以创建不同的存储类型。例如diskplugin.csi.alibabacloud.com表示使用阿里云云盘的Provisioner插件。

  2. 管理员无需手工分配PV,根据存储配置相应的StorageClass,等待PVC来消费。

  3. 用户根据业务实际情况,创建PVC用于声明Pod运行所需的存储能力,同时,在该PVC中声明需通过哪个StorageClass来处理该PVC的请求。

  4. 如果工作负载中定义了PVC需求,Pod在创建过程中,Kubernetes会依据该PVC中关联的StorageClass的存储细节,由存储插件Provisioner动态创建一个PV,实现应用对存储服务的访问。

使用动态存储卷的优势:

  • 动态存储卷让Kubernetes实现了PV的自动化生命周期管理,PV的创建、删除都通过Provisioner完成。

  • 自动化创建PV对象,减少了配置复杂度和集群管理员的工作量。

  • 动态存储卷可以实现PVC对存储的需求容量和Provisioner输出的PV容量一致,实现存储容量规划最优。

StorageClass

StorageClass用于定义存储的类别,提供动态分配存储卷的能力,您可以为其设置不同的参数,使存储资源能够根据需求自动供应和调整。在PVC存储声明中添加StorageClassName字段,当PVC在集群中找不到匹配的PV时,将根据StorageClassName的定义触发相应的Provisioner组件自动创建合适的PV以及底层存储,即创建动态存储卷,减少了创建和维护PV的工作量。下文以阿里云盘为例介绍如何自定义StorageClass存储类。更多关于云盘、NAS和OSS的自定义存储类及参数说明,请参见使用云盘动态存储卷使用NAS动态存储卷使用OSS动态存储卷

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: alicloud-disk-topology-alltype
provisioner: diskplugin.csi.alibabacloud.com
parameters:
  type: cloud_auto,cloud_essd,cloud_ssd,cloud_efficiency
  fstype: ext4
  diskTags/a: b
  encrypted: "false"
  performanceLevel: PL1
  provisionedIops: "40000"
  burstingEnabled: "false"
reclaimPolicy: Delete
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer  

主要参数说明

参数

说明

provisioner

存储资源提供商。支持配置如下:

  • diskplugin.csi.alibabacloud.com:表示使用阿里云云盘Provisioner插件创建StorageClass。

  • nasplugin.csi.alibabacloud.com:表示使用阿里云NAS Provisioner插件创建StorageClass。

  • ossplugin.csi.alibabacloud.com:表示使用阿里云OSS Provisioner插件创建StorageClass。

parameters

存储资源云盘的参数设置。

reclaimPolicy

存储资源云盘的回收策略,默认为Delete,支持Retain

  • Delete:删除PVC时,PV和云盘会一起删除。

  • Retain:删除PVC时,PV和云盘不会被删除,需要您手动删除。

如果数据安全性要求高,推荐使用Retain方式,以免误删数据。

allowVolumeExpansion

配置为true时,可以实现云盘的自动扩容。

volumeBindingMode

云盘的绑定模式。默认为Immediate,支持WaitForFirstConsumer

  • Immediate:表示先创建云盘再调度Pod。

  • WaitForFirstConsumer:延迟绑定,即调度器先调度Pod,并根据Pod的可用区信息创建云盘。推荐在多可用区集群中使用。

展开查看延迟绑定WaitForFirstConsumer说明

存储资源(例如阿里云云盘)不支持跨可用区挂载,使用时可能产生如下问题:

  • 创建了A可用区的存储卷,但是A可用区的节点资源已耗尽,导致Pod启动失败,无法挂载。

  • 集群管理员在规划PVC、PV的时候不能确定在哪些可用区创建多个PV作为备用。

volumeBindingMode参数用于解决此问题,将volumeBindingMode配置为WaitForFirstConsumer时,表示存储插件Provisioner在收到PVC Pending时,不会立即创建PV存储卷,而是等待该PVC被Pod消费时才执行创建流程。

实现原理

存储插件Provisioner在收到PVC Pending状态的时候不会立即进行存储卷创建,而是等待该PVC被Pod消费。若有Pod消费此PVC,调度器在识别该PVC属于延迟绑定模式后,会继续执行调度操作,并将调度结果通过patch命令写入PVC的metadata中。Provisioner检测到PVC中已写入的调度信息后,会根据调度信息获取创建目标存储卷的位置信息(地域和节点信息),然后触发PV的创建流程。

默认StorageClass

Kubernetes提供默认StorageClass机制,在PVC未指定StorageClassName的情况下,您可以通过默认StorageClass创建存储卷。更多信息,请参见Default StorageClass

由于默认StorageClass会对所有PVC起作用,对于具备不同类型存储卷能力的集群,需谨慎使用。例如,您想生成一个NAS类型PVC、PV,并绑定PVC和PV,但可能因为有默认StorageClass而自动创建了云盘PV。ACK集群没有提供默认StorageClass,如果您期望使用默认StorageClass,可以参考以下配置。

  1. 配置默认StorageClass。

    执行以下命令将StorageClass(alicloud-disk-topology-alltype)配置为一个默认StorageClass。

    说明

    此处以alicloud-disk-topology-alltype为例进行说明,

    kubectl annotate storageclass alicloud-disk-topology-alltype storageclass.kubernetes.io/is-default-class=true

    此时,查询集群中的StorageClass可以看到alicloud-disk-topology-alltype名字后面加了(default)字样。

    kubectl get sc

    返回结果如下:

    NAME                                        PROVISIONER                       AGE
    alicloud-disk-topology-alltype (default)    diskplugin.csi.alibabacloud.com   96m
  2. 使用默认StorageClass。

    1. 使用以下模板创建一个没有配置StorageClass的PVC。

      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
        name: disk-pvc
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 20Gi

      集群会自动创建一个云盘存储卷(PV),且配置了默认StorageClass(alicloud-disk-topology-alltype)。

      kubectl get pvc

      返回结果如下:

      NAME       STATUS   VOLUME                   CAPACITY   ACCESS MODES    STORAGECLASS                      AGE
      disk-pvc   Bound    d-bp18pbai447qverm****   20Gi       RWO             alicloud-disk-topology-alltype    49s

您可以通过以下命令取消默认存储类型的配置。

kubectl annotate storageclass alicloud-disk-topology-alltype storageclass.kubernetes.io/is-default-class-

容器服务 Kubernetes 版的StorageClass模板说明

StorageClass

匹配的存储卷类型

说明

alicloud-disk-efficiency

高效云盘

上一代云盘

alicloud-disk-ssd

SSD云盘

上一代云盘

alicloud-disk-essd

ESSD云盘

通过该StorageClass默认创建的为PL1级别的ESSD云盘。

alicloud-disk-topology-alltype

提供高可用选项,优先创建ESSD云盘。

  • 如果ESSD云盘售尽或当前节点不支持ESSD云盘,则尝试创建SSD云盘。

  • 如果SSD云盘售尽或当前节点不支持SSD云盘,则尝试创建高效云盘。

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: alicloud-disk-topology-alltype
    parameters:
      type: cloud_essd,cloud_ssd,cloud_efficiency
    provisioner: diskplugin.csi.alibabacloud.com
    reclaimPolicy: Delete
    allowVolumeExpansion: true
    volumeBindingMode: WaitForFirstConsumer

多可用区场景推荐

alibabacloud-cnfs-nas

创建集群时,可默认创建CNFS托管的NAS存储类,通过CNFS托管NAS使用时,可直接使用该存储类。更多信息,请参见使用CNFS管理NAS存储卷

CNFS托管NAS使用场景

相关文档

关于容器服务 Kubernetes 版存储相关的更多信息,请参见存储