Helm Installation
The recommended way to deploy the flexFS CSI driver is with the provided Helm chart.
Prerequisites
Section titled “Prerequisites”- Kubernetes 1.25 or later
- Helm 3
/dev/fuseavailable on all worker nodes (most Linux distributions include it by default)- Cluster must allow privileged pods in the
kube-systemnamespace (the node DaemonSet requires privileged mode for FUSE access)
Download the chart
Section titled “Download the chart”The Helm chart is distributed as a .tgz archive from get.flexfs.io. Download and extract it:
curl -fsSLO https://get.flexfs.io/v1.9.x/k8s/flexfs-csi-driver.tgztar -xzf flexfs-csi-driver.tgzExtraction creates a flexfs-csi-driver/ directory containing the chart:
flexfs-csi-driver/├── Chart.yaml├── values.yaml└── templates/ ├── clusterrole.yaml ├── clusterrolebinding.yaml ├── csidriver.yaml ├── daemonset.yaml ├── deployment.yaml └── serviceaccount.yamlChart overview
Section titled “Chart overview”| Field | Value |
|---|---|
| Chart name | flexfs-csi-driver |
| Chart type | application |
| Home | https://flexfs.io |
| Default namespace | kube-system |
Default values
Section titled “Default values”The following table lists the configurable values in values.yaml and their defaults:
| Key | Default | Description |
|---|---|---|
clusterRole.name | flexfs-csi-controller | ClusterRole name |
clusterRoleBinding.name | flexfs-csi-controller | ClusterRoleBinding name |
csiDriver.name | csi.flexfs.io | Name of the CSIDriver object |
daemonSet.app | flexfs-csi-node | Node pod label |
daemonSet.name | flexfs-csi-node | Node DaemonSet name |
daemonSet.namespace | kube-system | Node DaemonSet namespace |
deployment.app | flexfs-csi-controller | Controller pod label |
deployment.name | flexfs-csi-controller | Controller Deployment name |
deployment.namespace | kube-system | Controller Deployment namespace |
deployment.replicas | 2 | Controller replica count |
driver.image | flexfs/csi-driver-<MAJOR>.<MINOR>:latest | CSI driver container image |
driver.imagePullPolicy | Always | Image pull policy |
driver.name | flexfs-csi-driver | Container name |
kubeletDir | /var/lib/kubelet | Kubelet root directory on the host. Override on distributions that relocate it (see MicroK8s and custom kubelet directories) |
serviceAccount.name | flexfs-csi-controller | ServiceAccount name |
serviceAccount.namespace | kube-system | ServiceAccount namespace |
Installation
Section titled “Installation”Run the following from the directory where you extracted the archive (so that ./flexfs-csi-driver resolves to the chart):
helm install flexfs-csi-driver ./flexfs-csi-driver \ --namespace kube-systemTo customize values:
helm install flexfs-csi-driver ./flexfs-csi-driver \ --namespace kube-system \ --set deployment.replicas=3 \ --set driver.imagePullPolicy=IfNotPresentOr use a values override file:
helm install flexfs-csi-driver ./flexfs-csi-driver \ --namespace kube-system \ -f my-values.yamlWhat gets created
Section titled “What gets created”The chart installs six Kubernetes resources:
| Resource | Kind | Name |
|---|---|---|
| CSI driver registration | CSIDriver | csi.flexfs.io |
| Service account | ServiceAccount | flexfs-csi-controller |
| Cluster role | ClusterRole | flexfs-csi-controller |
| Cluster role binding | ClusterRoleBinding | flexfs-csi-controller |
| Controller | Deployment | flexfs-csi-controller |
| Node plugin | DaemonSet | flexfs-csi-node |
RBAC permissions
Section titled “RBAC permissions”The ClusterRole grants the controller the following access:
| API group | Resources | Verbs |
|---|---|---|
storage.k8s.io | csinodes | get, list, watch |
"" (core) | events | create, list, patch, update, watch |
"" (core) | nodes | get, list, watch |
"" (core) | persistentvolumeclaims | get, list, update, watch |
"" (core) | persistentvolumes | create, delete, get, list, watch |
"" (core) | secrets | get, list |
storage.k8s.io | storageclasses | get, list, watch |
Controller Deployment
Section titled “Controller Deployment”The controller runs two containers:
- flexfs-csi-driver — the CSI driver process
- csi-provisioner (
registry.k8s.io/sig-storage/csi-provisioner:v3.6.4) — the external provisioner that watches for PVCs and calls CreateVolume/DeleteVolume
The controller pods use the system-cluster-critical priority class and tolerate CriticalAddonsOnly. They are scheduled only on Linux nodes.
Node DaemonSet
Section titled “Node DaemonSet”The node DaemonSet runs two containers on every node:
- flexfs-csi-driver — the CSI driver process, running in privileged mode
- csi-node-driver-registrar (
registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.10.1) — registers the CSI driver with kubelet
Key volume mounts on the node pods:
| Volume | Host path | Container path | Purpose |
|---|---|---|---|
driver-dir | {kubeletDir}/plugins/csi.flexfs.io | /csi | CSI socket |
kubelet-dir | {kubeletDir} | {kubeletDir} | Bidirectional mount propagation for FUSE |
registration-dir | {kubeletDir}/plugins_registry | /registration | kubelet plugin registration |
All of these paths, plus the --kubeletDir argument passed to the driver process, derive from the kubeletDir value (default /var/lib/kubelet).
The DaemonSet uses OnDelete update strategy, system-node-critical priority class, and tolerates all taints.
MicroK8s and custom kubelet directories
Section titled “MicroK8s and custom kubelet directories”Some Kubernetes distributions run kubelet with a non-standard --root-dir. The most common example is MicroK8s, which uses /var/snap/microk8s/common/var/lib/kubelet.
The kubeletDir value must match the node’s actual kubelet root directory. It controls three things that all have to agree:
- The DaemonSet host-path mounts and the
csi-node-driver-registrarregistration path. - The
kubelet-dirvolumemountPathinside the node container (which carriesBidirectionalmount propagation). - The
--kubeletDirargument passed to the driver process, which the driver uses to locate its FUSE base mounts under{kubeletDir}/flexfs.
If kubeletDir does not match the real kubelet root, the driver’s base FUSE mount can still appear on the host, but the per-pod bind mount is created at a path outside the propagated volume and never reaches the pod — so the pod’s mount point looks empty with no error in the logs.
For MicroK8s, install with:
helm install flexfs-csi-driver ./flexfs-csi-driver \ --namespace kube-system \ --set kubeletDir=/var/snap/microk8s/common/var/lib/kubeletUpgrading
Section titled “Upgrading”Download and extract the chart for the new version (see Download the chart), then:
helm upgrade flexfs-csi-driver ./flexfs-csi-driver \ --namespace kube-systemUninstalling
Section titled “Uninstalling”helm uninstall flexfs-csi-driver --namespace kube-systemNext steps
Section titled “Next steps”- Create a Secret with admin server credentials for dynamic provisioning
- Create a PV/PVC for static provisioning
- Review the full Configuration reference