Ideal for I/O-intensive and latency-sensitive workloads like databases and middleware, the dynamic volume mechanism simplifies storage lifecycle management by automatically creating and mounting a dedicated cloud disk for each application replica.
How it works
A StatefulSet uses cloud disks as dynamic storage volumes through the following process:
Define a template
Create or use a default StorageClass as a template to dynamically create cloud disks. The StorageClass specifies key parameters, such as the disk type, performance, and reclaim policy.Declare storage requirements in the application
In the StatefulSet, define
volumeClaimTemplatesand reference the StorageClass to specify the storage capacity and access mode for the PVCs.Automatically create and mount storage volumes
When the StatefulSet creates a Pod, the system automatically generates a unique PVC for the Pod based on the template. The CSI component then creates a PV based on the StorageClass, binds the PV to the PVC, and mounts the corresponding cloud disk to the Pod.
Prerequisites
Availability zone limitations: Except for ESSD zone-redundant cloud disks, other cloud disk types can only be attached to pods in the same availability zone.
Instance type family limitations: Some cloud disk types can only be attached to specific instance type families.
CSI component requirements: The csi-plugin and csi-provisioner components must be installed.
The CSI components are installed by default. Check the page to ensure they are still installed. We recommend upgrading the CSI components to the latest version.
Virtual node limitations: To use a cloud disk on a virtual node, your cluster and kube-scheduler must meet the following version requirements.
Lingjun Node limitations: To use a cloud disk on a Lingjun Node, you must meet the following requirements.
Step 1: Choose a StorageClass
ACK provides several default StorageClasses. Since a StorageClass cannot be modified after creation, you can manually create a StorageClass if the default configurations do not meet your requirements.
Default StorageClass
You can choose one of the following default StorageClasses and reference its name in the storageClassName field of your application.
Storageclass name | Provisioned disk type |
| This StorageClass schedules the Pod before creating the Cloud Disk, which prevents mount failures due to availability zone mismatches ( |
| Provisions an ESSD. The default performance level is PL1, and the minimum disk capacity is 20 GiB. Important ESSDs in a Cloud Box only support the PL0 performance level. You must manually create a StorageClass and specify |
| Provisions an SSD cloud disk. The minimum disk capacity is 20 GiB. |
| Provisions an ultra disk. The minimum disk capacity is 20 GiB. |
You can run kubectl describe sc <storageclass-name> to view the detailed configuration of a StorageClass.Manual creation
Kubectl
Create a file named
disk-sc.yaml.The following example shows a StorageClass that uses
volumeBindingMode: WaitForFirstConsumerto delay PV binding.apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: # Name of the StorageClass name: alicloud-disk-wait-for-first-consumer # Provisioner. This must be set to this value when using the Alibaba Cloud Disk CSI plug-in. provisioner: diskplugin.csi.alibabacloud.com parameters: # Cloud Disk type. The system attempts to create a disk in the specified order. type: cloud_auto,cloud_essd,cloud_ssd # File system type fstype: ext4 diskTags: "a:b,b:c" encrypted: "false" # Performance level for the ESSD performanceLevel: PL1 provisionedIops: "40000" burstingEnabled: "false" # Volume binding mode. WaitForFirstConsumer is recommended for multi-AZ scenarios. volumeBindingMode: WaitForFirstConsumer # Reclaim policy reclaimPolicy: Retain # Whether to allow volume expansion allowVolumeExpansion: true # Topology restrictions: Restricts disk creation to the specified availability zones. allowedTopologies: - matchLabelExpressions: - key: topology.diskplugin.csi.alibabacloud.com/zone values: # Replace with your availability zones - cn-hangzhou-i - cn-hangzhou-kThe following table describes the main parameters.
Parameter
Description
provisionerThe provisioner. This required parameter must be set to
diskplugin.csi.alibabacloud.comwhen using the Alibaba Cloud Disk CSI plug-in.parameterstypeThe Cloud Disk type. This is a required parameter. Valid values include:
cloud_essd(default): ESSDcloud_auto: ESSD AutoPL cloud diskcloud_essd_entry: Block Storage Overviewcloud_ssd: SSD cloud diskcloud_efficiency: ultra diskelastic_ephemeral_disk_standard: Standard elastic ephemeral diskelastic_ephemeral_disk_premium: Premium elastic ephemeral diskcloud_regional_disk_auto: ESSD Co-located Redundant Disk
You can specify a comma-separated list of types, for example,
type: cloud_ssd,cloud_essd,cloud_auto. The system attempts to create a disk in the specified order. The final disk type depends on factors like the node's instance type and the disk types available in the availability zone.resourceGroupIdThe resource group for the Cloud Disk. Default:
"".regionIdThe region of the Cloud Disk, which must be the same as the cluster's region.
fstypeThe file system for the Cloud Disk. Valid values:
ext4(default) andxfs.mkfsOptionsFormatting options for the Cloud Disk, for example,
mkfsOptions: "-O project,quota".diskTagsTags for the Cloud Disk. For example,
diskTags: "a:b,b:c". You can also use the formatdiskTags/a: b. Requires CSI component version v1.30.3 or later.encryptedSpecifies whether to encrypt the Cloud Disk. Default:
false.performanceLevelThe performance level of the ESSD. Valid values are
PL0,PL1(default),PL2, andPL3.When used with a Cloud Box, this must be set to
PL0.volumeExpandAutoSnapshot(Deprecated)Deprecated since CSI version 1.31.4.
provisionedIopsSets the provisioned IOPS for an ESSD AutoPL cloud disk.
burstingEnabledFor an ESSD AutoPL cloud disk, specifies whether to enable burst. Default:
false.multiAttachSpecifies whether to enable the multi-attach feature for the Cloud Disk. Default:
false.volumeBindingModeThe volume binding mode for the Cloud Disk. Valid values:
Immediate(default): Creates the Cloud Disk before creating the Pod.WaitForFirstConsumer: Delays binding. Schedules the Pod first, then creates the Cloud Disk in the Pod's availability zone.In multi-AZ clusters,
WaitForFirstConsumeris recommended to prevent mount failures that can occur if a Cloud Disk and its node are in different availability zones.If you need to schedule Pods to virtual nodes, using a StorageClass of type
WaitForFirstConsumeris not supported with certain scheduling methods or specific annotations. For more information, see What do I do if a PVC remains in the Pending state when a Pod with a Cloud Disk is scheduled to a virtual node?.
reclaimPolicyThe reclaim policy for the Cloud Disk.
Delete(default): When the PVC is deleted, the PV and the underlying Cloud Disk are also deleted.Retain: When the PVC is deleted, the PV and the underlying Cloud Disk are retained.To prevent accidental data loss, we recommend using the
Retainpolicy.
allowVolumeExpansionIf set to
true, allows online expansion of Cloud Disks.allowedTopologiesRestricts the Cloud Disk to be provisioned only in specific topological domains.
key: The topology domain label. Supported values include:topology.diskplugin.csi.alibabacloud.com/zone: A dedicated topologykeyprovided by the Alibaba Cloud CSI plug-in.alibabacloud.com/ecs-instance-id: When using an elastic ephemeral disk, you can use this to specify a node.
values: A list containing availability zone or node IDs.
Create the StorageClass.
kubectl create -f disk-sc.yamlVerify the StorageClass.
kubectl get scThe output shows that the StorageClass was created with the
WaitForFirstConsumerbinding mode.NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE alicloud-disk-wait-for-first-consumer diskplugin.csi.alibabacloud.com Retain WaitForFirstConsumer true 10s
Console
On the ACK Clusters page, click the name of your cluster. In the left navigation pane, click .
Click Create, select Cloud Disk as the Volume Type, configure the parameters, and then click Create.
Parameter
Description
Parameters
Default parameter:
type.The Cloud Disk type. This is a required parameter. Valid values include:
cloud_essd(default): ESSDcloud_auto: ESSD AutoPL cloud diskcloud_essd_entry: Block Storage Overviewcloud_ssd: SSD cloud diskcloud_efficiency: ultra diskelastic_ephemeral_disk_standard: Standard elastic ephemeral diskelastic_ephemeral_disk_premium: Premium elastic ephemeral diskcloud_regional_disk_auto: ESSD Co-located Redundant Disk
You can specify a comma-separated list of types, for example,
type: cloud_ssd,cloud_essd,cloud_auto. The system attempts to create a disk in the specified order. The final disk type depends on factors like the node's instance type and the disk types available in the availability zone.
Reclaim policy
The reclaim policy for the Cloud Disk.
Delete(default): When the PVC is deleted, the PV and the underlying Cloud Disk are also deleted.Retain: When the PVC is deleted, the PV and the underlying Cloud Disk are retained.To prevent accidental data loss, we recommend using the
Retainpolicy.
Binding Mode
The volume binding mode for the Cloud Disk. Valid values:
Immediate(default): Creates the Cloud Disk before creating the Pod.WaitForFirstConsumer: Delays binding. Schedules the Pod first, then creates the Cloud Disk in the Pod's availability zone.In multi-AZ clusters,
WaitForFirstConsumeris recommended to prevent mount failures that can occur if a Cloud Disk and its node are in different availability zones.If you need to schedule Pods to virtual nodes, using a StorageClass of type
WaitForFirstConsumeris not supported with certain scheduling methods or specific annotations. For more information, see What do I do if a PVC remains in the Pending state when a Pod with a Cloud Disk is scheduled to a virtual node?.
The new StorageClass appears on the StorageClasses page.
Step 2: Create an application with a cloud disk
This section uses a StatefulSet as an example to show how to mount a Cloud Disk volume.
A Cloud Disk provides non-shared storage and, unless multi-attach is enabled, can be mounted to only one Pod at a time. Sharing a PVC in a multi-replica Deployment can prevent new Pods from starting if the Cloud Disk is already in use by another Pod.
If you still need to use a Cloud Disk with a Deployment, consider using a Cloud Disk as an ephemeral volume. To enable multi-attach, see Use NVMe-based Cloud Disks with multi-attach and reservation.
Create a file named
statefulset.yaml.The following example creates a StatefulSet with two Pods. It uses
volumeClaimTemplatesto automatically create and bind an independent persistent volume for each Pod.apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: serviceName: "nginx" replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: # We recommend configuring the following securityContext to optimize mount performance. securityContext: fsGroup: 1000 fsGroupChangePolicy: "OnRootMismatch" containers: - name: nginx image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6 ports: - containerPort: 80 volumeMounts: # Mount the data volume to the /data directory in the container. # The name must match metadata.name defined in volumeClaimTemplates. - name: pvc-disk mountPath: /data # Define the PVC template. volumeClaimTemplates: - metadata: name: pvc-disk spec: # Access mode accessModes: [ "ReadWriteOnce" ] # Associate with the StorageClass created earlier. storageClassName: "alicloud-disk-wait-for-first-consumer" resources: requests: # Requested storage capacity, which is the size of the Cloud Disk. storage: 20GiImportantWhen you configure
securityContext.fsgroup, the kubelet recursively changes file permissions (chmod/chown) when mounting a volume. This can significantly increase mount time for volumes with many files.For clusters of version 1.20 or later, we recommend setting
fsGroupChangePolicytoOnRootMismatch. This optimizes mount performance by only performing the recursive permission change when the volume is first mounted and the root directory permissions do not match. If performance remains an issue or you require more granular permission control, use aninitContainerto manage permissions before the application container starts.Create the StatefulSet.
kubectl create -f statefulset.yamlVerify that the Pods are running.
kubectl get pod -l app=nginxVerify that the Cloud Disk is mounted.
In this example, the Pod is named
web-1. Replace it with your actual Pod name.kubectl exec web-1 -- df -h /dataExpected output:
Filesystem Size Used Avail Use% Mounted on /dev/vdb 20G 24K 20G 1% /data
Step 3: Verify persistent storage
To verify that data on the cloud disk is persistent, you will write data to the disk, delete the Pod, and then check that the data persists after the Pod is recreated.
Write test data to the Pod.
In the
web-1Pod, create a file namedtestin the/datadirectory, which is the mount point for the cloud disk.kubectl exec web-1 -- touch /data/test kubectl exec web-1 -- ls /dataExpected output:
lost+found testSimulate a Pod failure by deleting the Pod.
kubectl delete pod web-1Run
kubectl get pod -l app=nginxagain. A new Pod with the same name,web-1, is automatically created.Verify the data in the new Pod.
In the new
web-1Pod, check the/datadirectory again.kubectl exec web-1 -- ls /dataThe output confirms that the
testfile still exists. This demonstrates that persistent storage preserves the data, even after the Pod is deleted and recreated.lost+found test
Production deployment
High availability
Cloud disk selection
Evaluate factors such as performance, billing, availability zones, and instance type families to ensure your pods are scheduled to compatible nodes.
When you select a cloud disk type, note that SSD cloud disks and Ultra cloud disks are being phased out. We recommend using ESSD PL0 cloud disks or ESSD Entry cloud disks to replace Ultra cloud disks, and ESSD AutoPL cloud disks to replace SSD cloud disks.
Cross-AZ disaster recovery
Application-level disaster recovery: For critical workloads such as databases, deploy application instances across multiple availability zones and use the application's native data synchronization mechanism for high availability.
Storage-level disaster recovery: Choose a cloud disk type that supports multi-AZ disaster recovery. This feature writes data synchronously to different availability zones within the same region, enabling cross-AZ failover. For more information, see Use ESSD Co-located Redundant Disks.
Data security and backup
Preventing accidental data deletion:
To prevent data loss, set the
reclaimPolicyof the StorageClass toRetain. This ensures the underlying cloud disk is retained when the PVC is deleted, which simplifies data recovery.Regular backups
Dynamic volumes simplify resource provisioning but do not replace data backups. For critical workloads, use Backup Center to back up and restore your data.
Encryption at rest: For applications that handle sensitive data, configure
encrypted: "true"in the StorageClass to encrypt cloud disks.
Performance and cost optimization
Parallel attach
To accelerate pod startup, use parallel attach for cloud disks.
Online volume resizing
Set
allowVolumeExpansion: truein the StorageClass to resize cloud disk storage volumes online when your storage needs grow.Storage monitoring and alerts
Configure alerts based on container storage monitoring to promptly detect storage volume anomalies or performance bottlenecks.
Billing
Cloud disks that are dynamically provisioned by a StorageClass use pay-as-you-go billing. For more information, see block storage billing and block storage pricing.
Clean up resources
To prevent unexpected charges and ensure data security, follow these steps to release unused resources.
Delete the workload
Action: Delete all applications using the associated PersistentVolumeClaim (PVC), such as Deployments and StatefulSets. This stops the running Pods and unmounts the associated volumes.
Example command:
kubectl delete deployment <your-deployment-name>
Delete the PVC
Action: Delete the PVC associated with your application. The
reclaimPolicyof the StorageClass determines the release of the bound PersistentVolume (PV) and underlying cloud disk.Delete: If the policy isDelete, deleting the PVC also deletes its bound PV and the underlying cloud disk. This action is irreversible. Proceed with caution.To prevent accidental data loss, you can create an automatic snapshot policy to back up the cloud disk before deletion.
Retain: If the policy isRetain, deleting the PVC changes the status of its bound PV toReleased, but the PV object and the underlying cloud disk are retained. If you no longer need the cloud disk and its data, follow the instructions in Release a cloud disk to delete it. This action is irreversible. Proceed with caution.
Example command:
kubectl delete pvc <your-pvc-name>
Delete Kubernetes storage resource definitions. This action removes only the resource definitions from the cluster and does not delete the underlying cloud disk.
Delete the PV
Action: You can manually delete the resource definition for a PV in the
Releasedstate.Example command:
kubectl delete pv <your-pv-name>
Delete the StorageClass
Action: If you no longer need this type of storage, you can delete the corresponding StorageClass.
Example command:
kubectl delete sc <your-storageclass-name>
FAQ
PVC stuck in Pending state when scheduled to a virtual node
This issue can occur if you use a StorageClass that does not support scheduling to virtual nodes. When a pod is scheduled to a virtual node using specific labels or annotations, you cannot use a StorageClass configured with volumeBindingMode: WaitForFirstConsumer.
Reason:
The WaitForFirstConsumer mode relies on the kube-scheduler to select a physical node for a Pod. This selection determines the availability zone, and a cloud disk is then created in that availability zone. However, the scheduling mechanism for virtual nodes does not follow this process. This prevents the CSI from obtaining the availability zone information, which in turn prevents the PV from being created, leaving the PVC in the Pending state.If you encounter this issue, check whether your pod or its namespace has any of the following configurations:
Label:
alibabacloud.com/eci: "true": Schedules the pod to run on ECI.alibabacloud.com/acs: "true": Schedules the pod to an ACS pod.
Node pinning:
Setting
spec.nodeNameto a node name with thevirtual-kubeletprefix pins the pod to that node.
Annotation:
k8s.aliyun.com/eci-vswitch: Specifies the vSwitch for the ECI pod.k8s.aliyun.com/eci-fail-strategy: "fail-fast": Sets the failure strategy for the ECI pod tofail-fast.
Mount a cloud disk for a single pod or single-replica deployment
For simple applications that do not require multi-replica scaling or stable network identifiers, you can manually create a PersistentVolumeClaim and mount it to a pod or a Deployment for persistent storage.
The workflow is as follows: Choose a StorageClass -> Create a PersistentVolumeClaim -> Mount the PersistentVolumeClaim in your application.
Create a PersistentVolumeClaim to request storage resources.
kubectl
Create a file named
disk-pvc.yaml.apiVersion: v1 kind: PersistentVolumeClaim metadata: name: disk-pvc spec: # Access mode accessModes: - ReadWriteOnce volumeMode: Filesystem resources: requests: # Requested storage capacity, which is the size of the cloud disk storage: 20Gi # Associate with the StorageClass created earlier storageClassName: alicloud-disk-topology-alltypeThe following table describes the parameters.
Parameter
Description
accessModesThe access modes of the volume. Valid values are
ReadWriteOnce,ReadOnlyMany, andReadWriteMany. The supported access modes depend on themultiAttachsetting in the StorageClass and thevolumeModesetting in the PersistentVolumeClaim.multiAttachspecifies whether to enable cloud disk multi-attach. The default value isfalse, which means the feature is disabled.When
multiAttachisfalseandvolumeModeis set to any value, the only supported access mode isReadWriteOnce.When
multiAttachistrueandvolumeModeisFilesystem, the supported access modes areReadWriteOnceandReadOnlyMany.When
multiAttachis set totrueandvolumeModeis set toBlock, all three access modes are supported.
ImportantIn this scenario, the access mode is typically
ReadWriteOnce(RWO), which means that it can be mounted by only one Pod at a time. Therefore, the number of Deployment replicas cannot be greater than 1. If you attempt to scale out, new Pods will remain in thePendingstate because they cannot mount the cloud disk that is already in use.volumeModeThe mode of the volume. Valid values:
Filesystem(default): The volume is formatted and mounted as a directory.Block: The volume is provided to the pod as a raw, unformatted block device.
storageThe requested storage capacity. Different cloud disk types have different capacity ranges. Ensure that the value of
storageis within the capacity limits of the cloud disk type that corresponds to the referenced StorageClass to prevent cloud disk creation failure.storageClassNameThe name of the StorageClass to use for this claim.
Create the PersistentVolumeClaim.
kubectl create -f disk-pvc.yamlCheck the PersistentVolumeClaim.
kubectl get pvcIn the output, because the StorageClass uses the
WaitForFirstConsumermode, the PVC is in thePendingstate until the first Pod that uses it is successfully scheduled.NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE disk-pvc Pending alicloud-disk-wait-for-first-consumer <unset> 14s
Console
In the left navigation pane of the cluster management page, choose .
On the Persistent Volume Claims page, click Create. Select Cloud Disk as the PVC Type and configure the parameters as prompted.
Parameter
Description
Allocation Mode
Select Use StorageClass.
Existing Storage Class
Select a default or manually created StorageClass.
Capacity
The requested storage capacity. Different cloud disk types have different capacity ranges. Ensure that the value of
storageis within the capacity limits of the cloud disk type that corresponds to the referenced StorageClass to prevent cloud disk creation failure.Access Mode
This scenario supports only ReadWriteOnce, which means a single pod can mount the volume with read-write access.
After creating the PersistentVolumeClaim, you can view it on the Persistent Volume Claims page.
Mount the PersistentVolumeClaim in your application.
Create a file named
disk-deployment.yaml.Deploy the Deployment.
kubectl create -f disk-deployment.yaml
Verify the mount result.
Confirm that the pod is running.
kubectl get pods -l app=nginx-singleConnect to the pod and verify that the cloud disk is mounted to the
/datadirectory.# Get the pod name POD_NAME=$(kubectl get pods -l app=nginx-single -o jsonpath='{.items[0].metadata.name}') # Run the df -h command on the mount point kubectl exec $POD_NAME -- df -h /dataThe following output indicates that the 20 GiB cloud disk is successfully mounted.
Filesystem Size Used Avail Use% Mounted on /dev/vdb 20G 24K 20G 1% /data
References
For recommendations on configuring high availability for cloud disk volumes in a multi-availability zone deployment, see High availability configuration recommendations for cloud disk volumes.
To learn about workload configuration parameters, see Create a stateful workload with a StatefulSet and Create a stateless workload with a Deployment.
If you no longer need a cloud disk and want to stop being billed for it, you can Release a cloud disk. Releasing the disk permanently deletes it and all its data.
If you encounter issues when using cloud disk volumes, see Cloud disk volume FAQ.
If your cluster is still using the deprecated FlexVolume component, see Migrate from FlexVolume to CSI.