The official CSI Driver for integrating PanFS storage with Container Orchestration Systems like Kubernetes.
- Overview
- Capabilities
- Compatibility
- Getting started
- Deploying Workloads
- CSI Driver Uninstallation
- API Documentation
- Testing
The Container Storage Interface (CSI) is a standard for exposing arbitrary block and file storage systems to containerized workloads on Container Orchestration Systems like Kubernetes. Using CSI, third-party storage providers can write and deploy plugins exposing new storage systems in Kubernetes without ever having to touch the core Kubernetes code. The Container Storage Interface was designed to help Container Orchestrators replace their existing in-tree storage driver mechanisms - especially vendor-specific plugins.
The PanFS CSI driver allows you to use PanFS volumes in a Kubernetes cluster. It is possible to use volumes from multiple realms within a single CSI driver instance. See the Deploying Workloads section for usage examples.
For more details, please see the Overview documentation
The driver implements the core CSI services for lifecycle management:
- Identity Service: Used for plugin discovery (
GetPluginInfo) and health checks (Probe). - Controller Service: Provides full lifecycle management, including:
CreateVolumeDeleteVolumeControllerExpandVolume
- Node Service: Handles volume attachment, mount, and unmount operations.
- Online Volume Expansion: Supports resizing volumes while they are attached and in use by a pod.
The driver exposes advanced PanFS features through CSI:
- Volume Quota Management: Supports configurable soft and hard quotas for PanFS volumes.
- Multiple Volume Layouts: Provisioning support for various PanFS layouts (e.g.,
raid6+,raid5+,raid10+). - End-to-End Encryption: Supports transparent volume encryption using an external KMIP provider (see Configure and deploy StorageClass).
- Robust Operation: Includes extensive parameter validation, unit conversion (e.g., GB/bytes), and mapping of PanFS CLI errors to CSI-compliant error codes.
The PanFS CSI driver supports custom mount options for PanFS volumes. You can specify mount options in the PersistentVolume manifest using the mountOptions field. This allows you to customize the mount behavior according to your requirements.
The PanFS CSI driver supports custom parameters for volume creation in the StorageClass manifest. You can specify parameters such as storageset, layout etc to customize the behavior of the created volumes.
For a full list of supported parameters, refer to the official PanFS documentation for volume creation corresponding to your PanFS version and CSI PanFS driver version.
This matrix defines the supported versions for the PanFS CSI Driver, Kubernetes, CSI Specification, and PanFS:
| PanFS CSI Version | Kubernetes Version | CSI Spec Version |
|---|---|---|
| 1.0.0 | 1.30.1+ | 1.7.0 |
| 1.0.1+ | 1.30.1+ | 1.11.0 |
| 1.1.0 | 1.30.1+ | 1.11.0 |
| 1.2.0 | 1.30.1+ | 1.11.0 |
| 1.2.1 | 1.30.1+ | 1.11.0 |
| 1.2.2 | 1.30.1+ | 1.11.0 |
- Deploy using the kubectl CLI tool
- PanFS CSI driver requires the panfs kernel module to be installed and configured on the host nodes
- Ensure that all required ports are open to allow PanFS to perform mounts (see details in the user guide)
- Kubernetes Cluster: Version 1.30.1+ with cluster-admin privileges
- kubectl: Compatible with your Kubernetes cluster version. See Kubernetes docs
- Linux Kernel: Compatible with PanFS kernel module (see compatibility matrix below)
- Container Runtime: Docker, containerd, or CRI-O
- Network: Ensure required ports are open for PanFS communication (refer to PanFS documentation)
- Container Registry Access: Credentials for pulling/pushing driver images
- PanFS Realm Access: Valid credentials and network connectivity to PanFS backend
For experienced users who want to deploy quickly, here's the essential command sequence:
Ensure the following Kubernetes ecosystem tools are installed in your cluster:
- cert-manager: Follow the installation guide.
- KMM (Kernel Module Manager): Follow the installation guide.
Create the namespace, configure registry credentials, and deploy the driver using the Kubernetes manifest file
# Create PanFS CSI Driver namespace
kubectl create namespace csi-panfs
# Configure secret for Private Registry with PanFS DFC KMM images
# REPLACE placeholders with your actual registry settings:
kubectl create secret docker-registry <your-secret-name> \
--docker-server=<your-registry-server> \
--docker-username=<your-username> \
--docker-password=<your-password> \
--docker-email=<your-email> \
--namespace=csi-panfsThis will deploy CSI driver components and the KMM module.
Please update the settings in deploy/k8s/csi-driver/template-csi-panfs.yaml according to your cluster specification and available image tags in your private registry:
Edit the deployment manifest at deploy/k8s/csi-driver/template-csi-panfs.yaml to configure essential settings:
<IMAGE_PULL_SECRET_NAME>: The name of the secret created above.<PANFS_DFC_KMM_PRIVATE_REGISTRY>: The URL of your private registry hosting the DFC/KMM images.<DFC_RELEASE_VERSION>: The specific version tag of the DFC release you are deploying.
Note: Review other settings relevant to your Kubernetes infrastructure, such as:
replicastolerationsnodeSelector- etc
Once configured, deploy the driver and KMM module:
kubectl apply -f deploy/k8s/csi-driver/template-csi-panfs.yamlThe expected output will look like:
poddisruptionbudget.policy/csi-panfs-controller-pdb created
serviceaccount/csi-panfs-controller created
serviceaccount/csi-panfs-node created
clusterrole.rbac.authorization.k8s.io/csi-panfs-controller-provisioner created
clusterrole.rbac.authorization.k8s.io/csi-panfs-controller-attacher created
clusterrole.rbac.authorization.k8s.io/csi-panfs-controller-resizer created
clusterrole.rbac.authorization.k8s.io/csi-panfs-node created
clusterrolebinding.rbac.authorization.k8s.io/csi-panfs-controller-provisioner-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/csi-panfs-controller-attacher-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/csi-panfs-controller-resizer-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/csi-panfs-node-rolebinding created
role.rbac.authorization.k8s.io/csi-panfs-controller-provisioner created
role.rbac.authorization.k8s.io/csi-panfs-controller-attacher created
rolebinding.rbac.authorization.k8s.io/csi-panfs-controller-provisioner-rolebinding created
rolebinding.rbac.authorization.k8s.io/csi-panfs-controller-attacher-rolebinding created
daemonset.apps/csi-panfs-node created
deployment.apps/csi-panfs-controller created
csidriver.storage.k8s.io/com.vdura.csi.panfs created
module.kmm.sigs.x-k8s.io/panfs createdValidate Deployment:
Check the status of the deployed components:
- CSI Driver Registration:
kubectl get csidrivers | grep panfs - Controller Deployment: (Should show
READYequal toUP-TO-DATE)kubectl get deployment csi-panfs-controller -n csi-panfs
- Node DaemonSet: (Should show
READYequal toDESIRED)kubectl get daemonset csi-panfs-node -n csi-panfs
- KMM Module Status:
kubectl get module panfs -n csi-panfs -o yaml | sed -n '/status:$/,/^$/p'
The StorageClass defines the provisioned volume properties and provides PanFS Realm access credentials.
Edit deploy/k8s/storage-class/template-secret-in-driver-ns.yaml to replace the following placeholders with your PanFS Realm details.
<STORAGE_CLASS_NAME>: The desired name for your StorageClass (e.g.,csi-panfs-storage-class).<REALM_ADDRESS>: The PanFS backend address (e.g.,panfs.example.com).- Credentials: Provide one of the following sets of authentication data:
<REALM_USERNAME>and<REALM_PASSWORD>(for user/password authentication)<REALM_PRIVATE_KEY>and<REALM_PRIVATE_KEY_PASSPHRASE>(for key-based authentication)
<KMIP_CONFIG_DATA>: KMIP server connection details for volume encryption (if used).
To designate this StorageClass as the default option for volume provisioning in your Kubernetes cluster, add the following annotation to the metadata section of its manifest:
metadata:
annotations:
storageclass.kubernetes.io/is-default-class: "true"To enable transparent, end-to-end volume encryption using a KMIP provider:
- Enable Encryption in StorageClass: Set the parameter below to
"true"in the StorageClass manifest:kind: StorageClass parameters: panfs.csi.vdura.com/encryption: "true" # Enables encryption for volumes
- Configure KMIP Client: The KMIP client configuration file content must be placed in the Secret under the
kmip_config_datakey as a YAML multi-line string:kind: Secret stringData: kmip_config_data: |- # Insert the full KMIP client configuration file content here. # This typically includes server addresses, port, and client TLS/PKI settings.
- Make sure KMM module is configured to load
wolfsslkermel module. Check this:kubectl get module panfs -n csi-panfs -o jsonpath='{.spec.moduleLoader.container.modprobe.modulesLoadingOrder}' ["panfs","wolfssl"]
Deploy PanFS Storage Class:
kubectl apply -f deploy/k8s/storage-class/template-secret-in-driver-ns.yamlThe expected output will look like this:
namespace/csi-panfs-storage-class unchanged
secret/csi-panfs-storage-class configured
storageclass.storage.k8s.io/csi-panfs-storage-class configuredValidate StorageClass:
kubectl get sc csi-panfs-storage-classExpected output:
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
csi-panfs-storage-class com.vdura.csi.panfs Delete WaitForFirstConsumer true 2m
If the StorageClass is missing or misconfigured, verify the configuration variables and check kubectl logs for errors.
Refer to usage-guide.md for YAML manifests and examples of deploying workloads with the PanFS CSI Driver.
A complete uninstallation ensures that all associated resources—workloads, PersistentVolumes, the StorageClass, driver components, and kernel modules—are cleanly removed from the Kubernetes cluster.
Before deleting the driver, you must ensure no running applications are actively using PanFS volumes.
-
Identify all PanFS PersistentVolumes (PVs): This command lists the names of all PVs provisioned by the PanFS CSI driver.
kubectl get pv -o jsonpath='{.items[?(@.spec.csi.driver=="com.vdura.csi.panfs")].metadata.name}' -
Delete PVCs and Workloads: Manually delete all PersistentVolumeClaims (PVCs) and the workloads (Pods, Deployments, StatefulSets) that rely on the identified PVs.
⚠️ Important: Deleting the PVCs will trigger the deletion of the associated PersistentVolumes (PVs), which in turn will cause the CSI Controller to delete the corresponding volume data on the backend PanFS storage, based on thereclaimPolicydefined in your StorageClass (typicallyDelete).
Delete the StorageClass(es) and the associated Secret containing the PanFS Realm credentials.
# Delete the StorageClass and the Secret containing the Realm credentials.
# Replace 'panfs-storage-class.yaml' with the actual file name you used.
kubectl delete -f panfs-storage-class.yamlUse the original deployment manifest to remove the Controller, Node DaemonSet, KMM Module, and all associated RBAC and custom resources.
# Delete the CSI driver Deployment, DaemonSet, CSIDriver object, and KMM Module.
# Replace 'panfs-csi-driver.yaml' with the actual file name you used.
kubectl delete -f panfs-csi-driver.yamlRemove Node Labels:
The KMM deployment sets labels on worker nodes. These labels must be removed to signal a complete cleanup.
# Removes the panfs readiness label from all nodes.
kubectl label node -l node-role.kubernetes.io/worker= node.kubernetes.io/csi-driver.panfs.ready- --overwriteVerify Label Removal:
Ensure no nodes still have the node.kubernetes.io/csi-driver.panfs.ready label set. The count should be 0.
kubectl get nodes --show-labels | grep node.kubernetes.io/csi-driver.panfs.ready | wc -l
0Remove the namespace and any labels or secrets created during the prerequisite steps.
-
Remove the CSI Driver Namespace:
kubectl delete namespace csi-panfs
-
Remove Registry Secret (if it was created in a separate namespace): If you created the private registry secret in a different namespace, delete it now.
kubectl delete secret <your-secret-name> --namespace=<your-namespace>
If the cluster was solely dedicated to running the PanFS CSI driver, you may optionally uninstall the dependencies that were installed as prerequisites.
- Uninstall KMM (Kernel Module Manager): Refer to the KMM documentation.
- Uninstall cert-manager: Refer to the cert-manager documentation.
You can generate and view Go API documentation for this project using the pkgsite tool.
- Install pkgsite:
go install golang.org/x/pkgsite/cmd/pkgsite@latest- Run pkgsite in the project root:
pkgsite -open .- It opens your browser, or navigate to http://localhost:8080 to view the generated documentation for all Go packages in the repository.
This will provide a browsable interface for all exported types, functions, and documentation comments in your codebase.
The PanFS CSI driver includes a ready-to-use Docker Compose setup for running CSI Sanity tests, located in tests/csi_sanity/docker-compose.yaml.
-
Build the CSI driver and sanity test images:
- Set the environment variables
CSI_IMAGE(your built PanFS CSI driver image) andCSI_TEST_IMAGE(the baked test image, seetests/csi_sanity/Dockerfile). - Example:
export CSI_IMAGE=your-registry/panfs-csi-driver:latest export CSI_TEST_IMAGE=your-registry/panfs-csi-sanity:latest docker compose -f tests/csi_sanity/docker-compose.yaml up --build
- Set the environment variables
-
The compose file will start controller and node plugin containers, then run the sanity test suite in a dedicated container. Results will be shown in the output.
-
You can customize secrets and test parameters by editing
tests/csi_sanity/secrets.yamland environment variables in the compose file.
- The sanity test container uses the
csi-sanitytool and runs tests against the controller and node endpoints exposed by the plugin containers. - Healthchecks ensure the plugins are ready before tests start.
- You can inspect logs for detailed test output and troubleshooting.
- For more details on CSI Sanity, see the CSI Sanity documentation.
End-to-end (E2E) tests validate the PanFS CSI driver in a real Kubernetes cluster, covering full volume lifecycle operations, dynamic provisioning, expansion, and workload integration.
- All manifests and configuration are in
tests/e2e/:e2e-runner.yaml: Deploys Namespace, ServiceAccount, RBAC, ConfigMap, and a CronJob to run E2E tests.test-driver.yaml: CSI test driver configuration (capabilities, access modes, stress/performance options).test-sc.yaml: StorageClass definition for E2E tests.
- Deploy the E2E test environment:
kubectl apply -f tests/e2e/e2e-runner.yamlThis creates the namespace, RBAC, config, and a CronJob that runs daily at 2:00 AM.
- To run the E2E test job immediately:
kubectl create job --from=cronjob/tests -n e2e tests-manual-
You can customize the test driver and StorageClass by editing
test-driver.yamlandtest-sc.yamlin thetests/e2e/folder. The ConfigMap ine2e-runner.yamlreferences these files. -
Review job logs for test results and troubleshooting:
kubectl logs job/tests-manual -n e2e- E2E tests require a working Kubernetes cluster and sufficient permissions.
- The CronJob uses a prebuilt test image and runs tests with the configuration from the ConfigMap.
- For more details, see
tests/e2e/Readme.mdin this repository.