The FlexVolume2CSI command-line interface (CLI) batch-converts YAML files for PersistentVolumes (PVs), PersistentVolumeClaims (PVCs), and workloads that use inline FlexVolume storage. Use it as part of migrating an ACK cluster from FlexVolume to Container Storage Interface (CSI).
FlexVolume2CSI lists volume and workload resources in your cluster, translates standard FlexVolume fields into the corresponding CSI format, and writes the converted YAML to an output file. It does not deploy the converted resources — you review and deploy them separately.
Scope: FlexVolume2CSI converts standard PersistentVolumes (PVs), PersistentVolumeClaims (PVCs), and workload inline volumes that use NAS, OSS, or Alibaba Cloud disk volumes only. It does not convert other storage types.
Verify the generated YAML file before deploying it to the cluster.
Prerequisites
Before you begin, make sure you have:
-
macOS or Linux (the CLI does not support Windows)
-
The cluster ID of the FlexVolume cluster
-
PVs, PVCs, or workloads that use NAS, OSS, or Alibaba Cloud disk volumes
Step 1: Install FlexVolume2CSI
-
Run the following command to install FlexVolume2CSI.
curl https://ack-csiplugin.oss-cn-hangzhou.aliyuncs.com/flexvolume2csi/get-translator.sh | bash -
Verify the installation.
flexvolume2csi versionExpected output:
flexvolume2csi: v2.0.0+f87c834 BuildDate: 2025-01-06T03:49:37Z GitCommit: f87c83459b8407668a04f7e7434cc51439c87508 GitTreeState: clean GoVersion: go1.23.3 Compiler: gc Platform: darwin/arm64
Step 2: Configure cluster access
Run the following command and follow the prompts to configure the target cluster.
flexvolume2csi configure
Expected output:
Configuring profile 'default' ...
Default Cluster Id (ClusterId of ACK Flexvolume Cluster) [c4869a2f603ca4e74****************]:
Default Kubeconfig Path (default is ~/.kube/config) []:
Saving profile[default] ...
Done.
| Parameter | Description |
|---|---|
| Cluster Id | The ID of the FlexVolume cluster. |
| Kubeconfig Path | The path to the kubeconfig file for the FlexVolume cluster. Defaults to ~/.kube/config. |
Step 3: Convert FlexVolume PVs and PVCs
Use flexvolume2csi translate to generate CSI YAML for PVs and PVCs.
FlexVolume PVCs and PVs cannot be converted in place using kubectl apply — you must redeploy them. If you need FlexVolume and CSI resources to coexist temporarily (using the csi-compatible-controller component), use -p or -s to avoid name conflicts.
Flags
Run flexvolume2csi translate help to see all available flags.
flexvolume2csi translate [-n namespace] [-c pvc] [-o outputfile] [-p prefix] [-s suffix] [-b backupfile] [-t storageclass]
| Flag | Description |
|---|---|
-o |
Path to the generated CSI YAML file. Defaults to ./outputfile.txt. Leave blank to print to stdout. |
-b |
Path to the backup YAML file for the original FlexVolume PVs and PVCs. Defaults to ./backupfile.txt. Leave blank to skip the backup. |
-n |
Namespace to process. Defaults to all namespaces. |
-c |
PVC name to process. Processes only the specified PVC and its corresponding PV. Must be used with -n. |
-p |
Prefix to add to generated CSI PV and PVC names. For example, -p csi renames pvc-test to csi-pvc-test. |
-s |
Suffix to add to generated CSI PV and PVC names. For example, -s csi renames pvc-test to pvc-test-csi. |
-t |
StorageClass name to apply to the generated CSI resources. |
Example
This example converts a FlexVolume NAS PV and PVC to CSI.
-
Create a
pv.yamlfile with the following content and apply it to the FlexVolume cluster.apiVersion: v1 kind: PersistentVolume metadata: name: pv-nas spec: capacity: storage: 5Gi storageClassName: nas accessModes: - ReadWriteMany flexVolume: driver: "alicloud/nas" options: server: "0cd8b4a576-u****.cn-hangzhou.nas.aliyuncs.com" # Replace with your NAS mount target address. path: "/k8s" vers: "3" options: "nolock,tcp,noresvport"kubectl apply -f pv.yaml -
Create a
pvc.yamlfile with the following content and apply it.apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-nas spec: accessModes: - ReadWriteMany storageClassName: nas resources: requests: storage: 5Gikubectl apply -f pvc.yaml -
Confirm that the PV and PVC are bound.
kubectl get pvc | grep pvc-nasExpected output:
pvc-nas Bound pv-nas 5Gi RWO nas 10s -
Convert all PVs and PVCs in the cluster. The
-s csiflag appends-csito the generated resource names to avoid conflicts.flexvolume2csi translate -s csi -
Review the generated CSI YAML.
cat ./outputfile.yamlExpected output:
--- apiVersion: v1 kind: PersistentVolume metadata: labels: alicloud-pvname: pv-nas-csi name: pv-nas-csi spec: accessModes: - ReadWriteMany capacity: storage: 5Gi csi: driver: nasplugin.csi.alibabacloud.com volumeAttributes: path: /k8s server: 0cd8b4a576-u****.cn-hangzhou.nas.aliyuncs.com volumeHandle: pv-nas-csi mountOptions: - nolock,tcp,noresvport - vers=3 persistentVolumeReclaimPolicy: Retain storageClassName: nas volumeMode: Filesystem --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-nas-csi namespace: default spec: accessModes: - ReadWriteMany resources: requests: storage: 5Gi selector: matchLabels: alicloud-pvname: pv-nas-csi storageClassName: nas volumeMode: Filesystem volumeName: pv-nas-csi
(Optional) Step 4: Convert workloads with inline FlexVolume volumes
Earlier versions of ACK managed clusters and ACK Serverless clusters support mounting FlexVolume storage directly to workloads in inline mode. If your cluster has such workloads, convert their YAML files separately using flexvolume2csi inline-translate.
The inline mount method does not use PVC or PV resources. For example:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nginx
spec:
serviceName: nginx
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
volumeMounts:
- name: test
mountPath: /data
ports:
- containerPort: 80
volumes:
- name: test
flexVolume:
driver: "alicloud/disk"
fsType: "ext4"
options:
volumeId: "d-bp1f3b5d0b0a8e7e6f****"
volumeClaimTemplates:
- metadata:
name: disk-ssd
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "alicloud-disk-ssd"
resources:
requests:
storage: 20Gi
The volume named test is the FlexVolume disk volume mounted in inline mode.
The volumeClaimTemplates field lets the controller dynamically create PVC and PV resources. Those generated resources can be converted using the procedure in Step 3. To recreate them as CSI resources, confirm that the data is no longer needed before deleting the resources, then delete the FlexVolume PVC and PV, and change storageClassName in volumeClaimTemplates to a CSI StorageClass.
Conversion targets
The conversion output depends on the volume type:
-
Disk volumes without a `volumeId`: converted to inline ephemeral volumes.
-
All other types: converted to CSI PV and PVC resources. The output file includes the PV, PVC, and the updated workload manifest.
Flags
Run flexvolume2csi inline-translate help to see all available flags.
flexvolume2csi inline-translate [-n namespace] [-k kind] [-i item] [-f inputfile] [-o outputfile] [-b backupfile] [-t storageclass] [-c capacity]
| Flag | Description |
|---|---|
-o |
Path to the generated CSI YAML file. Defaults to ./outputfile.txt. Leave blank to print to stdout. |
-b |
Path to the backup YAML file for the original FlexVolume workloads. Defaults to ./backupfile.txt. Leave blank to skip the backup. |
-n |
Namespace to process. Defaults to all namespaces. |
-k |
Workload kind to process (for example, sts or deploy). Defaults to all kinds. Pods are excluded unless you specify -k pod. |
-i |
Workload name to process. Must be used with -n and -k. |
-f |
Read workload resources from a local YAML file instead of listing from the cluster. Cannot be combined with -n, -k, or -i. |
-t |
StorageClass name to apply to the generated CSI resources. |
-c |
Storage capacity to set on the generated CSI resources. |
Example 1: Convert a disk volume without a volumeId to an ephemeral volume
-
Create and deploy the following workload in the FlexVolume cluster.
apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6 volumeMounts: - name: test mountPath: /data ports: - containerPort: 80 volumes: - name: test flexVolume: driver: "alicloud/disk" fsType: "ext4" options: volumeSize: "20" -
Convert the workload.
flexvolume2csi inline-translate -k deploy -n default -i nginx -
Review the generated CSI YAML.
cat ./outputfile.yamlExpected output:
--- apiVersion: apps/v1 kind: Deployment metadata: name: nginx namespace: default spec: progressDeadlineSeconds: 600 replicas: 1 revisionHistoryLimit: 10 selector: matchLabels: app: nginx strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate template: metadata: labels: app: nginx spec: containers: - image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6 imagePullPolicy: IfNotPresent name: nginx ports: - containerPort: 80 protocol: TCP resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /data name: test dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler securityContext: {} terminationGracePeriodSeconds: 30 volumes: - ephemeral: volumeClaimTemplate: metadata: spec: accessModes: - ReadWriteOnce resources: requests: storage: 20Gi name: test -
Before deploying, adjust the generated YAML as needed. For ephemeral volumes, specify a StorageClass:
volumes: - ephemeral: volumeClaimTemplate: metadata: spec: accessModes: - ReadWriteOnce resources: requests: storage: 20Gi storageClassName: ephemeral-diskAlternatively, pass
-tduring conversion to set the StorageClass for all resources:flexvolume2csi inline-translate -k deploy -n default -i nginx -t ephemeral-disk
Example 2: Convert other volume types to CSI PV and PVC resources
This example uses -f to convert a StatefulSet from a local file.
-
Save the StatefulSet YAML shown at the beginning of this step as
disk-static-sts.yaml. -
Convert the StatefulSet.
flexvolume2csi inline-translate -f disk-static-sts.yaml -
Review the generated CSI YAML.
cat ./outputfile.txtExpected output:
--- apiVersion: v1 kind: PersistentVolume metadata: name: d-bp1f3b5d0b0a8e7e6f**** spec: accessModes: - ReadWriteOnce claimRef: kind: PersistentVolumeClaim name: sts-nginx-test namespace: default csi: driver: diskplugin.csi.alibabacloud.com fsType: ext4 volumeAttributes: volumeId: d-bp1f3b5d0b0a8e7e6f**** volumeHandle: d-bp1f3b5d0b0a8e7e6f**** persistentVolumeReclaimPolicy: Delete --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: sts-nginx-test namespace: default spec: accessModes: - ReadWriteOnce resources: {} volumeName: d-bp1f3b5d0b0a8e7e6f**** --- apiVersion: apps/v1 kind: StatefulSet metadata: name: nginx namespace: default spec: replicas: 1 selector: matchLabels: app: nginx serviceName: nginx template: metadata: labels: app: nginx spec: containers: - image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6 name: nginx ports: - containerPort: 80 resources: {} volumeMounts: - mountPath: /data name: test volumes: - name: test persistentVolumeClaim: claimName: sts-nginx-test updateStrategy: {} volumeClaimTemplates: - metadata: name: disk-ssd spec: accessModes: [ "ReadWriteOnce" ] storageClassName: "alicloud-disk-ssd" resources: requests: storage: 20GiThe inline FlexVolume volume is converted to a CSI PVC and PV. The StatefulSet now references the PVC instead of the inline volume. The
volumeClaimTemplatessection is not modified. -
Before deploying, adjust the generated YAML as needed. For CSI disk volumes, two fields are typically missing from the generated output:
-
Storage capacity: declare the required capacity on the PVC and PV. For example, set
capacity.storage: 20Gion the PV andresources.requests.storage: 20Gion the PVC. -
StorageClass in volumeClaimTemplates: change
storageClassNameto a CSI StorageClass.
After adjustment:
--- apiVersion: v1 kind: PersistentVolume metadata: name: d-bp1f3b5d0b0a8e7e6f**** spec: accessModes: - ReadWriteOnce capacity: storage: 20Gi claimRef: kind: PersistentVolumeClaim name: sts-nginx-test namespace: default csi: driver: diskplugin.csi.alibabacloud.com fsType: ext4 volumeAttributes: volumeId: d-bp1f3b5d0b0a8e7e6f**** volumeHandle: d-bp1f3b5d0b0a8e7e6f**** persistentVolumeReclaimPolicy: Delete --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: sts-nginx-test namespace: default spec: accessModes: - ReadWriteOnce resources: requests: storage: 20Gi volumeName: d-bp1f3b5d0b0a8e7e6f****Alternatively, pass
-tand-cduring conversion to set the StorageClass and capacity for all resources:flexvolume2csi inline-translate -f disk-static-sts.yaml -t <csi-storageclass> -c "20Gi" -
Step 5: Deploy the generated CSI YAML
After verifying the generated YAML, deploy it to the cluster. FlexVolume2CSI only generates YAML files — it does not deploy them. Use kubectl create -f instead of kubectl apply -f to avoid resource name conflicts.
For the complete migration process, see the scenario guides in Migrate from FlexVolume to CSI.