Kubernetes does not automatically know which cloud disk to provision for a workload — you must define a StorageClass that maps your disk type and zone preferences, then reference it in a persistent volume claim (PVC). When the PVC is created, the Disk-Controller provisions the disk automatically and binds it as a persistent volume (PV).
Prerequisites
Before you begin, ensure that you have:
-
A running ACK cluster with kubectl configured
-
Permissions to create StorageClass and PVC resources in the cluster
Default StorageClasses
Single-zone clusters include the following StorageClasses out of the box. Multi-zone clusters require you to create a StorageClass manually to specify the target zone.
| StorageClass | Disk type | Best for |
|---|---|---|
alicloud-disk-efficiency |
Ultra disk | Cost-sensitive workloads with moderate I/O requirements |
alicloud-disk-ssd |
Standard SSD | General-purpose workloads requiring reliable performance |
alicloud-disk-essd |
Enhanced SSD (ESSD) | Low-latency, high-throughput production workloads |
alicloud-disk-available |
High-availability mode | Workloads where disk availability takes priority over disk type |
alicloud-disk-topology |
WaitForFirstConsumer mode | Multi-zone clusters where pod scheduling determines the disk zone |
For alicloud-disk-available, the system attempts to create a standard SSD first, then falls back to an ultra disk if SSD resources are exhausted. For Disk-Controller versions earlier than v1.14.8.44-c23b62c5-aliyun, the fallback order is: enhanced SSD (ESSD) → standard SSD → ultra disk.
Create a StorageClass
Choose a StorageClass type based on your cluster configuration:
-
Single-zone cluster or fixed-zone disk: Create a StorageClass with a zone ID
-
Multi-zone cluster: Create a StorageClass in WaitForFirstConsumer mode
Create a StorageClass with a zone ID
Use this approach for single-zone clusters or when you want to pin disk creation to a specific zone.
-
Create a file named
storage-class.yamlwith the following content:kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: alicloud-disk-ssd-hangzhou-b provisioner: alicloud/disk parameters: type: cloud_ssd regionId: cn-hangzhou zoneId: cn-hangzhou-b reclaimPolicy: Retain # Default is Delete. Set to Retain to prevent accidental data loss.The following table describes the parameters:
Parameter Description Required Default provisionerThe volume plug-in for provisioning disks. Set to alicloud/disk.Yes — typeThe disk type. Valid values: cloud_efficiency(ultra disk),cloud_ssd(standard SSD),cloud_essd(ESSD),available(high-availability mode that automatically selects the best available type).Yes — regionIdThe region where the disk is created. Yes — zoneIdThe zone where the disk is created. For multi-zone clusters, specify multiple zones separated by commas: cn-hangzhou-a,cn-hangzhou-b,cn-hangzhou-c.Yes — reclaimPolicyThe policy for reclaiming the disk when the PVC is deleted. Retainkeeps the disk;Deleteremoves it. Set toRetainto prevent data loss.No DeleteencryptedWhether to encrypt the disk. No false -
Apply the StorageClass:
kubectl apply -f storage-class.yaml -
Verify that the StorageClass was created:
kubectl get storageclass alicloud-disk-ssd-hangzhou-bThe output should show the StorageClass with
alicloud/diskas the provisioner.
Create a StorageClass in WaitForFirstConsumer mode
In multi-zone clusters, a PV can be provisioned before a pod is scheduled — placing the disk in a zone that differs from where the pod eventually runs. When that happens, the pod fails to start because it cannot attach a disk from another zone. WaitForFirstConsumer mode solves this by delaying disk provisioning until the consuming pod is scheduled, so the disk is always created in the same zone as the pod.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: alicloud-disk-topology-ssd
provisioner: alicloud/disk
parameters:
type: cloud_ssd
reclaimPolicy: Retain # Default is Delete.
volumeBindingMode: WaitForFirstConsumer
Apply the StorageClass:
kubectl apply -f storage-class-topology.yaml
How zone selection works — the following table summarizes disk placement behavior based on your StorageClass configuration:
| Configuration | Disk placement |
|---|---|
No zoneId, no WaitForFirstConsumer |
Zone where the Disk-Controller component is deployed |
zoneId set, no WaitForFirstConsumer |
Specified zones, selected by round-robin |
WaitForFirstConsumer enabled |
Zone of the node where the consuming pod is scheduled |
Create a PVC and a Pod
The following manifest creates a PVC backed by the alicloud-disk-ssd-hangzhou-b StorageClass and a Pod that mounts the disk:
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: disk-ssd
spec:
accessModes:
- ReadWriteOnce
storageClassName: alicloud-disk-ssd-hangzhou-b
resources:
requests:
storage: 20Gi
---
kind: Pod
apiVersion: v1
metadata:
name: disk-pod-ssd
spec:
containers:
- name: disk-pod
image: nginx
volumeMounts:
- name: disk-pvc
mountPath: "/mnt"
restartPolicy: "Never"
volumes:
- name: disk-pvc
persistentVolumeClaim:
claimName: disk-ssd
Apply the manifest:
kubectl apply -f pvc-pod.yaml
Verify that the PVC is bound and the Pod is running:
kubectl get pvc disk-ssd
kubectl get pod disk-pod-ssd
A successfully bound PVC shows STATUS: Bound. A running Pod shows STATUS: Running.
Create a multi-instance StatefulSet
Use volumeClaimTemplates to dynamically create a separate PVC and PV for each StatefulSet replica. The following example creates a two-replica nginx StatefulSet with a 20 GiB disk per replica:
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx
serviceName: "nginx"
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
name: web
volumeMounts:
- name: disk-ssd
mountPath: /data
volumeClaimTemplates:
- metadata:
name: disk-ssd
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "alicloud-disk-ssd-hangzhou-b"
resources:
requests:
storage: 20Gi
Apply the manifest:
kubectl apply -f statefulset.yaml
Verify that the StatefulSet, Pods, and PVCs are all created:
kubectl get statefulset web
kubectl get pods -l app=nginx
kubectl get pvc -l app=nginx
Each Pod (web-0, web-1) gets its own PVC (disk-ssd-web-0, disk-ssd-web-1), each backed by an independently provisioned disk.