TrueNAS CSI Driver

March 3, 2026 ยท View on GitHub

A Container Storage Interface (CSI) driver for TrueNAS 25.10.0+, enabling dynamic provisioning of persistent volumes in Kubernetes using TrueNAS storage.

Features

  • NFS volumes - ReadWriteMany (RWX) access mode for shared storage
  • iSCSI volumes - Block storage with ReadWriteOnce (RWO) and ReadWriteMany (RWX) access modes (RWX requires cluster filesystem like GFS2/OCFS2)
  • Dynamic provisioning - Automatic volume creation and deletion
  • Volume expansion - Online resize of volumes
  • Snapshots and clones - CSI snapshot support for backup and cloning
  • CHAP authentication - Secure iSCSI connections
  • ZFS compression - LZ4, ZSTD, GZIP, and other algorithms
  • ZFS encryption - Dataset-level encryption with key management
  • Automatic snapshot scheduling - Periodic snapshots via StorageClass
  • TrueNAS Websocket API - Uses the modern TrueNAS Websocket API

Requirements

TrueNAS

  • TrueNAS SCALE 25.10.0+
  • API access enabled
  • At least one ZFS pool configured

Kubernetes

Node Requirements

  • NFS volumes: No additional requirements
  • iSCSI volumes: open-iscsi package installed on worker nodes

Quick Start

  1. Create an API key in TrueNAS

    • Log into TrueNAS web UI
    • Navigate to your profile โ†’ API Keys
    • Create a new API key and copy it
  2. Configure the driver

    # Edit the deployment manifest
    vi deploy/truenas-csi-driver.yaml
    

    Update the ConfigMap with your TrueNAS connection details and the Secret with your API key.

  3. Deploy the driver

    kubectl apply -f deploy/truenas-csi-driver.yaml
    
  4. Create a StorageClass and PVC

    kubectl apply -f examples/storageclass-nfs.yaml
    kubectl apply -f examples/pvc-nfs.yaml
    

Installation

Prerequisites

Install the snapshot controller (required for snapshot support):

kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshots.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/deploy/kubernetes/snapshot-controller/rbac-snapshot-controller.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/deploy/kubernetes/snapshot-controller/setup-snapshot-controller.yaml

Deploy the Driver

  1. Edit deploy/truenas-csi-driver.yaml with your configuration
  2. Apply the manifest:
    kubectl apply -f deploy/truenas-csi-driver.yaml
    

Verify Installation

# Check driver pods are running
kubectl get pods -n truenas-csi

# Verify CSI driver is registered
kubectl get csidrivers

Non-Standard Kubelet Paths

The default deployment manifest uses /var/lib/kubelet as the kubelet root directory. Some Kubernetes distributions use a different path. If your distribution uses a non-standard path, you must update the following in deploy/truenas-csi-driver.yaml before deploying:

  1. All hostPath values containing /var/lib/kubelet
  2. The DRIVER_REG_SOCK_PATH environment variable
  3. The --kubelet-registration-path argument
  4. The mountPath for the kubelet-dir volume mount on the csi-node container
DistributionKubelet Path
Standard Kubernetes/var/lib/kubelet (default)
MicroK8s/var/snap/microk8s/common/var/lib/kubelet
K3s/var/lib/rancher/k3s/agent/kubelet

Important: The kubelet-dir mountPath must match the hostPath. If they differ, NFS mounts will succeed inside the CSI container but will not propagate to kubelet, causing pods to see local storage instead of NFS.

MicroK8s Mount Propagation

MicroK8s runs inside a snap with its own mount namespace. For CSI mount propagation to work, the host root filesystem must have shared propagation before MicroK8s starts:

sudo mount --make-rshared /
microk8s start

To make this persistent across reboots, create a systemd unit:

sudo tee /etc/systemd/system/microk8s-mount-propagation.service <<EOF
[Unit]
Description=Ensure shared mount propagation for MicroK8s
Before=snap.microk8s.daemon-containerd.service

[Service]
Type=oneshot
ExecStart=/bin/mount --make-rshared /
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl enable microk8s-mount-propagation

Configuration

Driver Configuration (ConfigMap)

SettingDescriptionExample
truenasURLWebSocket URL to TrueNAS APIwss://10.0.0.100/api/current
truenasInsecureSkip TLS verificationtrue (for self-signed certs)
defaultPoolDefault ZFS pool for volumestank
nfsServerNFS server address10.0.0.100
iscsiPortaliSCSI portal address10.0.0.100:3260
iscsiIQNBaseBase IQN for iSCSI targetsiqn.2024-01.com.example

StorageClass Parameters

General Parameters

ParameterDescriptionValues
protocolStorage protocolnfs, iscsi
poolZFS pool (overrides default)pool name
compressionZFS compression algorithmOFF, LZ4, GZIP, ZSTD, ZLE, LZJB
syncZFS sync modeSTANDARD, ALWAYS, DISABLED

NFS Parameters

ParameterDescriptionExample
nfs.hostsAllowed hosts10.0.0.0/8,192.168.1.0/24
nfs.networksAllowed networks10.0.0.0/8
nfs.mountOptionsClient mount optionshard,nfsvers=4.1
nfs.mapAllUserNFS user mapping (default: root)postgres
nfs.mapAllGroupNFS group mapping (default: wheel)postgres

iSCSI Parameters

ParameterDescriptionValues
volblocksizeZVOL block size512, 1K, 2K, 4K, 8K, 16K, 32K, 64K, 128K
iscsi.blocksizeiSCSI logical block size512, 1024, 2048, 4096
iscsi.chapUserCHAP usernamestring
iscsi.chapSecretCHAP password (12-16 chars)string
iscsi.chapPeerUserMutual CHAP peer userstring
iscsi.chapPeerSecretMutual CHAP peer passwordstring
iscsi.initiatorsAllowed initiator IQNscomma-separated
iscsi.networksAllowed network CIDRscomma-separated

Snapshot Task Parameters

ParameterDescriptionValues
snapshot.scheduleCron schedule (5 fields)0 0 * * *
snapshot.retentionRetention period1-365
snapshot.retentionUnitRetention unitHOUR, DAY, WEEK, MONTH, YEAR
snapshot.namingNaming schemaauto-%Y-%m-%d_%H-%M
snapshot.recursiveInclude child datasetstrue, false

Encryption Parameters

ParameterDescriptionValues
encryptionEnable encryptiontrue, false
encryption.algorithmEncryption algorithmAES-256-GCM, AES-128-CCM
encryption.passphrasePassphrase (min 8 chars)string
encryption.keyHex-encoded key (64 chars)string
encryption.generateKeyAuto-generate keytrue, false

Examples

See the examples/ folder for sample configurations:

  • storageclass-nfs.yaml - Basic NFS StorageClass
  • storageclass-nfs-compressed.yaml - NFS with ZSTD compression
  • storageclass-iscsi.yaml - Basic iSCSI StorageClass
  • storageclass-iscsi-chap.yaml - iSCSI with CHAP authentication
  • storageclass-encrypted.yaml - Encrypted storage
  • pvc-nfs.yaml / pvc-iscsi.yaml - PVC examples
  • pod-with-pvc.yaml - Pod using a PVC
  • volumesnapshotclass.yaml / volumesnapshot.yaml - Snapshot examples

Building

Build the binary

make build

Build container images

# Build Alpine-based image (standard Kubernetes)
make docker-build

# Build UBI-based image (Red Hat OpenShift certification)
make build-ubi

Push to quay.io

# Login to quay.io
docker login quay.io

# Push UBI image to quay.io/truenas_solutions
make push-ubi

# Push all images (driver, operator, bundle)
make push-all

Run tests

make test

Container Images

ImageDescription
ghcr.io/truenas/truenas-csiCSI driver (Alpine-based, for standard Kubernetes)
quay.io/truenas_solutions/truenas-csiCSI driver (UBI-based, for Red Hat OpenShift)
quay.io/truenas_solutions/truenas-csi-operatorKubernetes operator
quay.io/truenas_solutions/truenas-csi-operator-bundleOLM bundle for OperatorHub

Running the Demo

For an interactive demonstration of all driver features using a local Kind cluster, see docs/demo.md.

OpenShift

The TrueNAS CSI Driver supports Red Hat OpenShift 4.20+ and is designed for OperatorHub distribution.

Quick Start (OpenShift)

  1. Install via OperatorHub

    • Navigate to Operators > OperatorHub
    • Search for "TrueNAS CSI"
    • Click Install
  2. Create credentials secret

    apiVersion: v1
    kind: Secret
    metadata:
      name: truenas-api-credentials
      namespace: truenas-csi
    stringData:
      api-key: "YOUR-API-KEY"
    
  3. Create TrueNASCSI resource

    apiVersion: csi.truenas.io/v1alpha1
    kind: TrueNASCSI
    metadata:
      name: truenas
    spec:
      truenasURL: "wss://your-truenas-ip/api/current"
      credentialsSecret: "truenas-api-credentials"
      defaultPool: "tank"
      nfsServer: "your-truenas-ip"
    

OpenShift Documentation

Demo Scripts

Interactive demo scripts are provided to test the CSI driver:

Standard Kubernetes (Kind)

# Set TrueNAS connection details in deploy/truenas-csi-driver.yaml, then:
./demo-simple.sh

OpenShift (CRC/OpenShift Local)

# Set environment variables
export TRUENAS_IP=192.168.1.100
export TRUENAS_API_KEY=your-api-key
export TRUENAS_POOL=tank

# Run the demo
./demo-openshift.sh

Both demos provide interactive menus to test NFS/iSCSI provisioning, volume expansion, snapshots, and cloning.

Contributing

License

GNU General Public License 3.0