All Products
Search
Document Center

Container Service for Kubernetes:Use a static cloud disk persistent volume for persistent storage - FlexVolume

Last Updated:Mar 26, 2026

Statically provisioned disk volumes let you attach an existing Alibaba Cloud disk to a pod so that data survives pod restarts and rescheduling. Unlike dynamic provisioning, you create the persistent volume (PV) and persistent volume claim (PVC) yourself, then deploy an application that references the PVC.

Here is a summary of the process:

  1. As a cluster administrator, create a PV backed by an existing disk.

  2. Create a PVC that binds to the PV using a label selector.

  3. Deploy an application that mounts the PVC.

Prerequisites

Before you begin, ensure that you have:

Limitations

  • Each disk can be mounted to only one pod at a time.

  • A disk can only be mounted to a node in the same zone as the disk.

Use cases

Static disk provisioning is a good fit for:

  • Stateful workloads with high I/O requirements — databases such as MySQL and Redis that need dedicated block storage without data sharing.

  • High-speed log writes — applications that write log data at sustained high throughput.

  • Pod-independent data storage — data that must outlive any individual pod.

Create a PV

  1. Create a file named pv-static.yaml with the following content:

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: <your-disk-id>
      labels:
        alicloud-pvname: <your-disk-id>
        failure-domain.beta.kubernetes.io/zone: <your-zone>
        failure-domain.beta.kubernetes.io/region: <your-region>
    spec:
      capacity:
        storage: 20Gi
      accessModes:
        - ReadWriteOnce
      flexVolume:
        driver: "alicloud/disk"
        fsType: "ext4"
        options:
          volumeId: "<your-disk-id>"

    Replace the placeholders with your actual values:

    Field Description Required Example
    name (metadata) The name of the PV. Set to the disk ID. Yes <your-disk-id>
    alicloud-pvname Label used by the PVC selector to bind to this PV. Set to the disk ID. Yes <your-disk-id>
    failure-domain.beta.kubernetes.io/zone The zone where the disk is deployed. Required for multi-zone clusters to schedule pods to the correct zone. Yes (multi-zone clusters) cn-hangzhou-b
    failure-domain.beta.kubernetes.io/region The region where the disk is deployed. Required for multi-zone clusters. Yes (multi-zone clusters) cn-hangzhou
    capacity.storage Storage size. Yes 20Gi
    volumeId The ID of the existing disk to attach. Yes <your-disk-id>
    For clusters deployed across multiple zones, the failure-domain.beta.kubernetes.io/zone and failure-domain.beta.kubernetes.io/region labels ensure that pods are scheduled to the zone where the disk is located. See Mount a statically provisioned disk volume for details.
  2. Apply the manifest:

    kubectl create -f pv-static.yaml
  3. Verify that the PV was created: Log on to the ACK console. In the left-side navigation pane, click Clusters. On the Clusters page, find the cluster that you want to manage, and click the name of the cluster or click Details in the Actions column. In the left-side navigation pane of the details page, choose Volumes > Persistent Volumes. Verify that the newly created PV is displayed.

Create a PVC

  1. Create a file named pvc-static.yaml with the following content:

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: pvc-disk
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 20Gi
      selector:
        matchLabels:
          alicloud-pvname: <your-disk-id>

    Replace <your-disk-id> with the disk ID you used when creating the PV. The selector.matchLabels field binds this PVC to the PV with the matching alicloud-pvname label.

  2. Apply the manifest:

    kubectl create -f pvc-static.yaml
  3. Verify that the PVC was created: Log on to the ACK console. In the left-side navigation pane, click Clusters. On the Clusters page, find the cluster that you want to manage, and click the name of the cluster or click Details in the Actions column. In the left-side navigation pane of the details page, choose Volumes > Persistent Volume Claims. On the Persistent Volume Claims page, verify that the newly created PVC is displayed.

Deploy an application

  1. Create a file named static.yaml with the following content:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-static
      labels:
        app: nginx
    spec:
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx
            volumeMounts:
              - name: disk-pvc
                mountPath: "/data"
          volumes:
            - name: disk-pvc
              persistentVolumeClaim:
                claimName: pvc-disk

    The Deployment mounts the pvc-disk PVC to the /data path inside the container.

  2. Apply the manifest:

    kubectl create -f static.yaml
  3. Verify that the Deployment and pod are running:

    kubectl get pod | grep static

    Expected output:

    nginx-static-78c7dcb9d7-g****   2/2     Running     0          32s

    You can also verify in the ACK console: navigate to Workloads > Deployments and confirm that nginx-static is listed.

Verify data persistence

Run through the following steps to confirm that data written to the disk survives pod deletion and recreation.

  1. Confirm the disk is mounted to /data:

    kubectl exec nginx-static-78c7dcb9d7-g**** -- df | grep data

    Expected output:

    /dev/vdf        20511312    45080  20449848   1% /data
  2. List the files at /data:

    kubectl exec nginx-static-78c7dcb9d7-g**** -- ls /data

    Expected output:

    lost+found
  3. Create a test file:

    kubectl exec nginx-static-78c7dcb9d7-g**** -- touch /data/static
  4. Confirm the file exists:

    kubectl exec nginx-static-78c7dcb9d7-g**** -- ls /data

    Expected output:

    static
    lost+found
  5. Delete the pod to trigger recreation:

    kubectl delete pod nginx-static-78c7dcb9d7-g****

    Expected output:

    pod "nginx-static-78c7dcb9d7-g****" deleted

    In a separate terminal, watch the pod lifecycle:

    kubectl get pod -w -l app=nginx

    Expected output:

    NAME                            READY   STATUS            RESTARTS   AGE
    nginx-static-78c7dcb9d7-g****   2/2     Running           0          50s
    nginx-static-78c7dcb9d7-g****   2/2     Terminating       0          72s
    nginx-static-78c7dcb9d7-h****   0/2     Pending           0          0s
    nginx-static-78c7dcb9d7-h****   0/2     Pending           0          0s
    nginx-static-78c7dcb9d7-h****   0/2     Init:0/1          0          0s
    nginx-static-78c7dcb9d7-g****   0/2     Terminating       0          73s
    nginx-static-78c7dcb9d7-h****   0/2     Init:0/1          0          5s
    nginx-static-78c7dcb9d7-g****   0/2     Terminating       0          78s
    nginx-static-78c7dcb9d7-g****   0/2     Terminating       0          78s
    nginx-static-78c7dcb9d7-h****   0/2     PodInitializing   0          6s
    nginx-static-78c7dcb9d7-h****   2/2     Running           0          8s
  6. Get the name of the recreated pod:

    kubectl get pod

    Expected output:

    NAME                            READY   STATUS      RESTARTS   AGE
    nginx-static-78c7dcb9d7-h****   2/2     Running     0          14s
  7. Verify that the test file still exists in the recreated pod:

    kubectl exec nginx-static-78c7dcb9d7-h6brd -- ls /data

    Expected output:

    static
    lost+found

    The static file is present, confirming that data written to the disk persists across pod deletions and recreations.

What's next