Before starting tasks such as AI training or data analytics, prefetch large volumes of cold data stored in Object Storage Service (OSS) on demand into high-performance storage volumes—such as CPFS for Lingjun or cloud disks. Compute tasks can then read data directly from these high-performance volumes at high speed. After the task completes, the storage volume is automatically reclaimed, balancing compute acceleration with cost optimization.
How it works
Feature implementation
This feature uses Kubernetes Volume Populators and is managed by ACK's storage-operator. When you create a persistent volume claim (PVC) that references the custom resource OSSVolumePopulator (OSSVP), storage-operator intercepts the request and performs the data population operation.
Depending on the target volume type, population occurs in one of the following modes.
Mode | Supported storage types | Description |
| CPFS for Lingjun | storage-operator leverages CPFS's native data flow capability to populate data. This mode does not consume cluster compute resources and offers higher efficiency. |
| Other storage types, such as cloud disks or CPFS general-purpose edition | storage-operator creates a temporary pod in the This mode consumes cluster compute resources. |
After successful data population, the PVC status changes from Pending to Bound. At this point, application pods can mount the PVC and access the prefetched data.
Typical scenarios
This feature supports two primary use cases.
Dimension | Scenario 1: Prefetch data to CPFS for Lingjun shared volumes | |
Applicable scenario | High-throughput, read-intensive workloads such as AI model training and inference, designed to overcome OSS access performance bottlenecks. | Parallel batch processing or data pipeline tasks requiring isolated, read-write workspaces, designed to resolve concurrency conflicts and ensure data isolation. |
Technical implementation | Use CPFS for Lingjun with the | Use any dynamically provisioned storage such as cloud disks with the |
Key characteristics |
|
|
Workflow
The core steps for using VolumePopulator are similar across both modes.
|
Preparations
Ensure your cluster runs Kubernetes 1.26 or later and uses the CSI plugin. This feature relies on dynamically provisioned volumes and only supports dynamically provisioned storage.
To upgrade your cluster, see Manually upgrade a cluster. To migrate from FlexVolume to CSI, see Migrate FlexVolume to CSI using csi-compatible-controller.
Upgrade storage-operator to v1.35.1 or later and enable the
VolumePopulatorFeature Gate.If other feature gates are already enabled, use the format:
xxxxxx=true,yyyyyy=false,VolumePopulator=true
Scenario 1: Prefetch data to CPFS for Lingjun shared volumes
This solution targets read-only, high-throughput scenarios like model training and inference. It leverages CPFS for Lingjun's data flow capability to prefetch models from OSS into CPFS for Lingjun volumes on demand, enabling multiple GPU tasks to read data at high speed.
Preparations
Complete the preparations for using CPFS for Lingjun dynamic volumes.
Review the CPFS for Lingjun data flow (invitational preview) documentation for feature details and limits.
ImportantCPFS for Lingjun data flow is in invitational preview. Performance may fluctuate in large-scale clusters. If you encounter issues or have product suggestions, join DingTalk group 35532895 to contact us.
1. Set a specific tag on the OSS bucket
Follow the instructions in Object tagging operations to add a tag to your OSS bucket with key cpfs-dataflow and value true.
Do not delete or modify this tag during use, as it may cause volume creation to fail.
2. Create OSSVolumePopulator (OSSVP)
Create an OSSVolumePopulator resource in the same namespace as your application and PVC to define the OSS data source.
apiVersion: storage.alibabacloud.com/v1beta1
kind: OSSVolumePopulator
metadata:
name: qwen3-32b
# Must be in the same namespace as the application and PVC
namespace: bmcpfs-dataflow-demo
spec:
bucket: <your-bucket-name>
region: cn-hangzhou
endpoint: oss-cn-hangzhou-internal.aliyuncs.com
path: /Qwen3-32B/
# Dedicated for CPFS for Lingjun volumes, leveraging its data flow capability
mode: bmcpfs-dataflow
# Optional advanced configurations for bmcpfs-dataflow mode
# This example recommends default settings. Ignore if no special requirements.
# bmcpfsDataflow:
# Maximum data flow throughput (MB/s). Options: 600, 1200, 1500. Default: 600
# throughput: 1200
# Enable encrypted transfer. Default: empty (disabled)
# sourceSecurityType: SSL
# Data prefill mode. Default: metadataAndData for full prefill.
# Set to metadata for metadata-only prefill.
# dataType: metadataAndDataParameter descriptions:
Name | Description | Optional | Default |
| OSSVolumePopulator must reside in the same namespace as the application and PVC. | No | N/A |
| OSS bucket name. | No | N/A |
| OSS region. | No | N/A |
| OSS service endpoint address. | No | N/A |
| Path prefix within the OSS bucket, such as | Yes |
|
| Operation mode. Options:
| Yes |
|
| Maximum CPFS for Lingjun data flow throughput (MB/s). Options: | Yes | Same as CPFS for Lingjun data flow default |
| Data transfer security protocol type, such as | Yes | Encryption disabled |
| Specify data type to sync:
| Yes |
|
3. Prepare StorageClass and PVC
Create a StorageClass that references CPFS for Lingjun, then create a PVC and reference the previously created OSSVP using dataSourceRef.
Create StorageClass | Each dynamic volume created through this StorageClass automatically creates a Fileset on the backend CPFS for Lingjun. By creating different OSSVP resources, you can prefill different OSS datasets into different dynamic volumes using the same StorageClass. |
Create PVC | Because the StorageClass sets |
4. Verify data prefill status
Check data flow progress: During population, the PVC status remains Pending and changes to Bound after completion.
For bmcpfs-dataflow mode, you can also check real-time CPFS for Lingjun data flow progress using the following command.
kubectl -n bmcpfs-dataflow-demo describe ossvp qwen3-32bstatusduring population:Bmcpfs Dataflow: 62a4e7ec-fae1-4f11-848f-b57cxxxxxxxx: Data Flow Id: df-29d3ad9e9xxxxxxx Data Flow Task Id: task-2993179xxxxxxxxx File Set Id: fset-2997498xxxxxxxxx File System Id: bmcpfs-29000z8xz3lf5xxxxxxxx Progress: 59%statusafter completion:Message: Populated successfully
5. Create workload and use data
After the PVC becomes Bound, create a workload that mounts this PVC.
This example uses GPU resources. For verification only, create a CPU pod and use kubectl exec to log into the container and inspect the data.
Resource cleanup guide
After completing AI training or inference tasks, promptly release the CPFS for Lingjun shared volumes and related workloads created for them.
Resources to release:
Workloads using the shared volume (in this example, a
StatefulSet)PVC used for data prefilling
Backend storage resources (CPFS for Lingjun FileSet) automatically created by the PVC
Cleanup procedure:
Delete the workload
Delete the StatefulSet using the volume to release the PVC.
kubectl delete statefulset demo-apply-qwen3-32b -n bmcpfs-dataflow-demoDelete the PVC
Because the StorageClass sets
reclaimPolicy: Delete, this action automatically triggers deletion of the backend CPFS FileSet, releasing storage space and stopping billing.kubectl delete pvc qwen3-32b -n bmcpfs-dataflow-demoVerify resource cleanup:
Verify CPFS for Lingjun file system: Go to the NAS console, select File System > File System List, and confirm the FileSet associated with this PVC has been deleted and the file system's used capacity has decreased.
Verify OSS source data: This operation does not affect OSS source data. To verify, go to the OSS console and confirm the dataset remains intact.
Scenario 2: Prefetch data to isolated cloud disk volumes
This solution applies to batch processing workflows. Using Argo Workflows, it dynamically creates and preheats an independent cloud disk for each task, achieving data isolation and elasticity.
Preparations
Enable
VolumePopulatorPodHandlerin storage-operator.After enabling, the system automatically grants necessary RBAC permissions to related components and temporary pods. Evaluate potential security risks before enabling.
Argo Workflows is installed.
This example uses serverless compute (ECI) to run data prefilling tasks and workflows, so you must also install the ack-virtual-node component. If you use non-serverless compute for verification, remove the related label
alibabacloud.com/eci: "true"from resources.
1. Authorize data prefilling tasks to access OSS
In generic mode, data prefilling tasks run as temporary pods in the ack-volume-populator namespace. You must grant these pods permission to access the OSS bucket containing the source data.
RRSA method: Dynamically assign temporary, auto-rotating RAM roles to pods for fine-grained, application-level permission isolation with higher security.
AccessKey method: Store static, long-term credentials in a Secret. Simple to configure but less secure.
RRSA method
1. Enable RRSA in your cluster
Log on to the ACK console. In the left-side navigation pane, click Clusters.
On the Clusters page, find the target cluster and click its name. In the left-side pane, click Cluster Information.
On the Basic Information tab, find the Security and Auditing section. To the right of RRSA OIDC, click Enable. Follow the on-screen prompts to enable RRSA during off-peak hours.
When the cluster status changes from Updating to Running, RRSA is enabled.
After you enable RRSA, the maximum validity period for new ServiceAccount tokens created in the cluster is limited to 12 hours.
2. Create a RAM role and grant permissions
Create a RAM role for pods to assume, enabling OSS access through RRSA authentication.
AccessKey method
Create a RAM user (skip this step if you already have one). Go to the Create User page in the RAM console. Follow the on-screen instructions to create a RAM user. Set a logon name and password.
Create a permission policy.
Following the principle of least privilege, create a custom policy granting access to the target OSS bucket (OSS read-only or read-write permissions).
Go to the RAM console - Create Policy page, switch to JSON Editor, and configure the policy script as instructed.
Grant the policy to the RAM user.
Go to the Users page in the RAM console. In the Actions column for the target user, click Attach Policy.
In the Access Policy section, search for and select the policy you created, and add the permissions.
Create an AccessKey for the RAM user to store as a Secret for data prefilling.
Go to the RAM console - Users page, click the target user in the RAM user list, then in the AccessKey tab, click Create AccessKey.
Follow the instructions to create the AccessKey in the dialog box and securely store the AccessKey ID and AccessKey Secret.
Create a Secret in the cluster.
Use the following YAML to create a Secret in the
ack-volume-populatornamespace to store the AccessKey.apiVersion: v1 kind: Secret metadata: name: oss-secret # The namespace must be set to ack-volume-populator namespace: ack-volume-populator stringData: # Replace with the previously obtained AccessKey ID accessKeyId: <your-AccessKey-ID> # Replace with the previously obtained AccessKey Secret accessKeySecret: <your-AccessKey-Secret>
2. Create OSSVolumePopulator (OSSVP)
Create an OSSVolumePopulator resource in the same namespace as your application and PVC to define the data source and specify mode as generic along with the authorization method.
apiVersion: storage.alibabacloud.com/v1beta1
kind: OSSVolumePopulator
metadata:
name: generic-demo
# Must be in the same namespace as the application and PVC
namespace: argo
spec:
bucket: my-test-bucket
region: cn-hangzhou
endpoint: oss-cn-hangzhou-internal.aliyuncs.com
path: /many-files/
# Generic mode for any backend storage volume
mode: generic
generic:
# Add labels to data population task pods for scheduling to ECI pods
labels:
alibabacloud.com/eci: "true"
# Add annotations to data population task pods for configuring ECI specs
annotations:
k8s.aliyun.com/eci-use-specs: "2-4Gi"
# Choose either secretRef or rrsaConfigs
# secretRef: oss-secret
rrsaConfigs:
# ARN of the RAM role used for RRSA authorization
roleArn: "acs:ram::1234567*****:role/oss-populator"
# ARN of the cluster's OIDC Provider
oidcProviderArn: "acs:ram::1234567*****:oidc-provider/my-oidc-provider"
# Configure affinity for data population task pods to schedule to specific nodes
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: "disktype"
operator: NotIn
values:
- "hdd"
# Configure tolerations for data population task pods
tolerations:
- key: "virtual-kubelet.io/provider"
operator: Equal
value: "alibabacloud"
effect: NoSchedule
# Maximum throughput (MB/s)
# throughput: 1000Parameter descriptions:
Name | Description | Optional | Default |
| OSSVolumePopulator must reside in the same namespace as the application and PVC. | No | N/A |
| OSS bucket name. | No | N/A |
| OSS region. | No | N/A |
| OSS service endpoint address. | No | N/A |
| Path prefix within the OSS bucket, such as | Yes |
|
| Operation mode. Options:
| Yes |
|
| Add labels to data population task pods for scheduling to ECI. | Yes | N/A |
| Add annotations to data population task pods for configuring ECI specs. | Yes | N/A |
| Name of the Secret storing the AccessKey. Choose either this or | Yes | N/A |
| ARN of the RAM role used for RRSA authorization. Go to the RAM console - Roles page, click the RAM role name, and get it from the details page. | Required when using RRSA | N/A |
| ARN of the cluster's OIDC Provider. Go to the ACK clusters page, click the target cluster name, select Cluster Information, and get it from the Basic Information tab under RRSA OIDC. | Required when using RRSA | N/A |
| Configure affinity for data population task pods to schedule to specific nodes. | Yes | N/A |
| Configure tolerations for data population task pods. | Yes | N/A |
| Maximum throughput (MB/s) to set the maximum download speed for data population task pods. Unlike | Yes | Unlimited (actual rate depends on node network, CPU, and storage write performance) |
3. Prepare StorageClass
This scenario requires a StorageClass for dynamically provisioning cloud disks. ACK provides a default StorageClass and also supports manually creating a StorageClass.
This example uses
alicloud-disk-essd, which hasreclaimPolicyset toDeleteandvolumeBindingModeset toImmediate, suitable for scenarios using serverless compute where zone awareness isn't required.If you run workflows on non-serverless compute, use a StorageClass with
volumeBindingModeset toWaitForFirstConsumer(such asalicloud-disk-topology-alltype) to ensure cloud disks and application pods are created in the same zone, avoiding scheduling failures due to zone mismatches.
4. Create Argo Workflow
The following Workflow example uses an ephemeral volumeClaimTemplate to dynamically create an independent cloud disk with prefilled initial data for each parallel task.
After creating the Workflow, check logs from any task pod to confirm successful reading of prefilled data.
In production environments, you can also use Argo Workflows' Artifact feature to persist final computation results in OSS.
# Replace <your-workflow-pod-name> with the actual pod name
kubectl -n argo logs <your-workflow-pod-name>Expected output:
Subtask started, ID: 1
Creating a new log file...
Listing contents from the disk populated by OSSVP:
1-logs
lost+found
results-2025-04-16T07:48:00Z
...
Subtask completed, ID: 1Result analysis:
1-logs: File newly written by the task, verifying the volume is read-write capable and storage is isolated between parallel tasks.results-2025-04-16T07:48:00Zand similar files: Data prefilled from OSS to the cloud disk, confirming the prefilling feature works correctly.lost+found: Directory automatically generated after file system formatting. Ignore it.
Resource cleanup guide
After completing batch processing tasks, promptly release the isolated cloud disk volumes and related workflows dynamically created by Argo Workflow.
Resources to release:
Argo Workflow instance
Temporary PVCs automatically created by the Workflow
Backend storage resources (cloud disks) automatically created by the PVCs.
Release flow:
Delete the Argo Workflow:
For this scenario, typically just delete the
Workflowresource. Because the workflow usesephemeralvolume claims, deleting the Workflow automatically cascades deletion of all PVCs it created. TheStorageClasssetsreclaimPolicy: Delete, which further triggers automatic deletion of backend cloud disks, releasing resources and stopping billing.# Replace <workflow-name> with the actual Workflow name kubectl -n argo delete workflow <workflow-name>Verify resource cleanup:
Verify PVCs: Run
kubectl -n argo get pvcto confirm all PVCs related to this workflow have been deleted.Verify cloud disk resources: Go to ECS console - Block Storage - Disks and confirm no cloud disk resources remain from this workflow.
Verify OSS source data: This operation does not affect OSS source data. To verify, go to the OSS console and confirm the dataset remains intact.
Production environment recommendations
Cost and resource management:
Set automatic resource reclamation: Configure
reclaimPolicy: Deletefor the StorageClass used to dynamically create volumes. This ensures high-performance storage resources are automatically cleaned up after task completion.Optimize data population costs (
genericmode): Ingenericmode, data population consumes compute resources. By configuringaffinityandtolerationsinOSSVolumePopulator, you can schedule temporary task pods to lower-cost serverless compute (including ACS, ECI) or spot instances.Plan storage capacity: The
storagecapacity requested when creating a PVC must exceed the source data size. Otherwise, data population fails due to insufficient space.
Performance and stability:
Cloud disk zone alignment: Cloud disks are zone-scoped resources. When using ECS nodes, set the
StorageClassvolumeBindingModetoWaitForFirstConsumerto ensure cloud disks and application pods are always created in the same zone, avoiding mount failures from cross-zone scheduling.Balance CPFS for Lingjun prefill modes: If you prioritize quick Persistent Volume (PV) readiness and can tolerate some latency on first file reads, choose
dataType: metadata. If your workload requires high first-read performance and full data prefilling, choosedataType: metadataAndData.Status monitoring: Use
kubectl describe ossvp <name>to monitor data prefill task status and events for quick troubleshooting.
Security and permissions:
Use RRSA for secure authorization: In
genericmode, when granting OSS access permissions to data population task pods, prefer the RRSA method to avoid security risks from AccessKey leakage.
Billing information
This feature involves the following charges:
High-performance storage fees: Charged based on the created volume type (such as CPFS for Lingjun or cloud disks) and their lifecycle.
OSS storage fees: Storage fees for source data in OSS.
Data transfer fees: Configure the OSS internal endpoint in OSSVP to avoid traffic charges. Using the public endpoint incurs traffic fees.
Compute resource fees (only for
genericmode): Temporary pods ingenericmode consume cluster compute resources (CPU, memory, bandwidth) and are billed based on specifications and duration.For CPFS for Lingjun in
bmcpfs-dataflowmode, data stream tasks are free to use because the data stream feature is in public preview.
FAQ
After prefilling completes, if I update source files in OSS, will the data in the volume sync automatically?
No. Data prefilling is a one-time operation during volume creation. Once the volume is created and populated, its contents are decoupled from the OSS source data. Any subsequent changes to OSS will not sync to the created volume.
Why does my PVC stay in Pending status?
Pending is normal during data prefilling. If it remains Pending for an extended period, troubleshoot as follows.
kubectl describe pvc <pvc-name> -n <namespace>: Check PVC events for populator-related error messages.kubectl describe ossvp <ossvp-name> -n <namespace>: Check OSSVP status and events for population task status, progress, or failure reasons.If using
genericmode, check for failed pods in theack-volume-populatornamespace and review their logs. Common causes include insufficient OSS permissions, network issues, or insufficient storage space.