longhorn
This example shows you how to deploy Longhorn using Zarf.
Before deploying Longhorn, make sure your nodes are configured with the Longhorn Installation Requirements. You can verify this automatically with Longhorn’s own preflight checker: install longhornctl and run longhornctl check preflight --kubeconfig=<path-to-your-kubeconfig> against the target cluster before deploying this package. It requires a real kubeconfig (it self-deploys its own short-lived DaemonSet across the cluster to run the checks), so it isn’t included as a Zarf component here. Run it from your workstation as a pre-deploy step instead.
You will need open-iscsi installed.
If you wish to support RWX access modes you’ll need to install an NFSv4 client on each node.
If you’re working with K3s, there is extra setup required. See Longhorn CSI on K3s.
The values file from this example was pulled using the directions at Customizing Default Settings as the path for kubelet needs to be set for K3s as per Longhorn CSI on K3s
You do not need to use the values file and can remove it from the Zarf package configuration if you’re not using K3s and don’t need that variable set.
The global.imageRegistry value in values.yaml is set to Zarf’s ###ZARF_REGISTRY### template variable. Zarf’s mutating webhook already rewrites container image references on admission, so this value isn’t needed for images to be pulled correctly. The webhook redirects any pod’s image regardless of this setting. However, longhorn-manager is also passed its own expected image as a --manager-image command-line flag (rendered from this same global.imageRegistry value, independent of the webhook), which it compares against its own running pod’s image to detect stale manager instances during upgrades. If global.imageRegistry is left unset, that flag never matches the webhook-rewritten pod image, and longhorn-manager gets stuck permanently treating its own fresh pod as stale. So this value is required for longhorn-manager’s own bootstrap logic, not just image resolution, and should not be removed.
zarf.yaml
kind: ZarfPackageConfigmetadata: name: longhorn description: Example package for Longhorn cloud native distributed block storage for Kubernetes version: 1.11.2components: - name: longhorn required: true description: Deploy Longhorn into a Kubernetes cluster. https://longhorn.io actions: # Set the delete confirmation flag for Longhorn onRemove: before: - cmd: './zarf tools kubectl -n longhorn-system patch -p ''{"value": "true"}'' --type=merge lhs deleting-confirmation-flag' onDeploy: after: - description: Longhorn EngineImages to finish deploying on every node maxTotalSeconds: 300 wait: cluster: kind: engineimages.longhorn.io name: longhorn.io/component=engine-image namespace: longhorn-system condition: "{.status.state}=deployed" - description: Longhorn InstanceManagers to finish starting on every node maxTotalSeconds: 300 wait: cluster: kind: instancemanagers.longhorn.io name: longhorn.io/component=instance-manager namespace: longhorn-system condition: "{.status.currentState}=running" manifests: - name: longhorn-connect namespace: longhorn-system files: - connect.yaml charts: - name: longhorn url: https://charts.longhorn.io version: 1.11.2 namespace: longhorn-system valuesFiles: - values.yaml images: - longhornio/csi-attacher:v4.11.0-20260428 - longhornio/csi-provisioner:v5.3.0-20260428 - longhornio/csi-resizer:v2.1.0-20260428 - longhornio/csi-snapshotter:v8.5.0-20260428 - longhornio/csi-node-driver-registrar:v2.16.0-20260428 - longhornio/livenessprobe:v2.18.0-20260428 - longhornio/backing-image-manager:v1.11.2 - longhornio/longhorn-engine:v1.11.2 - longhornio/longhorn-instance-manager:v1.11.2 - longhornio/longhorn-manager:v1.11.2 - longhornio/longhorn-share-manager:v1.11.2 - longhornio/longhorn-ui:v1.11.2 - longhornio/support-bundle-kit:v0.0.84
documentation: readme: readme.md