All Products
Search
Document Center

Container Service for Kubernetes:Use CPFS for Lingjun dynamic volumes

Last Updated:Jul 16, 2026

Use dynamic volumes to provision CPFS for Lingjun storage on demand without manually managing PVs. Multiple applications can read and write in parallel, which suits AI training and big data analytics workloads that need to share code, configuration files, and intermediate computation results.

Limitations

Violating these constraints causes mount failures or unrecoverable cluster state.

  • Same hpn-zone required for VSC mounting: The pod's node must be in the same hpn-zone as the CPFS for Lingjun file system.

  • Node initialization: A Lingjun node must be associated with a CPFS for Lingjun file system at initialization. Skipping this causes CSI mount failures.

  • One file system per pod: Do not mount multiple volumes from the same CPFS for Lingjun file system in one pod (e.g., multiple PVs with the same bmcpfsId). The native protocol does not support mounting the same file system multiple times in a pod, even to different subdirectories.

  • Drain before taking a node offline: Drain all pods from a failing Lingjun node before taking it offline. Skipping this leaves unrecoverable pod resources and inconsistent cluster metadata.

Prerequisites

Make sure you have:

  • Cluster version 1.26 or later (upgrade guide).

  • Nodes running Alibaba Cloud Linux 3.

  • The following storage add-ons at their minimum versions. Install or upgrade on the Add-ons page.

    Component

    Minimum version

    CSI add-on (csi-plugin and csi-provisioner)

    v1.33.1

    cnfs-nas-daemon add-on

    0.1.2

    bmcpfs-csi add-on (bmcpfs-csi-controller on the ACK-managed control plane and bmcpfs-csi-node deployed as a DaemonSet on cluster nodes)

    1.35.1

Configure cnfs-nas-daemon resources

cnfs-nas-daemon manages Elastic File Client (EFC) processes and directly affects storage performance. Configure its resources on the Add-ons page:

  • CPU: 0.5 core per 1 Gb/s of bandwidth, plus 1 core for metadata management. Example: 100 Gb/s NIC → 100 × 0.5 + 1 = 51 cores.

  • Memory: 15% of the node's total memory. CPFS for Lingjun uses FUSE, so data caching and file metadata both consume memory.

Fine-tune resource limits based on actual workload.

Important

cnfs-nas-daemon uses the OnDelete update strategy. After changing settings on the Add-ons page, manually delete the cnfs-nas-daemon pod on each node to apply changes. Do this during off-peak hours.

  • Nodes without hot upgrade support: Causes a hardware interrupt. Application pods fail and must be manually deleted, then restart and recover automatically.

  • Nodes with hot upgrade support: Pods recover automatically. Hot upgrade requires: kernel 5.10.134-18+, bmcpfs-csi-controller and bmcpfs-csi-plugin 1.35.1+, and cnfs-nas-daemon 0.1.9-compatible.1+.

Step 1: Create a CPFS file system

  1. Create a CPFS for Lingjun file system and record the file system ID.

  2. (Optional) To mount on non-Lingjun nodes, create a VPC mount target in the same VPC as your cluster nodes. Record the mount target domain name (format: cpfs-*-vpc-*.<Region>.cpfs.aliyuncs.com).

    If all pods run on Lingjun nodes, VSC (Virtual Storage Controller) mounting applies by default. Skip this step.

Review CPFS for Lingjun limits before proceeding.

Step 2: Create a StorageClass

The StorageClass defines provisioning parameters such as the file system ID and reclaim policy.

  1. Create sc.yaml:

    Parameter

    Required

    Description

    bmcpfsId

    Yes

    CPFS for Lingjun file system ID. Format: bmcpfs-xxxxxxxxx or cpfs-xxxxxxxxx.

    path

    No

    Subdirectory within the file system. Volume mounts at {path}/{volumeName}/. Defaults to /{volumeName}/.

    allowVolumeExpansion

    No

    Reserved parameter. The current version does not support dynamic expansion.

    reclaimPolicy

    No

    Delete (default): deletes the backend fileset when the PVC is deleted. Retain: keeps the fileset; requires manual cleanup. Use Retain in production.

    allowVolumeExpansion: true
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: alicloud-bmcpfs-test
    parameters:
      bmcpfsId: bmcpfs-xxxxxx
      vpcMountTarget: cpfs-xxxxx-vpc-xxxxx.cn-hangzhou.cpfs.aliyuncs.com
    provisioner: bmcpfsplugin.csi.alibabacloud.com
    reclaimPolicy: Delete
    volumeBindingMode: Immediate
  2. Apply the StorageClass:

    kubectl apply -f sc.yaml

    Expected output:

    storageclass.storage.k8s.io/alicloud-bmcpfs-test created

Step 3: Create a PVC

A PVC references the StorageClass to request dynamically provisioned storage.

  1. Create pvc.yaml:

    Parameter

    Description

    accessModes

    ReadWriteMany only. Allows concurrent multi-pod access.

    storage

    Requested storage capacity. Supports units such as Gi and Ti.

    volumeMode

    Only Filesystem is supported.

    storageClassName

    StorageClass name. Triggers dynamic volume creation.

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: bmcpfs-vsc
      namespace: default
    spec:
      accessModes:
        - ReadWriteMany  # Supports concurrent reads and writes across multiple pods
      resources:
        requests:
          storage: 10Ti  # Supports large-capacity storage (Ti level)
      volumeMode: Filesystem  # Only Filesystem is supported
      storageClassName: alicloud-bmcpfs-test  # Must match the StorageClass created in Step 2
  2. Apply the PVC:

    kubectl apply -f pvc.yaml
  3. Verify the PVC is bound:

    kubectl get pvc bmcpfs-vsc -n default

    Expected output:

    NAME         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS           AGE
    bmcpfs-vsc   Bound    pvc-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx   10Ti       RWX            alicloud-bmcpfs-test   30s

    When STATUS is Bound, the PV is automatically created. Confirm provisioning:

    kubectl describe pvc bmcpfs-vsc -n default

    Check Events for a Provisioning succeeded message.

Step 4: Deploy a workload and mount the PVC

The following Deployment runs three replicas sharing a single CPFS for Lingjun volume.

  1. Create deploy.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: cpfs-shared-example
    spec:
      replicas: 3  # Three replicas verify that shared storage works across multiple pods
      selector:
        matchLabels:
          app: cpfs-shared-app
      template:
        metadata:
          labels:
            app: cpfs-shared-app
        spec:
          tolerations:
            - key: node-role.alibabacloud.com/lingjun
              operator: Exists
              effect: NoSchedule
          # Optional: to pin all pods to a specific node, uncomment and set the node name
          # nodeName: cn-hangzhou.10.XX.XX.226
          containers:
          - name: app-container
            image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
            volumeMounts:
              - name: pvc-cpfs
                mountPath: /data  # Shared volume mounted at /data inside the container
            lifecycle:
              postStart:
                exec:
                  command:
                    - /bin/sh
                    - -c
                    - >
                      echo "Data written by $(hostname)" > /data/$(hostname).txt &&
                      echo "Deployment is running, check shared data in /data." &&
                      sleep 3600
          volumes:
            - name: pvc-cpfs
              persistentVolumeClaim:
                claimName: bmcpfs-vsc  # References the PVC created in Step 3
  2. Apply the Deployment:

    kubectl apply -f deploy.yaml

    Expected output:

    deployment.apps/cpfs-shared-example created

Clean up resources

Delete resources in this order to avoid unexpected costs and preserve data safety.

  1. Delete workloads — Stop all applications using the PVCs. This unmounts the volumes.

    kubectl delete deployment <your-deployment-name>
  2. Delete PVCs — The outcome depends on the reclaimPolicy of the StorageClass:

    • Retain (recommended): The CPFS for Lingjun fileset and data remain intact. Proceed to Step 3 to delete the PV.

    • Delete: Permanently deletes the bound PV and backend fileset. Irreversible.

    kubectl delete pvc <your-pvc-name>
  3. Delete PVs (only when reclaimPolicy is Retain) — After PVC deletion, the PV enters Released status. Delete it to remove the Kubernetes resource. Backend data is unaffected.

    kubectl delete pv <your-pv-name>
  4. (Optional) Delete the StorageClass — Delete if no longer needed. Existing volumes are unaffected.

    kubectl delete sc <your-sc-name>
  5. Delete the CPFS for Lingjun file system — Permanently deletes all data, including data retained by the Retain policy. Confirm no dependencies remain, then delete the file system.

Troubleshooting

PVC stays in Pending status

A PVC stuck in Pending means provisioning failed. PVC events usually identify the cause.

kubectl describe pvc <your-pvc-name> -n <your-namespace>

Check Events for warnings. Common causes:

  • StorageClass not found: storageClassName is incorrect or the StorageClass does not exist.

  • provisioning failed or failed to create fileset: Backend storage issue. Continue below.

If events indicate a configuration issue, inspect the StorageClass and verify CSI driver registration:

# Check the StorageClass configuration
kubectl get storageclass <your-sc-name> -o yaml

# Verify the CSI driver is registered
kubectl get csidriver bmcpfsplugin.csi.alibabacloud.com

Confirm that:

  • provisioner matches bmcpfsplugin.csi.alibabacloud.com.

  • bmcpfsId is correct and the file system exists.

  • If get csidriver returns no output, the driver is not installed. Install bmcpfs-csi-controller, bmcpfs-csi-node, and cnfs-nas-daemon from the Add-ons page.

Pod stays in ContainerCreating or MountVolume.Setup failed

The pod reached the node but volume mount failed. Follow these steps to identify the cause.

  1. Check pod events:

    kubectl describe pod <pod-name> -n <your-namespace>

    Check Events for Warning messages such as FailedMount or MountVolume.Setup failed.

  2. Confirm the PVC is bound.

    kubectl get pvc <your-pvc-name>

    STATUS must be Bound. If Pending, see PVC stays in Pending status.

  3. If bound, check node-side CSI plugin logs:

    kubectl get pods -n kube-system -l app.kubernetes.io/name=bmcpfs-csi-driver \
      --field-selector spec.nodeName=<nodeName> \
      -o name | xargs kubectl logs -n kube-system -c csi-plugin

    These logs show network connectivity, mount target permission, and I/O errors.