Block Storage
    Kubernetes

    Deploy Longhorn Storage on Kubernetes

    Run Longhorn distributed block storage on a Kubernetes cluster hosted on RamNode VPS nodes — node prep, StorageClasses, replicas, and backups.

    Longhorn is a distributed block storage system for Kubernetes. This guide covers deploying it on a kubeadm-provisioned cluster running on RamNode KVM VPS instances, across one or more RamNode regions: Atlanta (ATL), Piscataway (EWR), Seattle (PNW), Los Angeles (LAX), and Amsterdam (NLX).

    Assumption: you have a working Kubernetes cluster (1.27+) on RamNode VPS nodes, with kubectl and helm configured from your jump host. If any of that isn't true yet, say so and I'll add a cluster-bootstrap section.


    1. Regional topology consideration (RamNode-specific)

    Longhorn replicates volumes at the storage layer and is latency-sensitive between replicas. If your nodes span RamNode regions such as ATL, EWR, PNW, LAX, and NLX:

    • Do not spread a single Longhorn volume's replicas across regions — cross-region latency will tank IOPS and can trigger replica rebuilds.
    • Run one Longhorn deployment per region (i.e., regional clusters, not one global cluster), or if you must run a single multi-region cluster, use Longhorn's node/zone tagging so replicas stay within a region:
    shell
    # Label nodes by region during kubeadm join / after
    kubectl label node <node> topology.kubernetes.io/zone=atl

    Longhorn's Data Locality and anti-affinity settings key off standard topology.kubernetes.io/zone labels, so tag every node accordingly before installing.


    2. Node prerequisites

    Run on every node that will host Longhorn storage (all worker nodes, typically):

    shell
    # Ubuntu/Debian nodes
    sudo apt-get update
    sudo apt-get install -y open-iscsi nfs-common
    sudo systemctl enable --now iscsid
    
    # CentOS/RHEL/AlmaLinux nodes
    sudo yum install -y iscsi-initiator-utils nfs-utils
    sudo systemctl enable --now iscsid

    Check kernel modules Longhorn needs:

    shell
    # On each node
    sudo modprobe dm_crypt   # if you plan to use encrypted volumes
    lsmod | grep iscsi_tcp

    Extra disks

    RamNode KVM VPS plans typically ship with a single root volume. If you want Longhorn to use dedicated block storage rather than carving space out of the root disk:

    1. Attach an additional volume/disk to each VPS via your provisioning path using your provider control panel or API.
    2. Format and mount it as a dedicated Longhorn data path:
    shell
    sudo mkfs.ext4 /dev/vdb
    sudo mkdir -p /var/lib/longhorn
    echo '/dev/vdb /var/lib/longhorn ext4 defaults 0 2' | sudo tee -a /etc/fstab
    sudo mount -a

    Automate this with a configuration management role so it stays consistent across nodes rather than being done by hand.

    Pre-install check tool

    Longhorn ships an environment checker — run it before installing:

    shell
    kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.7.2/deploy/prerequisite/longhorn-iscsi-installation.yaml
    kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.7.2/deploy/prerequisite/longhorn-nfs-installation.yaml

    Pin to the Longhorn version you're actually installing — check https://github.com/longhorn/longhorn/releases for the current stable tag before running this in production.


    3. Install Longhorn (Helm)

    shell
    helm repo add longhorn https://charts.longhorn.io
    helm repo update
    
    kubectl create namespace longhorn-system
    
    helm install longhorn longhorn/longhorn \
      --namespace longhorn-system \
      --set defaultSettings.defaultDataLocality=best-effort \
      --set defaultSettings.replicaAutoBalance=best-effort \
      --set persistence.defaultClassReplicaCount=3

    For a single-region, small fleet, 3 replicas per volume is a reasonable default. For edge/DR-style nodes with fewer hosts, drop to 2 and accept the reduced fault tolerance.

    Wait for all components to come up:

    shell
    kubectl -n longhorn-system get pods -w

    4. Set as default StorageClass (optional)

    shell
    kubectl get storageclass
    kubectl patch storageclass longhorn -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

    If you're also deploying CloudNativePG, you'll likely want a dedicated, non-default StorageClass tuned for database I/O (see the CloudNativePG guide's storage section) rather than relying on this default.


    5. Access the UI

    Don't expose the Longhorn UI publicly by default — port-forward from your jump host:

    shell
    kubectl -n longhorn-system port-forward svc/longhorn-frontend 8080:80

    Then tunnel to it: ssh -L 8080:localhost:8080 jumphost. If you want persistent access, put it behind an ingress with basic auth or your existing VPN, not directly on the internet.


    6. Backups

    Longhorn backs up to an S3-compatible target. RamNode doesn't have a native object storage product, so common options:

    • Stand up a small MinIO instance on its own RamNode VPS as the backup target.
    • Point at an external S3-compatible provider.
    shell
    kubectl -n longhorn-system create secret generic longhorn-backup-secret \
      --from-literal=AWS_ACCESS_KEY_ID=<key> \
      --from-literal=AWS_SECRET_ACCESS_KEY=<secret> \
      --from-literal=AWS_ENDPOINTS=https://minio.internal.ramnode:9000

    Set the backup target in Longhorn UI (Settings → General → Backup Target) or via kubectl edit settings.longhorn.io backup-target -n longhorn-system.

    Set a RecurringJob for scheduled snapshots/backups per volume rather than relying on manual backups.


    7. Verification checklist

    shell
    kubectl -n longhorn-system get pods            # all Running
    kubectl get storageclass                        # longhorn present
    kubectl get nodes.longhorn.io -n longhorn-system # all nodes schedulable

    Create a test PVC and pod, write data, delete the pod, recreate it, confirm data persists — do this once per region before calling it production-ready.


    8. Troubleshooting notes

    • Mixed CentOS 6/7 + Ubuntu hosts: Longhorn requires a reasonably modern kernel (4.x+) with iSCSI support. CentOS 6 nodes are very likely too old to run Longhorn workers reliably — plan to exclude them or complete their AlmaLinux migration first.
    • Legacy Python interpreter issues you hit in the Ansible buildout don't affect Longhorn itself (it's all container images), but if you're automating node prep via Ansible, reuse the same ansible_python_interpreter overrides you already resolved.