Apache CloudStack has quietly become a serious Kubernetes host via CKS (CloudStack Kubernetes Service) and CAPC (Cluster API Provider CloudStack). But a Kubernetes cluster without persistent storage is a stateless toy: databases, message queues, and anything that needs to survive a pod restart need real, attachable, resizable disks.
That’s the gap the cloudstack-csi-driver closes. It is the plugin that lets Kubernetes talk to CloudStack’s storage layer using the standard Container Storage Interface (CSI), regardless of how the cluster itself was provisioned.
The driver’s only real requirements are CloudStack API credentials and a way to match Kubernetes node names to CloudStack VMs, either by name or via cloud-init/ignition instance metadata.
That’s why it works identically whether the cluster came from CKS, from CAPC, or was bootstrapped by hand. The Helm chart or manifest simply needs to be applied and pointed at a cloud-config secret. CKS happens to be the one place that performs this bootstrap automatically.
Where It Fits: CKS’s “Enable CSI Integration” Toggle
Starting in CloudStack 4.22.0, CKS includes native CSI integration, allowing CKS clusters to dynamically provision CloudStack volumes for Kubernetes pods without requiring a manual driver installation.
If you are using CAPC, you get the same driver and the same features, but you install the Helm chart yourself rather than having it configured automatically during cluster creation.
A few things are worth knowing about how the CKS path is wired up:
- It’s baked into the data ISO: The CSI manifests and images ship inside the CKS Kubernetes data ISO itself. If you are running your own ISOs, you need to rebuild them with
create-kubernetes-binaries-iso.shto include the CSI manifests. Older ISOs will not contain them. - Pre-built ISOs are available: CloudStack publishes ready-to-use Kubernetes data ISOs with CSI already included at https://download.cloudstack.org/cks/, so in most cases there is no ISO-building step.
- It’s an opt-in checkbox: In the Kubernetes cluster creation form, under Advanced Settings, there is an Enable CSI Integration checkbox. Enabling it triggers the CSI bootstrap during cluster creation.
When enabled, CloudStack injects a cloud-config secret containing the required API credentials and rolls out the full CSI stack onto the new cluster.
This includes:
- A controller Deployment with two leader-elected replicas. It communicates with the CloudStack API to create, delete, attach, detach, expand, and snapshot volumes.
- A node DaemonSet running on every worker node, responsible for formatting, mounting, and resizing disks on the host where the pod actually runs.
That is the entire “day 0” story for CKS.
From that point on, the driver is simply there, registered with kubelet and watching for PersistentVolumeClaims. Everything after that — which disk offerings to expose, which storage classes to define, and whether to enable snapshots — is controlled by the cluster operator, regardless of how the cluster was created.
The Shape of the Driver
Under the hood, this is a fairly textbook CSI plugin. The same Go binary runs in two modes — controller and node — or in all mode for a combined single-binary deployment.
- Controller plugin (
pkg/driver/controller.go): implementsCreateVolume,DeleteVolume,ControllerPublishVolume/Unpublish,ControllerExpandVolume, and the snapshot RPCs. It is the only component that directly calls CloudStack operations such ascreateVolume,attachVolume, andcreateSnapshot. - Node plugin (
pkg/driver/node.go): implementsNodeStageVolume,NodePublishVolume,NodeExpandVolume, andNodeGetVolumeStats. This is where the block device is actually formatted and bind-mounted into the pod’s filesystem.
Both components are wired up behind the standard CSI sidecar containers, including:
external-provisionerexternal-attacherexternal-resizerexternal-snapshotternode-driver-registrarlivenessprobe
These components can be deployed through the Helm chart or manually.
Features That Actually Matter to a CloudStack Admin
Disk-Offering-Driven Storage Classes
A Kubernetes StorageClass maps directly to a CloudStack disk offering through the csi.cloudstack.apache.org/disk-offering-id parameter.
This means the performance tiers you have already defined in CloudStack — such as SSD-backed storage or custom IOPS offerings — become first-class Kubernetes storage classes.
You do not need to recreate your storage catalogue for Kubernetes. You expose the catalogue you already have.
One catch: the disk offering must be custom-sized and of type shared. This allows the driver to request the exact size specified by a PVC rather than relying on a fixed disk size.
Automatic Storage-Class Sync
Rather than manually writing a StorageClass YAML definition for every CloudStack disk offering, the bundled cloudstack-csi-sc-syncer can handle the process automatically.
The syncer can run as a Helm-managed Job or CronJob. It scans CloudStack disk offerings, filters them to compatible custom/shared offerings, and creates or removes matching Kubernetes storage classes.
In practical terms:
New disk offering in CloudStack → new storage class in Kubernetes.
No manual YAML update is required.
Zone-Aware, “Wait for the Pod” Provisioning
Storage classes use:
volumeBindingMode: WaitForFirstConsumer
This means a PersistentVolumeClaim is not bound to a disk until a pod has actually been scheduled.
The driver reports CSI topology segments based on the CloudStack zone ID, ensuring that the volume is created in the same zone where the pod is running.
Full Attach/Detach Lifecycle
CloudStack data disks can only be attached to one VM at a time, and the CSI driver models that behaviour correctly.
It advertises only the SINGLE_NODE_WRITER access mode.
The ControllerPublishVolume and ControllerUnpublishVolume operations are idempotent and also handle edge cases such as:
- A volume already being attached to the requested node
- A VM that no longer exists
- A volume that has disappeared from CloudStack
Instead of leaking these situations into Kubernetes as persistent errors, the driver returns CSI-spec-compliant responses.
Online Volume Expansion
A PVC can be expanded by increasing its spec.resources.requests.storage value.
The CSI driver then handles the expansion in two stages:
ControllerExpandVolumeresizes the CloudStack volume.NodeExpandVolumegrows the filesystem in place.
Supported filesystems include:
- ext2
- ext3
- ext4
- xfs
There is no pod restart required. For raw block volumes, the filesystem expansion step is skipped.
Volume Snapshots and Restore
With kvm.snapshot.enabled enabled in CloudStack KVM zones, the driver supports the full Kubernetes VolumeSnapshotClass and VolumeSnapshot workflow through the external snapshotter.
Supported operations include:
CreateSnapshotListSnapshotswith paginationDeleteSnapshot- Creating a new PVC directly from an existing snapshot
A restored volume is not attached until a pod actually claims it. This keeps the snapshot → restore → attach process lazy and topology-aware, just like fresh volume provisioning.
Configurable Reclaim Behaviour
Storage classes support both common Kubernetes reclaim policies:
- Delete: the default behaviour. Deleting the PVC, or tearing down the CKS cluster, also removes the underlying CloudStack disk.
- Retain: the underlying volume survives PVC or cluster deletion and can be recovered manually.
Multi-Tenant CloudStack Awareness
The driver configuration supports CloudStack:
- Projects
- Domains
- Accounts
It uses the same cloud-config format as the CloudStack Kubernetes Provider.
If you are already running the CloudStack cloud-controller-manager, the same secret can therefore be reused.
Production-Grade Helm Defaults
The Helm deployment includes several production-focused defaults.
- Controller pods use anti-affinity so they are spread across nodes.
- Controllers are preferentially placed on control-plane nodes.
- Sidecars use leader election.
- Components use hardened
securityContextsettings including non-root execution, read-only root filesystems, andRuntimeDefaultseccomp profiles. - The node DaemonSet runs with
privileged: truebecause it needs to bind mount into the kubelet directory. - An optional Prometheus
PodMonitorprovides observability.
Cross-Hypervisor Ambition
KVM is currently the most tested path, particularly for snapshot functionality.
However, the driver has been designed to work across:
- KVM
- VMware
- XenServer / XCP-ng
The implementation builds on the Apalia → Leaseweb → CloudStack community lineage and has been expanded to cover domains, projects, CKS, and CAPC.
The Division of Labour, Concretely
| CKS (“Enable CSI Integration”) Does | You Do After That |
|---|---|
Creates the cloudstack-secret with API credentials |
Decide which disk offerings should be Kubernetes-visible |
| Deploys the CSI controller Deployment and node DaemonSet from the data ISO’s bundled manifests | Create StorageClasses, or let the syncer create them |
| Registers the driver with kubelet on every node | Set reclaimPolicy per class: Delete or Retain |
| Handles node ↔ VM identity matching using names or cloud-init/ignition metadata | Apply VolumeSnapshotClass and related CRDs if you want snapshots |
| Runs the CSI sidecars, including provisioner, attacher, resizer, and registrar | Write PVCs and use nodeSelector/nodeAffinity rather than nodeName, so Kubernetes remains in control of topology-aware scheduling |
On CAPC, there is no automatic bootstrap step.
You install the chart yourself using helm install, or apply the necessary configuration with kubectl, and create the cloudstack-secret manually.
Everything after that works in the same way.
Why This Matters
Before CSI drivers such as this existed, persistent storage on CloudStack Kubernetes generally meant either NFS-backed volumes with no complete snapshot or resize workflow, or hand-written scripts calling the CloudStack API outside Kubernetes’ control loop.
The CSI driver changes that.
Combined with CKS’s one-click Enable CSI Integration bootstrap starting with CloudStack 4.22.0, or a self-service Helm installation on CAPC, the experience becomes much more seamless.
Operators can:
- Declare a
PersistentVolumeClaimand automatically receive a CloudStack disk - Resize volumes live
- Create snapshots
- Restore new volumes from snapshots
- Control whether storage is deleted or retained when claims disappear
For CloudStack operators, this means the primary storage tiers already available in the environment can become a self-service Kubernetes storage catalogue with very little additional operational overhead.
And that remains true regardless of whether the Kubernetes cluster was created using CKS, CAPC, or another provisioning workflow.
Conclusion
The CloudStack CSI driver brings Kubernetes-native persistent storage management directly into the CloudStack ecosystem.
With dynamic provisioning, topology awareness, online expansion, snapshot support, automatic storage-class synchronisation, and integration with CloudStack’s existing disk offerings, Kubernetes workloads can consume CloudStack storage without requiring a separate storage management model.
For CKS users, much of the initial integration can now be enabled directly during cluster creation.
For CAPC and manually provisioned Kubernetes environments, the same CSI capabilities are available through the Helm deployment.
The result is a more integrated storage experience in which Kubernetes manages storage through its standard CSI workflows while CloudStack continues to provide the underlying infrastructure.
Pearl is a quality and technology driven software engineer, with 5 years’ experience with relevant expertise in providing solutions to the telecom and software industry. Pearl has an excellent grasp of the evolving technologies in the changing telecom space. She is a go-getter, with a flair for learning new technologies. Pearl is based in Bangalore, India. Self-learning and self-motivation are the mantras that she follows to keep herself abreast with new things in her field of work.