Field Notes: Using the Harvester CSI Driver to consume Longhorn storage in your guest cluster

Share
Share

When running a guest Kubernetes cluster inside SUSE Virtualization/Harvester, you get the best of both worlds: bare-metal performance with VM-level flexibility. It’s a really common pattern: you installed your Rancher and downstream nodes as guest VMs and now you need to access the host storage (SUSE Storage/Longhorn).

If you’ve browsed the SUSE Rancher Apps Marketplace, you’ve likely spotted the Harvester CSI Driver Helm chart. This driver relies on Linux kernel storage utilities (specifically iSCSI) to hot-plug block storage directly from Harvester’s underlying Longhorn engine into your guest nodes.

Here is how to configure the Harvester CSI driver across a multi-OS guest environment, including Ubuntu, RHEL, and SLES.

Preparing the Guest Nodes

Before touching any Helm charts, we have to lay the groundwork. Because Longhorn provisions block storage over the network via iSCSI, every single Linux node in your guest Rancher cluster must have the iSCSI initiator running. SSH into your guest nodes and run the appropriate commands depending on their flavor:

For SUSE Linux Enterprise Server (SLES) / openSUSE

Drop into your SLES nodes and use zypper:

# zypper install -y open-iscsi
# systemctl enable --now iscsid

IMPORTANT for RWX (ReadWriteMany) Volumes: If you plan on using Harvester CSI’s newer shared filesystem capabilities (which rely on NFS under the hood), you should also grab the NFS client package on SLES: sudo zypper install -y nfs-client.

For Ubuntu / Debian

# apt-get update
# apt-get install -y open-iscsi nfs-common
# systemctl enable --now iscsid

For RHEL / CentOS / Rocky Linux

# yum install -y iscsi-initiator-utils nfs-utils
# systemctl enable --now iscsid

Step 1: Generate the Cloud Config on the Harvester Host

The Harvester CSI driver needs an identity. It requires a specific service account token to securely authenticate back to the Harvester API. We generate this configuration file directly from the Harvester host cluster management plane.

  1. Access a terminal with kubectl access to your Harvester host cluster.

  2. Download and execute Harvester’s official generation script:

# curl -LO https://raw.githubusercontent.com/harvester/harvester-csi-driver/master/deploy/generate_addon_csi.sh
# chmod +x generate_addon_csi.sh

Run the script with these parameters: <guest-cluster-name> <harvester-namespace-of-vms> [RKE2|k3s]
# ./generate_addon_csi.sh my-mixed-cluster default RKE2

(Note: If your guest cluster was built using K3s instead of RKE2, change the final argument of the script from RKE2 to k3s).

This script spits out a structured block of configuration data on how to access your Harvester cluster. Copy the output between the “### cloud-config ###” and “### cloud-init user data ##” tags to a new file named cloud-provider-config.

Step 2: Inject the Config into Your Guest Cluster

Regardless of whether a node runs SLES, Ubuntu, or RHEL, the Helm chart looks for this token locally on the guest nodes so its daemonset pods can mount it.

Method A: The Cloud-Init Way (Recommended)

If you are deploying your guest cluster via Rancher’s provisioning UI, you can automate this across all node templates. Paste the script’s output right after the “### cloud-init user data ###” tag directly into the Machine Pools > Show Advanced > User Data (Cloud-init) section. This guarantees that if your cluster autoscales with more SLES or Ubuntu nodes in the future, they will spin up with the storage config already baked in.

As a bonus, you can also add this runcmd section to your cloud-init to automate package installation and service start:

runcmd: 
  # 1. Detect the OS package manager and install iSCSI + NFS packages gracefully 
  - | 
    if command -v zypper &> /dev/null; then 
      echo "SUSE Linux Enterprise Server detected"
      zypper install -y open-iscsi nfs-client 
    elif command -v apt-get &> /dev/null; then 
      echo "Ubuntu/Debian detected" 
      apt-get update && apt-get install -y open-iscsi nfs-common 
    elif command -v dnf &> /dev/null || command -v yum &> /dev/null; then 
      echo "RHEL/Rocky/CentOS detected" 
      yum install -y iscsi-initiator-utils nfs-utils 
    fi  
  # 2. Enable and start the iSCSI daemon required by Longhorn 
  - systemctl daemon-reload 
  - systemctl enable --now iscsid

Method B: The Manual Way

If the cluster is already running and you prefer a manual approach, paste the script’s output onto every single guest node at this exact file path:

# mkdir -p /var/lib/rancher/rke2/etc/config-files
# vim /var/lib/rancher/rke2/etc/config-files/cloud-provider-config

Step 3: Deploy the Harvester CSI Driver

With the OS-level dependencies managed across your SLES and other Linux nodes, it’s time to pull the trigger on the Helm chart.

Option 1: Via the Helm CLI

Targeting your guest cluster’s kubeconfig, run the following commands to add the repository and install the chart into the kube-system namespace:

# helm repo add harvester https://charts.harvesterhci.io/
# helm repo update

# helm install harvester-csi-driver harvester/harvester-csi-driver \
  --namespace kube-system

Option 2: Via the Rancher Dashboard

  1. Open your Rancher UI and navigate to your Guest Cluster context.

  2. Go to Apps > Charts and search for Harvester CSI Driver.

  3. Click Install.

  4. You can safely leave the default values as-is; the chart automatically looks for the file path we populated in Step 2.

IMPORTANT: If you’re using SELinux

On the current version of the Helm chart, there is an issue if you’re using an OS that has SELinux enabled by default, like SLES 16.0. It causes the pods to crashloop trying to access the internal communication socket.

To fix this, run:

# kubectl patch deployment harvester-csi-driver-controllers -n kube-system \ 
   --type=merge \ 
   -p '{"spec":{"template":{"spec":{"securityContext":{"seLinuxOptions":{"type":"spc_t"}}}}}}'

Step 4: Verification & The Smoke Test

Once the Helm deployment finishes, the driver will automatically register a new default StorageClass inside your guest cluster.

Let’s verify it exists:

# kubectl get storageclass

You should see an output confirming Harvester is now your default storage provider:

NAME                  PROVISIONER               RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION
harvester (default)   driver.harvesterhci.io    Delete          Immediate           true

Testing with a Live Workload

To prove the pipeline works end-to-end across your infrastructure, let’s deploy a test PersistentVolumeClaim (PVC).

Create a file named test-pvc.yaml:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-harvester-storage
  namespace: default
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: harvester
  resources:
    requests:
      storage: 10Gi

Apply it to your guest cluster:

# kubectl apply -f test-pvc.yaml

Now, watch the status:

# kubectl get pvc test-harvester-storage -w

Within seconds, the status should flip from Pending to Bound. Behind the scenes, your guest cluster just talked to Harvester, which instructed Longhorn to carve out a 10Gi volume and hot-plug it directly into your virtual machine node, whether that node is running Ubuntu, RHEL, or SLES.

You can also go back to the Harvester console, go to Volumes and check that the new PVC is indeed there.

Wrapping Up

By leveraging the Harvester CSI driver, you eliminate the overhead of running a secondary storage solution inside your virtualized environment. Your guest applications get to feast on raw, bare-metal Longhorn performance managed cleanly through a single hyperconverged control plane, giving your SLES and multi-OS nodes native access to backend enterprise storage.

Share
(Visited 1 times, 1 visits today)
Avatar photo
1 views
Erico Mendonca Solution Architect @ SUSE