ACK allows you to mount a General-purpose CPFS file system as a dynamic volume by using CNFS. After you configure a StorageClass, each workload automatically obtains an independent, data-isolated persistent volume (PV), eliminating the need for manual storage management.
Workflow
When you use dynamic volumes, the system automatically provisions a persistent volume (PV) based on the specified StorageClass after your application creates a persistent volume claim (PVC). This method eliminates pre-provisioning and supports automatic volume expansion.
The following figure shows the workflow for mounting a CPFS dynamic volume in a cluster.
|
Prerequisites
Ensure your components meet the version requirements.
To upgrade your cluster, see Upgrade an ACK cluster.
1.26 and later
Ensure the CSI component version is v1.32.2-757e24b-aliyun or later.
To upgrade the CSI component, see Manage CSI components.
The cnfs-nas-daemon component is installed, and you have added
AlinasMountProxy=trueto the FeatureGate of the csi-plugin component to enable cnfs-nas-daemon. For more information, see Manage the cnfs-nas-daemon component.
Earlier than 1.26
Ensure the CSI component version is v1.24.11-5221f79-aliyun or later.
To upgrade the CSI component, see Manage CSI components.
Install the client dependencies and restart the csi-plugin component.
You have created a General-purpose CPFS file system and its corresponding protocol service in the same VPC as the cluster and obtained the mount target address. For more information, see Create a protocol service and obtain a mount target address.
For optimal performance, place the CPFS protocol service mount target and the cluster in the same vSwitch.
Limits
The CPFS general-purpose edition is available only in select regions. For more information, see Available regions for the CPFS general-purpose edition.
CPFS file systems can be mounted only to clusters within the same VPC.
For more information about the limits of CPFS, see Limits.
Step 1: Create a CNFS object
Create a CNFS object to register the existing CPFS file system with your cluster.
Create a file named
cnfs.yamlby using the following template.apiVersion: storage.alibabacloud.com/v1beta1 kind: ContainerNetworkFileSystem metadata: name: cnfs-nfs-cpfs spec: # Specify the backend storage type as CPFS. type: cpfs # Deleting this CNFS object does not delete the backend CPFS file system. reclaimPolicy: Retain parameters: # The domain name of the mount target for the CPFS protocol service. protocolServer: cpfs-xxxx.xxxx.cpfs.aliyuncs.com # Use the NFS client to mount the volume. useClient: NFSClientParameters:
Parameter
Description
spec.typeThe backend storage type. Set this to
cpfs.spec.reclaimPolicyThe reclaim policy. Only
Retainis supported. This setting prevents the backend CPFS file system from being deleted when the CNFS object is deleted.spec.parameters.protocolServerThe mount target domain of the protocol service for the General-purpose CPFS file system.
spec.parameters.useClientSet this to
NFSClientto use the NFS client for mounting.Create the CNFS object.
kubectl apply -f cnfs.yamlCheck the status of the CNFS object and confirm it is
Available.kubectl get cnfs cnfs-nfs-cpfs -o jsonpath='{.status.status}'
Step 2: Create a StorageClass
Create a StorageClass to serve as a template for dynamic provisioning and to reference the CNFS object you created.
Create a file named
sc.yamlby using the following template.apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: cnfs-nfs-cpfs-sc # Mount options. mountOptions: - nolock,tcp,noresvport - vers=3 parameters: # Create a subdirectory-based PV. volumeAs: subpath # Reference the CNFS object created earlier. containerNetworkFileSystem: "cnfs-nfs-cpfs" # The export path of the General-purpose CPFS protocol service. path: "/share" # Data handling policy when a PVC is deleted. `true` archives data instead of deleting it. archiveOnDelete: "true" provisioner: nasplugin.csi.alibabacloud.com # PV reclaim policy. Only Retain is supported in this example. reclaimPolicy: Retain # Allow volume expansion. allowVolumeExpansion: trueParameters:
Parameter
Description
mountOptionsThe mount options. You can use the default values shown in the example.
parameters.volumeAssubpath: Subpath mode. Each PV corresponds to an independent subdirectory on the CPFS file system, providing data isolation.sharepath: Sharepath mode. All PVs created from this StorageClass share the same directory on the CPFS file system.
parameters.containerNetworkFileSystemThe CNFS object to reference.
parameters.pathThe export path of the General-purpose CPFS protocol service, such as
/share. You can also specify a subdirectory, such as/share/dir.Currently, only regular directories are supported. Filesets are not supported.
parameters.archiveOnDeleteThis parameter takes effect only when
volumeAsis set tosubpathandreclaimPolicyis set toDelete.General-purpose CPFS is a shared storage service. This parameter provides a second confirmation before deletion.
Controls how subdirectory data is handled when the PVC is deleted.
true(default): The subdirectory is archived and renamed toarchived-{pvName}.{timestamp}instead of being deleted. You can manually recover the data.false: Permanently deletes the subdirectory and all its files. This data cannot be recovered.This operation deletes only the CPFS subdirectory and its files, not the CPFS file system itself. To delete the CPFS file system, see Delete a file system.
reclaimPolicyIf csi-provisioner is a managed component, its version must be v1.34.1 or later. There is no version restriction for unmanaged components.
This parameter takes effect only when
volumeAsis set tosubpath.The reclaim policy for the PV. It controls how resources are handled after the PVC is deleted.
Delete: Automatically releases the PV when the PVC is deleted. ThearchiveOnDeleteparameter then determines if the backend subdirectory data is also deleted.Retain: When the PVC is deleted, the PV is retained and the backend data is not affected. You must manually clean up the resources. This option is suitable for scenarios with high data security requirements.
allowVolumeExpansionIf this parameter is enabled, the CPFS volume can be automatically expanded.
Create the StorageClass.
kubectl apply -f sc.yamlCheck if the StorageClass was created successfully.
kubectl get sc cnfs-nfs-cpfs-scExpected output:
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE cnfs-nfs-cpfs-sc nasplugin.csi.alibabacloud.com Retain Immediate true 9s
Step 3: Create an application
Create a workload and specify the StorageClass you created in its volumeClaimTemplates section.
Create a file named
sts.yamlby using the following template.apiVersion: apps/v1 kind: StatefulSet metadata: name: cnfs-nfs-cpfs-sts spec: selector: matchLabels: app: nginx serviceName: "nginx" replicas: 2 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: pvc # Mount the storage volume to the /data directory in the container. mountPath: /data # Define a PVC template. The StatefulSet controller dynamically creates a PVC for each pod. volumeClaimTemplates: - metadata: name: pvc spec: accessModes: [ "ReadWriteOnce" ] # Reference the StorageClass created earlier. storageClassName: "cnfs-nfs-cpfs-sc" resources: requests: storage: 50GiCreate the application.
kubectl apply -f sts.yamlCheck if the pods are in the Running state.
kubectl get pod | grep cnfs-nfs-cpfs-stsExpected output:
cnfs-nfs-cpfs-sts-0 1/1 Running 0 11s cnfs-nfs-cpfs-sts-1 1/1 Running 0 9sConfirm that the pods have mounted the CPFS storage volume.
kubectl exec cnfs-nfs-cpfs-sts-0 -- mount | grep nfsThe following output indicates that CNFS has successfully mounted the CPFS file system by using the NFS client.
cpfs-********-********.cn-shanghai.cpfs.aliyuncs.com:/share/nas-804e8cb1-2355-4026-87fc-ee061e14f5f9 on /data type nfs (rw,relatime,vers=3,rsize=1048576,wsize=1048576,namlen=255,hard,nolock,noresvport,proto=tcp,port=30000,timeo=600,retrans=2,sec=sys,mountaddr=127.XX.XX.255,mountvers=3,mountport=30000,mountproto=tcp,local_lock=all,addr=127.XX.XX.255)
Step 4: Verify the results
After the application is created, the system automatically provisions and mounts the volume.
Verify automatic provisioning
Check the status of the PVCs to confirm that two PVCs have been automatically created and bound to dynamically generated PVs.
kubectl get pvc -l app=nginxExpected output:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
pvc-cnfs-nfs-cpfs-sts-0 Bound nas-8d2530eb-fcf9-4ad5-b5f8-bae02a1***** 50Gi RWO cnfs-nfs-cpfs-sc <unset> 63s
pvc-cnfs-nfs-cpfs-sts-1 Bound nas-e84cadaf-ce35-4745-8cbb-2a80026***** 50Gi RWO cnfs-nfs-cpfs-sc <unset> 61sVerify pod status and mount points
Check the mount point inside the container to confirm that the isolated CPFS subdirectory is mounted successfully.
kubectl exec cnfs-nfs-cpfs-sts-0 -- mount | grep /dataThe mount path in the expected output includes the auto-generated PV name (for example, nas-804e8cb1-xxxx), which indicates that an isolated subdirectory is mounted.
cpfs-....aliyuncs.com:/share/nas-804e8cb1-2355-4026-87fc-ee061e1****** on /data type nfs (rw,...)Verify volume isolation
Verify that the dynamic volumes created for different pods are isolated from each other.
Create a temporary file in
cnfs-nfs-cpfs-sts-0.kubectl exec cnfs-nfs-cpfs-sts-0 -- touch /data/test.txtCheck the /data directory in
cnfs-nfs-cpfs-sts-1to confirm that the test file does not exist.kubectl exec cnfs-nfs-cpfs-sts-1 -- ls /dataThe expected output does not contain the file. This confirms that the dynamically created storage volumes are isolated and that the data is not shared.
Production best practices
Performance tuning: General-purpose CPFS is suitable for high-throughput and high-IOPS scenarios. You can adjust NFS mount options, such as
rsizeandwsize, in the StorageClass'smountOptionsto optimize performance for specific workload requirements.Data protection: Set
reclaimPolicytoRetainandarchiveOnDeletetotruein the StorageClass to prevent accidental data loss from PVC deletion.
Clean up resources
To avoid unexpected charges and ensure data security, follow this procedure to release resources that you no longer need.
Delete the workload
Action: Delete all applications that use the relevant PVCs, such as the StatefulSet. This action stops the running pods and unmounts the storage volumes.
Example command:
kubectl delete statefulset <your-statefulset-name>
Delete PVCs
Action: Delete the PVCs associated with the application. The handling of backend data is determined by the combination of
volumeAs,reclaimPolicy, andarchiveOnDelete.volumeAs: subpathEach PVC corresponds to an independent subdirectory. The deletion behavior is as follows:
reclaimPolicy: Retain: The PV is retained, and the data in the CPFS subdirectory remains unchanged. You must perform a manual cleanup.reclaimPolicy: Delete+archiveOnDelete: "true": The PV is automatically released. The subdirectory is archived and renamed toarchived-{pvName}.{timestamp}, and no data is lost.reclaimPolicy: Delete+archiveOnDelete: "false": Automatically releases the PV and permanently deletes the subdirectory and its files. This data cannot be recovered. Proceed with caution.
volumeAs: sharepathMultiple PVCs share the same directory. Deleting a PVC does not affect the backend directory or its data. The
reclaimPolicyandarchiveOnDeleteparameters have no effect.
Regardless of the configuration, the CPFS file system itself is not deleted. To delete the CPFS file system, see Delete a file system.
Example command:
kubectl delete pvc <your-pvc-name>
Delete Kubernetes storage resources
This action only removes the resource definitions within the cluster. It does not delete the backend CPFS file system.
Delete the PV
Action: If
reclaimPolicyis set toRetain, the PV's status changes toReleasedafter the PVC is deleted. You can then manually delete the PV if you confirm the data is no longer needed.Example command:
kubectl delete pv <your-pv-name>
Delete the StorageClass
Action: If you no longer need this type of storage, you can delete the corresponding StorageClass.
Example command:
kubectl delete sc <your-storageclass-name>
Delete the CNFS object
Action: If you no longer need to use the CPFS file system with the cluster, you can delete the CNFS object. Deleting a CNFS object does not delete the backend CPFS file system.
Example command:
kubectl delete cnfs <your-cnfs-name>