Skip to content

Helm Installation

The recommended way to deploy the flexFS CSI driver is with the provided Helm chart.

  • Kubernetes 1.25 or later
  • Helm 3
  • /dev/fuse available on all worker nodes (most Linux distributions include it by default)
  • Cluster must allow privileged pods in the kube-system namespace (the node DaemonSet requires privileged mode for FUSE access)

The Helm chart is distributed as a .tgz archive from get.flexfs.io. Download and extract it:

Terminal window
curl -fsSLO https://get.flexfs.io/v1.9.x/k8s/flexfs-csi-driver.tgz
tar -xzf flexfs-csi-driver.tgz

Extraction 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.yaml
FieldValue
Chart nameflexfs-csi-driver
Chart typeapplication
Homehttps://flexfs.io
Default namespacekube-system

The following table lists the configurable values in values.yaml and their defaults:

KeyDefaultDescription
clusterRole.nameflexfs-csi-controllerClusterRole name
clusterRoleBinding.nameflexfs-csi-controllerClusterRoleBinding name
csiDriver.namecsi.flexfs.ioName of the CSIDriver object
daemonSet.appflexfs-csi-nodeNode pod label
daemonSet.nameflexfs-csi-nodeNode DaemonSet name
daemonSet.namespacekube-systemNode DaemonSet namespace
deployment.appflexfs-csi-controllerController pod label
deployment.nameflexfs-csi-controllerController Deployment name
deployment.namespacekube-systemController Deployment namespace
deployment.replicas2Controller replica count
driver.imageflexfs/csi-driver-<MAJOR>.<MINOR>:latestCSI driver container image
driver.imagePullPolicyAlwaysImage pull policy
driver.nameflexfs-csi-driverContainer name
kubeletDir/var/lib/kubeletKubelet root directory on the host. Override on distributions that relocate it (see MicroK8s and custom kubelet directories)
serviceAccount.nameflexfs-csi-controllerServiceAccount name
serviceAccount.namespacekube-systemServiceAccount namespace

Run the following from the directory where you extracted the archive (so that ./flexfs-csi-driver resolves to the chart):

Terminal window
helm install flexfs-csi-driver ./flexfs-csi-driver \
--namespace kube-system

To customize values:

Terminal window
helm install flexfs-csi-driver ./flexfs-csi-driver \
--namespace kube-system \
--set deployment.replicas=3 \
--set driver.imagePullPolicy=IfNotPresent

Or use a values override file:

Terminal window
helm install flexfs-csi-driver ./flexfs-csi-driver \
--namespace kube-system \
-f my-values.yaml

The chart installs six Kubernetes resources:

ResourceKindName
CSI driver registrationCSIDrivercsi.flexfs.io
Service accountServiceAccountflexfs-csi-controller
Cluster roleClusterRoleflexfs-csi-controller
Cluster role bindingClusterRoleBindingflexfs-csi-controller
ControllerDeploymentflexfs-csi-controller
Node pluginDaemonSetflexfs-csi-node

The ClusterRole grants the controller the following access:

API groupResourcesVerbs
storage.k8s.iocsinodesget, list, watch
"" (core)eventscreate, list, patch, update, watch
"" (core)nodesget, list, watch
"" (core)persistentvolumeclaimsget, list, update, watch
"" (core)persistentvolumescreate, delete, get, list, watch
"" (core)secretsget, list
storage.k8s.iostorageclassesget, list, watch

The controller runs two containers:

  1. flexfs-csi-driver — the CSI driver process
  2. 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.

The node DaemonSet runs two containers on every node:

  1. flexfs-csi-driver — the CSI driver process, running in privileged mode
  2. 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:

VolumeHost pathContainer pathPurpose
driver-dir{kubeletDir}/plugins/csi.flexfs.io/csiCSI socket
kubelet-dir{kubeletDir}{kubeletDir}Bidirectional mount propagation for FUSE
registration-dir{kubeletDir}/plugins_registry/registrationkubelet 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.

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:

  1. The DaemonSet host-path mounts and the csi-node-driver-registrar registration path.
  2. The kubelet-dir volume mountPath inside the node container (which carries Bidirectional mount propagation).
  3. The --kubeletDir argument 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:

Terminal window
helm install flexfs-csi-driver ./flexfs-csi-driver \
--namespace kube-system \
--set kubeletDir=/var/snap/microk8s/common/var/lib/kubelet

Download and extract the chart for the new version (see Download the chart), then:

Terminal window
helm upgrade flexfs-csi-driver ./flexfs-csi-driver \
--namespace kube-system
Terminal window
helm uninstall flexfs-csi-driver --namespace kube-system