Longhorn is a free and open-source storage system built for Kubernetes. It turns normal disks on your servers into safe and replicated storage that your pods can use. This guide provides a full Longhorn K3s setup NVMe build, from a clean multi-node cluster to a working backup target.
How to Install Longhorn on K3s with Dedicated NVMe Storage
Table of Contents
- Why Use Longhorn with Dedicated NVMe Disks
- What You Need Before You Start
- Step 1: Prepare Your NVMe Disks on Each Node
- Step 2: Install Required Packages on Every Node
- Step 3: Install K3s on the Master Node
- Step 4: Join Worker Nodes to the Cluster
- Step 5: Install Longhorn K3s Setup NVMe with Helm
- Step 6: Open the Longhorn Dashboard
- Step 7: Add and Tag Your Dedicated NVMe Disks
- Step 8: Create a Custom StorageClass with Replica Count and Tags
- Step 9: Create a Test Volume and Check It Works
- Step 10: Test Real Node Failover
- Step 11: Configure an S3-Compatible Backup Target
- Step 12: Take and Verify a Backup
- Best Practices for Production Clusters
- Conclusion

Why Use Longhorn with Dedicated NVMe Disks
A proper Longhorn K3s setup NVMe build uses separate physical NVMe drives just for storage, so your operating system disk stays untouched and fast.
NVMe drives give much lower latency than normal SSDs or spinning disks. Since Longhorn writes data to multiple replicas across nodes, disk speed matters a lot. Slow disks make every write wait longer.
If you are picking new hardware, servers like PerLod dedicated servers come with NVMe drives and private networking, which is exactly what replicated Kubernetes storage needs for fast and safe replica traffic between nodes.
What You Need Before You Start
For the Longhorn K3s setup NVMe build, make sure you have:
- At least 3 physical or virtual servers. 1 master node and 2+ worker nodes. Longhorn needs 3 nodes to keep 3 replicas of data.
- Ubuntu 24.04 LTS or newer on every node.
- A separate and unused NVMe disk on each storage node. For example,
/dev/nvme1n1, not the OS disk. - Root or sudo access on every node.
- Private networking between nodes for fast replica sync, with a public IP only on the node you will manage from.
- At least 4 GB RAM and 2 CPU cores per node.
Step 1: Prepare Your NVMe Disks on Each Node
The first step is to find and check your extra NVMe disk on every worker node. Do not format your OS disk.
Look for a disk with no mount point, such as nvme1n1. Format it with the ext4 filesystem, which Longhorn supports well:
You must make the mount permanent by adding it to /etc/fstab. First, get the disk UUID:
Then add the following line with your UUID to /etc/fstab:
Reload systemd's view of mounts and verify the entry mounts correctly:
Repeat this on every node that will provide storage. This dedicated disk step is what makes a Longhorn K3s setup NVMe deployment behave like a real production cluster.
Step 2: Install Required Packages on Every Node
Longhorn needs open-iscsi and nfs-common on every node, including the master node. These packages let Longhorn attach volumes and support backup mounts. Install them with the commands below:
Make sure iscsid is active and running. If your servers use multipath, add Longhorn's disks to its blacklist. If you skip this, multipath can grab the disks and cause attach errors on bare-metal servers.
Step 3: Install K3s on the Master Node
On your master node, use the command below to install K3s using the official install script. This installs the current stable K3s release automatically:
Then, run the following command to verify it is running:
Get the node token, which the other nodes need to join the cluster:
Also, note your master node's private IP address, using ip a.
Step 4: Join Worker Nodes to the Cluster
On each worker node, run the K3s agent install command and replace the IP and token with your own values from Step 3:
Then, from the master node, confirm all nodes joined and are Ready:
You should see one master node and your worker nodes, all marked Ready. You need this multi-node setup for a real Longhorn K3s setup NVMe test, because a single-node cluster cannot show true replica failover.
Tips: Teams that run virtual machines on the same cluster can check this guide on running KubeVirt VMs on K3s. It shows how to set up VM and container workloads on the same nodes.
Step 5: Install Longhorn K3s Setup NVMe with Helm
Now install Longhorn itself using Helm, which is the most reliable install method. First, install Helm if you do not have it yet:
Set your kubeconfig so helm and kubectl can talk to your K3s cluster:
Then, add the Longhorn Helm repository and update it:
Install the current stable Longhorn release into its own namespace:
This installs Longhorn, the current stable release at the time of writing. Watch the pods start up:
Wait until all pods show Running. This can take a few minutes on the first install since Longhorn pulls several container images to every node.
Step 6: Open the Longhorn Dashboard
Longhorn has its own web dashboard. K3s does not set up a load balancer on its own, so use kubectl port-forward to open the dashboard from your system:
Open http://localhost:8080 in your browser. You should see the Longhorn dashboard listing your nodes and their disks.
Step 7: Add and Tag Your Dedicated NVMe Disks
By default, Longhorn tries to use free space on the root disk of each node, which you do not want. Go to the Longhorn UI, click Node, select a worker node, and click Edit Node and Disks.
Remove the default disk if it points at the root filesystem. Then click Add Disk and point it at your NVMe mount path:
- Path:
/mnt/longhorn-nvme - Add a disk tag:
nvme
Repeat this for every storage node. Adding disk tags is what lets you later force specific volumes to only use NVMe disks.
Also, you can do this with kubectl instead of the UI:
While you are in the Node view, add a node tag like "storage" to each node that should hold Longhorn replicas. This helps if some nodes are only for running apps, not for storing data.
Step 8: Create a Custom StorageClass with Replica Count and Tags
The default Longhorn StorageClass works, but for real use you should make your own. This lets you control how many replicas you get and which disks are used. Create the file on your master node with this command:
Then, apply it with the command below:
numberOfReplicas: "3"keeps three copies of every volume, spread across three different nodes.diskSelector: "nvme"forces replicas onto disks taggednvmeonly.nodeSelector: "storage"forces replicas onto nodes taggedstorageonly.
This combination is the core of a correct Longhorn K3s setup NVMe design. Fast disks, spread-out copies, and no accidental use of slow root-disk space.
Step 9: Create a Test Volume and Check It Works
At this point, you can create a small test app with a PersistentVolumeClaim using your new StorageClass. Create the file with this command:
Apply it and check the volume is Bound and the pod is Running:
In the Longhorn UI, open Volume, find your new volume, and confirm it shows 3 healthy replicas on 3 different nodes.
Step 10: Test Real Node Failover
Pick the node currently running nvme-test-pod. Then, act like it failed by turning it off or by draining it:
Kubernetes will reschedule nvme-test-pod onto a healthy node. Longhorn already kept a full copy of the data on another node. So when the pod comes back, its data is still there:
You should still see hello-longhorn. This confirms your replicas are truly independent copies, not just a single disk pretending to be redundant. Once you are done testing, bring the node back:
Step 11: Configure an S3-Compatible Backup Target
Replicas protect you from a node failing. Backups protect you from a whole cluster failing, a bad kubectl delete, or ransomware. Longhorn supports AWS S3, MinIO, Backblaze, and other S3-compatible storage as a backup target.
First, create a Kubernetes secret with your S3 credentials:
Leave AWS_ENDPOINTS empty if you are using real AWS S3. Set it to your provider's URL if you use MinIO, Backblaze, or another S3-compatible service.
Now point Longhorn at your bucket with the command below:
Make sure the S3 URL ends with a /, or Longhorn will show a connection error. You can check the result in the Longhorn UI under Settings > General > Backup Target.
Step 12: Take and Verify a Backup
Go to the Longhorn UI, open Volume, select your test volume, and click Create Backup. Once it finishes, open Backup in the left menu. You should see your backup listed with a timestamp and size.
To automate this instead of clicking manually, you can create a recurring backup job. Create the file with this command:
Apply it with the command below:
This runs a backup every night at 2 AM and keeps the last 7 copies, which gives you a real recovery point if something goes wrong.
Best Practices for Production Clusters
- Always use at least 3 storage nodes so
numberOfReplicas: 3can actually spread data across separate hardware. - Keep the Longhorn NVMe disks separate from the OS disk, so a full OS disk never blocks storage writes.
- Set CPU and memory requests on
longhorn-managerandengine-imagepods on busy clusters, so they are not starved by other workloads. - Test failover and backup restore regularly, not just once during setup. A backup you have never restored is not a proven backup.
- Use private networking between nodes for replica traffic, which lowers latency and keeps storage traffic off your public network.
Conclusion
You now have a full Longhorn K3s NVMe cluster setup. Including multiple nodes, tagged NVMe disks, a custom StorageClass with 3 replicas, a tested node failure, and auto backups to S3. This is how real production storage runs on bare metal, not just a single-node demo.
Next, you can add more storage nodes, change replica counts, or send backups to a disaster-recovery cluster elsewhere.
We hope you enjoy this guide. For more detailed information, you can check the Official Longhorn Documentation.