动态挂载云盘存储卷

对于非共享数据,I/O和延迟要求较高的应用场景,可以选择云盘作为持久化存储卷。本文介绍如何为应用动态挂载云盘存储卷,并验证云盘的持久化存储。

背景信息

云盘是一种数据块级别的块存储产品,采用分布式多副本机制,具有低时延、高性能、持久性、高可靠等特点。适用于非共享数据,以及对I/O、延迟要求较高的应用场景。更多信息,请参见存储概述

说明

ACS仅支持动态挂载云盘存储卷,暂不支持静态挂载云盘存储卷。

前提条件

ACS集群中已安装最新版本的managed-csiprovisioner组件。

说明

您可以在ACS集群管理页的左侧导航栏选择运维管理 > 组件管理,在存储页签下查看managed-csiprovisioner组件的安装情况。

使用限制

  • 云盘为非共享存储,一个云盘存储卷只能挂载到一个Pod上。

  • 云盘只能挂载到相同可用区的Pod上,不支持跨可用区挂载。

注意事项

  • 推荐使用StatefulSet挂载云盘或者单独为Pod挂载云盘,不推荐使用Deployment。

    说明

    由于一个云盘只能挂载到一个Pod上,为Deployment挂载云盘时,Replica必须配置为1,即无法为每个Pod配置独立的存储卷,并且不能保证挂载、卸载的优先顺序。此外,由于Deployment的升级策略,重启Pod时,新的Pod可能会一直无法挂载云盘。因此不推荐为Deployment挂载云盘。

  • 动态挂载云盘时,自动创建的云盘采用按量计费。

  • 动态挂载云盘时,如果在应用的YAML中配置了securityContext.fsgroup,在挂载完成后,ACS会执行chmodchown操作,导致挂载时间延长。

    说明

    配置了securityContext.fsgroup后,挂载云盘时会自动调整卷内文件的所有者,根据文件数量,这可能导致较长的准备时间。您可以将fsGroupChangePolicy配置为OnRootMismatch,实现仅在首次启动容器时才会调整文件的所有者,后续Pod升级或重建等场景下,挂载时长会恢复正常。若仍不能满足需求,建议利用initContainer自行实现调整权限相关操作。

动态挂载云盘存储卷

通过kubectl命令

步骤一:创建StorageClass

默认情况下,ACS提供了名为alicloud-disk-topology-alltype的StorageClass,该StorageClass支持依次创建cloud_essd(ESSD云盘)、cloud_ssd(SSD云盘)和cloud_efficiency (高效云盘)类型的PV。如果默认提供的StorageClass无法满足您的需求,您可以参考以下步骤手动创建新的StorageClass。

  1. 连接集群。具体操作,请参见获取集群KubeConfig并通过kubectl工具连接集群在CloudShell上通过kubectl管理Kubernetes集群

  2. 参考参数说明表修改以下YAML内容,并保存为disk-sc.yaml。

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: alicloud-disk-essd
    provisioner: diskplugin.csi.alibabacloud.com
    parameters:
      type: cloud_essd
      fstype: ext4
      performanceLevel: PL1
    reclaimPolicy: Delete
    volumeBindingMode: WaitForFirstConsumer
    allowVolumeExpansion: true

    相关参数说明如下:

    参数

    说明

    type

    云盘类型。取值如下:

    • cloud_essd_entry:ESSD Entry云盘

    • cloud_auto:ESSD AutoPL云盘

    • cloud_essd(默认值):ESSD云盘

    • cloud_ssd:SSD云盘

    • cloud_efficiency:高效云盘

    支持任意组合上述参数,例如:type: cloud_efficiency, cloud_ssd, cloud_essd,此时将按照配置顺序依次尝试创建指定类型的云盘,直到创建成功。

    说明

    您可以结合云盘计费、性能等选择合适的云盘类型。更多信息,请参见块存储价格块存储性能

    fstype

    云盘的文件系统类型。默认为ext4。支持ext3ext4xfs

    performanceLevel

    ESSD云盘的性能级别。默认为PL1。支持PL0PL1PL2PL3。更多信息,请参见ESSD云盘

    provisioner

    驱动类型。此处配置为diskplugin.csi.alibabacloud.com,表示使用阿里云云盘CSI插件。

    reclaimPolicy

    云盘的回收策略,仅支持Delete,表示删除PVC时,PV和云盘会一起删除。

    volumeBindingMode

    云盘的绑定模式。仅支持WaitForFirstConsumer,表示延迟绑定,即先调度Pod,再根据Pod的可用区信息创建云盘。

    allowVolumeExpansion

    是否自动扩容云盘。

  3. 创建StorageClass。

    kubectl create -f disk-sc.yaml
  4. 查看StorageClass。

    kubectl get sc

    预期返回:

    NAME                             PROVISIONER                       RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
    alicloud-disk-essd               diskplugin.csi.alibabacloud.com   Delete          WaitForFirstConsumer   true                   78s
    alicloud-disk-topology-alltype   diskplugin.csi.alibabacloud.com   Delete          WaitForFirstConsumer   true                   23d
    ......

步骤二:创建PVC

  1. 将以下YAML内容保存为disk-pvc.yaml。

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: disk-pvc
    spec:
      accessModes:
      - ReadWriteOncePod
      volumeMode: Filesystem
      resources:
        requests:
          storage: 20Gi
      storageClassName: alicloud-disk-essd

    相关参数说明如下:

    参数

    说明

    accessModes

    访问模式。目前仅支持ReadWriteOncePod。

    volumeMode

    存储卷的模式。取值范围:

    • Filesystem(默认):文件系统

    • Block:块

    storage

    分配给Pod的存储容量,即要创建的云盘容量大小。

    storageClassName

    要绑定的StorageClass名称。

  2. 创建PVC。

    kubectl create -f disk-pvc.yaml
  3. 查看PVC。

    kubectl get pvc

    预期返回如下,可以看到由于volumeBindingModeWaitForFirstConsumer,此时PVC还未绑定PV。

    NAME       STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS         VOLUMEATTRIBUTESCLASS   AGE
    disk-pvc   Pending                                      alicloud-disk-essd   <unset>                 7s

步骤三:创建应用并挂载云盘

  1. 使用以下YAML内容,创建disk-test.yaml文件。

    以下YAML示例可以创建包含1个Pod的StatefulSet,Pod通过名为disk-pvc的PVC申请存储资源,挂载路径为/data

    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: disk-test
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: registry.cn-hangzhou.aliyuncs.com/acs-sample/nginx:latest
            ports:
            - containerPort: 80
            volumeMounts:
            - name: pvc-disk
              mountPath: /data
          volumes:
            - name: pvc-disk
              persistentVolumeClaim:
                claimName: disk-pvc
  2. 创建StatefulSet并挂载云盘。

    kubectl create -f disk-test.yaml
    重要

    创建StatefulSet时,系统将根据PVC和StorageClass的配置自动创建一块按量付费的云盘,以及对应的PV。

  3. 查看StatefulSet中Pod的部署情况。

    kubectl get pod | grep disk-test

    预期返回如下,示例使用的StatefulSet副本数为1,因此创建了一个Pod。

    disk-test-0   1/1     Running   0          52s
  4. 查看PVC。

    kubectl get pvc

    预期返回如下,可以看到此时PVC已绑定自动创建的云盘类型的PV。

    NAME       STATUS   VOLUME                   CAPACITY   ACCESS MODES   STORAGECLASS         VOLUMEATTRIBUTESCLASS   AGE
    disk-pvc   Bound    d-uf698s3h14isyj6b****   20Gi       RWOP           alicloud-disk-essd   <unset>                 111s
  5. 查看挂载路径,确认已挂载云盘。

    kubectl exec disk-test-0 -- df | grep data

    预期返回:

    /dev/vdb        20466256      24  20449848   1% /data

通过控制台

步骤一:创建存储类(StorageClass)

默认情况下,ACS提供了名为alicloud-disk-topology-alltype的StorageClass,该StorageClass支持依次创建cloud_essd(ESSD云盘)、cloud_ssd(SSD云盘)和cloud_efficiency (高效云盘)类型的PV。如果默认提供的StorageClass无法满足您的需求,您可以参考以下步骤手动创建新的StorageClass。

  1. 登录容器计算服务控制台

  2. 集群页面,单击目标集群ID,进入该集群的管理页面。

  3. 在集群管理页面的左侧导航栏,选择存储 > 存储类

  4. 创建存储类。

    1. 存储类页面,单击创建

    2. 在弹出的对话框中,完成参数配置,然后单击创建

      参数

      说明

      示例

      名称

      StorageClass名称,自定义输入。格式要求请参考界面提示。

      alicloud-disk-essd

      存储卷类型

      选择云盘

      云盘

      参数

      默认参数为type,表示云盘类型。取值如下:

      • cloud_essd_entry:ESSD Entry云盘

      • cloud_auto:ESSD AutoPL云盘

      • cloud_essd(默认值):ESSD云盘

      • cloud_ssd:SSD云盘

      • cloud_efficiency:高效云盘

      支持任意组合上述参数,例如:type: cloud_efficiency, cloud_ssd, cloud_essd,此时将按照配置顺序依次尝试创建指定类型的云盘,直到创建成功。

      说明

      您可以结合云盘计费、性能等选择合适的云盘类型。更多信息,请参见块存储价格块存储性能

      可添加以下参数:

      • fstype

        云盘的文件系统类型。默认为ext4。支持ext3ext4xfs

      • performanceLevel

        ESSD云盘的性能级别。默认为PL1。支持PL0PL1PL2PL3。更多信息,请参见ESSD云盘

      type:cloud_essd

      回收策略

      云盘的回收策略,仅支持Delete,表示删除PVC时,PV和云盘会一起删除。

      Delete

      绑定模式

      云盘的绑定模式。仅支持WaitForFirstConsumer,表示延迟绑定,即先调度Pod,再根据Pod的可用区信息创建云盘。

      WaitForFirstConsumer

步骤二:创建存储声明(PVC)

  1. 在集群管理页面的左侧导航栏,选择存储 > 存储声明

  2. 存储声明页面,单击创建

  3. 在弹出的对话框中,完成参数配置,然后单击创建

    参数

    说明

    示例

    存储声明类型

    选择云盘

    云盘

    名称

    PVC名称,自定义输入。格式要求请参考界面提示。

    disk-pvc

    分配模式

    默认已选择使用存储类动态创建

    使用存储类动态创建

    已有存储类

    选择要绑定的StorageClass。

    alicloud-disk-essd

    总量

    分配给Pod的存储容量,即要创建的云盘容量大小。

    20Gi

    访问模式

    仅支持ReadWriteOnce,表示卷只能被一个Pod以读写方式挂载。

    ReadWriteOnce

    创建完成后,在存储声明页面可以看到新创建的PVC,由于StorageClass中绑定模式为WaitForFirstConsumer,此时PVC还未绑定PV,状态为Pending。

步骤三:创建应用并挂载云盘

  1. 在集群管理页面的左侧导航栏,选择工作负载 > 有状态

  2. 有状态页面,单击使用镜像创建

  3. 完成StatefulSet的参数配置,单击创建

    需要注意的参数如下,其他参数保持默认即可。更多信息,请参见创建有状态工作负载StatefulSet

    配置页

    参数

    说明

    示例

    应用基本信息

    应用名称

    StatefulSet名称,自定义输入。格式要求请参考界面提示。

    disk-test

    副本数量

    配置StatefulSet的副本数量。

    1

    容器配置

    镜像名称

    输入用于部署应用的镜像地址。

    registry.cn-hangzhou.aliyuncs.com/acs-sample/nginx:latest

    所需资源

    设置所需的vCPU和内存资源。

    0.25 vCPU,0.5 GiB

    数据卷

    单击增加云存储声明,然后完成参数配置。

    • 挂载源:选择之前创建的PVC。

    • 容器路径:输入云盘要挂载到的容器路径。

    • 挂载源:disk-pvc

    • 容器路径:/data

  4. 查看应用部署情况。

    1. 有状态页面,单击应用名称。

    2. 容器组页签下,确认Pod已正常运行(状态为Running)。

  5. 查看存储卷和存储声明。

    • 存储卷页面,可以看到已自动创建了一个PV,该PVC的名称对应云盘ID。

    • 存储声明页面,可以看到PVC已绑定PV,状态为Bound。

验证云盘的持久化存储

按照上文示例创建的StatefulSet中含有1个Pod,该Pod挂载了一个云盘。当该Pod被删除时,自动创建的新Pod将重新挂载之前的云盘,云盘中的数据仍然保留。您可以通过以下方式验证云盘的持久化存储。

  1. 查看挂载路径,即查看云盘中的数据。

    kubectl exec disk-test-0 -- ls /data

    预期返回:

    lost+found
  2. 在云盘中写入文件。

    kubectl exec disk-test-0 -- touch /data/test
  3. 删除Pod。

    kubectl delete pod disk-test-0
    说明

    删除StatefulSet中的Pod后,系统会自动创建一个新的Pod。

  4. 查看新创建的Pod。

    kubectl get pod

    预期返回如下,由于StatefulSet的命名特性,新创建的Pod和之前的Pod名称一致。

    NAME          READY   STATUS    RESTARTS   AGE
    disk-test-0   1/1     Running   0          27s
  5. 确认新创建的Pod已重新挂载云盘,云盘中的数据仍然存在。

    kubectl exec disk-test-0 -- ls /data

    预期返回如下,可以看到云盘中存在之前写入的test文件。

    lost+found  test