Skip to content

local-rwx

⚠️ Pre-release — do not install in production. v0.3.0 is the first public candidate. Only kind and one k3s cluster have recorded evidence; every other distro and CNI row is untested, and data lives on one node with no replication or failover. Try it on a lab or staging cluster, run make e2e, and test with us: bugs, distro/CNI results, and real-hardware findings are what move this to a release. See docs/support.md for what is and is not covered.

local-rwx provisions Kubernetes ReadWriteMany volumes from a node's local disk through NFS-Ganesha. It deliberately does not replicate data.

Pick the right storage

local-path                 local-rwx                      replicated storage
──────────                 ─────────                      ──────────────────
local disk                 local disk                     replicated disks
RWO                        RWX over NFSv4.1               RWX / RWO
no replication             no replication                 survives node loss
lowest overhead            one NFS network hop            engine + replica fan-out

Use local-rwx when several pods need the same files and node-loss recovery can come from a backup or the source of truth. Use Longhorn, Ceph, or Mayastor when the storage layer must survive loss of the data node. Use local-rwx-hostpath for a single pod or for databases that replicate themselves; an NFS-backed class is not a database replication strategy.

Quickstart

local-rwx v0.3.0 targets Kubernetes 1.35, 1.36, and 1.37; the release support claim is made only after all three CI matrix jobs pass. Helm and the controller reject versions below 1.35. Every eligible node must have mount.nfs (nfs-common on Debian/Ubuntu or nfs-utils on RHEL/Fedora); the installed agent reports an actionable Warning when it is missing.

One command installs the pinned release:

kubectl apply -f https://raw.githubusercontent.com/p10node/local-rwx/v0.3.0/deploy/manifest/local-rwx.yaml

The same manifest is attached to every GitHub release, and a Helm chart is published to oci://ghcr.io/p10node/charts/local-rwx. Then create a volume:

kubectl apply -f - <<'YAML'
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: shared
spec:
  storageClassName: local-rwx
  accessModes: [ReadWriteMany]
  resources:
    requests:
      storage: 1Gi
YAML
kubectl wait pvc/shared --for=jsonpath='{.status.phase}'=Bound --timeout=120s

The default StorageClass uses shared mode, /var/lib/local-rwx, archiveOnDelete=true, rootSquash=true, and hard NFSv4.1 mounts. Capacity is advisory in this release. local-rwx-hostpath is a separate RWO class with WaitForFirstConsumer scheduling. Shared is the only supported RWX mode in v0.3.0; mode: dedicated is experimental and refused unless the controller runs with --enable-dedicated.

For local validation:

make verify
make e2e

Important operational facts

  • One server and one NFSv4.1 export serve PVC subdirectories on each selected data node.
  • The PV records the Service ClusterIP, not Service DNS. Service and Deployment finalizers protect this immutable endpoint.
  • Ganesha's shared export FSID and NFSv4 recovery state persist under the backing hostPath, so server restarts do not change file handles.
  • The server is non-privileged, but its required hostPath and two Linux capabilities require the dedicated local-rwx-server namespace to use Pod Security privileged enforcement.
  • NFS sec=sys is suitable for a trusted cluster, not hostile multi-tenancy.
  • Shared endpoints have no default NetworkPolicy because restrictive peers break legitimate cross-node mounts on tested Calico; dedicated endpoints get exact-selector policies allowing node IPs and pod CIDRs, but those are exposure reduction rather than workload authentication. Live placement changes have both blocked legitimate mounts and allowed outsider traffic, so dedicated isolation is not a portable release guarantee under the current architecture. Dedicated mode is therefore off by default in v0.3.0 and is not covered by release acceptance; enabling it never claims an isolation boundary.
  • Draining or losing the selected data node makes every volume on it unavailable. There is no automatic failover or replication.
  • Deleting a PVC archives its data by default. Set StorageClass parameter archiveOnDelete: "false" only when permanent removal is intended.
  • Mount options are copied into each PV at provision time. Changing a StorageClass does not update existing volumes.

See docs/modes.md, docs/runbook.md, docs/migration.md, docs/troubleshooting.md, docs/security.md, docs/support.md, docs/risks.md, and docs/comparison.md before production use.

Recovering an accidentally removed Service

The normal finalizer prevents deletion while PVs reference a Service. If an administrator forcibly removed that protection from a shared endpoint and the Service is gone, --recover reconstructs missing shared-server resources at the ClusterIPs recorded in PV annotations. Dedicated endpoint recovery is not automated in v0.3.0; restore its resources from a captured manifest or migrate/restore the data. Stop application changes first and verify that the old IP has not been allocated elsewhere.

kubectl -n local-rwx-system patch deployment local-rwx-controller --type=json \
  -p='[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--recover"}]'
kubectl -n local-rwx-system rollout status deployment/local-rwx-controller
kubectl -n local-rwx-system logs deployment/local-rwx-controller | grep 'recovered immutable NFS endpoints'

Remove the temporary --recover argument after success. Recovery fails closed if PV annotations conflict, are incomplete, or Kubernetes cannot reserve the recorded ClusterIP; do not edit PV.spec.nfs to work around that error.

Development status

Gate and implementation evidence are tracked in agents/PROGRESS.md. agents/PLAN.md remains the authoritative scope and design document.

About

Kubernetes dynamic provisioner for non-replicated ReadWriteMany (RWX) volumes backed by local node disks and served over NFS-Ganesha.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages