NFS and Network Storage: A Complete Guide from Homelab to the Cloud
Network storage is how you stop caring which physical machine your data lives on. Whether you’re sharing a media library across three Raspberry Pis, providing shared storage to a Kubernetes cluster, or running a high-performance computing workload that needs parallel I/O across dozens of nodes, the answer is some form of network-attached storage with a protocol that matches the access pattern.
This guide covers the full landscape: the protocols (NFS, SMB, iSCSI), the distributed filesystems (Lustre, Ceph), and how all of it maps to both homelab deployments and cloud services on Azure, AWS, and GCP. By the end you’ll be able to match any storage requirement to the right protocol and deployment model.
The Network Storage Landscape
Before diving into configuration, it helps to understand what category of problem each technology solves:
| Technology | Type | Best For |
|---|---|---|
| NFSv3 | File (NAS) | Unix/Linux file sharing, simple and fast |
| NFSv4.1/4.2 | File (NAS) | Modern Linux, Kubernetes PVs, pNFS parallel I/O |
| SMB/CIFS (Samba) | File (NAS) | Cross-platform (Windows/Mac/Linux), AD integration |
| iSCSI | Block (SAN) | VMs, databases — raw block device over TCP |
| Fibre Channel | Block (SAN) | Enterprise SAN, high throughput, not homelab |
| Ceph | Object + Block + File | Distributed, scale-out, Kubernetes RWX volumes |
| Lustre | Parallel File | HPC, large sequential I/O, hundreds of clients |
| GlusterFS | Distributed File | Scale-out NAS, simpler than Ceph |
| S3 / Object | Object | Backup, media, unstructured data at scale |
NFS: Network File System
NFS is the foundation of Unix network storage. It’s been around since 1984, is supported natively by every Linux distribution and macOS, and remains the dominant protocol for shared Linux filesystems.
NFSv3 vs NFSv4 vs NFSv4.1/4.2
| Feature | NFSv3 | NFSv4 | NFSv4.1 | NFSv4.2 |
|---|---|---|---|---|
| Stateful | No | Yes | Yes | Yes |
| Single port | No (needs portmapper) | Yes (2049) | Yes | Yes |
| Strong security | No | Yes (Kerberos) | Yes | Yes |
| File delegation | No | Yes | Yes | Yes |
| Parallel I/O (pNFS) | No | No | Yes | Yes |
| Server-side copy | No | No | No | Yes |
| Sparse files | No | No | No | Yes |
| Firewall friendly | Difficult | Easy | Easy | Easy |
NFSv3 is simpler, stateless, and faster for small deployments. It requires rpcbind and multiple ports (111, 2049, plus dynamic mountd/statd ports), making firewalling awkward.
NFSv4 uses a single TCP port (2049), is stateful with file locking, supports strong security via Kerberos, and is the right choice for any new deployment.
NFSv4.1 with pNFS (parallel NFS) allows clients to read/write directly to multiple storage devices simultaneously — used by enterprise NAS appliances and cloud file services for scale-out performance.
NFSv4.2 adds server-side copy (copy_file_range syscall avoids client→server→client round-trips), sparse file support, and improved security labels.
Setting Up an NFS Server (Linux)
|
|
/etc/exports — The Share Configuration
|
|
Key export options explained:
| Option | Meaning |
|---|---|
rw / ro |
Read-write or read-only |
sync |
Write to disk before acknowledging (safe, slower) |
async |
Acknowledge before disk write (fast, risk of data loss on crash) |
root_squash |
Map remote root to nobody (security default — use it) |
no_root_squash |
Allow remote root to act as local root (only for trusted admin hosts) |
all_squash |
Map all users to nobody (maximum restriction) |
no_subtree_check |
Don’t verify file is in exported subtree (improves reliability, minor security trade-off) |
fsid=0 |
Marks the NFSv4 pseudo-root |
crossmnt |
Allow crossing mount points within the export |
anonuid / anongid |
UID/GID to map squashed users to |
|
|
NFSv4 Pseudo-Root Setup
NFSv4’s pseudo-root lets you present all shares under a single mount point, avoiding the need for the client to know the exact server path:
|
|
|
|
Mounting NFS on Clients
|
|
/etc/fstab — Persistent Mounts
|
|
Mount option reference:
| Option | Purpose |
|---|---|
hard |
Retry indefinitely if server unreachable (vs soft which returns errors) |
intr |
Allow interrupting hung NFS operations with Ctrl+C |
timeo=600 |
Timeout in deciseconds (60s) before retrying |
retrans=2 |
Retransmit count before returning an error |
rsize=1048576 |
Read block size (1MB — much faster than default 128KB) |
wsize=1048576 |
Write block size |
proto=tcp |
Use TCP (default for NFSv4, more reliable than UDP) |
nfsvers=4.2 |
Request NFSv4.2 specifically |
_netdev |
Wait for network before mounting |
auto |
Mount at boot |
nofail |
Don’t halt boot if mount fails (useful for optional shares) |
Automount with systemd
Automounting mounts the share on first access and unmounts it after a timeout — useful for shares that aren’t always needed:
|
|
|
|
|
|
NFS Performance Tuning
|
|
Benchmarking NFS
|
|
NFS Security: Kerberos Authentication
By default NFS uses AUTH_SYS — it trusts the client’s claimed UID/GID. Any client on your network can claim to be any user. For a trusted homelab LAN, this is usually fine. For multi-tenant environments, Kerberos (sec=krb5) provides real authentication.
|
|
Setting up a full Kerberos KDC is beyond most homelab needs. For homelab security, combining NFS with a WireGuard VPN tunnel (so only VPN peers can reach the NFS server) achieves similar isolation with much less complexity.
Samba / SMB: Cross-Platform File Sharing
Samba implements the SMB (Server Message Block) protocol, allowing Linux servers to share files with Windows, macOS, and other Linux systems using the same protocol built into every Windows installation.
Installing and Configuring Samba
|
|
|
|
|
|
Mounting SMB on Linux
|
|
iSCSI: Block Storage Over TCP
Where NFS shares a filesystem, iSCSI shares a raw block device. The client (initiator) sees what looks like a local disk; the OS formats it with any filesystem. This is the right choice for VMs and databases that need a dedicated block device.
Key Concepts
- Target: The server exposing the block device
- Initiator: The client connecting to and using the block device
- LUN (Logical Unit Number): The specific block device being shared
- IQN (iSCSI Qualified Name):
iqn.2026-01.arpa.home:storage.lun01
Setting Up an iSCSI Target (TGT)
|
|
|
|
|
|
Connecting an iSCSI Initiator (Client)
|
|
iSCSI Performance Considerations
iSCSI performance is highly sensitive to network quality. For homelab use:
- Dedicate a VLAN or a separate NIC to iSCSI traffic
- Use jumbo frames (MTU 9000) on the iSCSI network — significant throughput improvement
- Enable iSCSI multipath (
multipathd) for both redundancy and throughput with multiple NICs
|
|
Lustre: High-Performance Parallel Filesystem
Lustre is the dominant filesystem in high-performance computing (HPC). If you’ve ever used a national supercomputer or a large cloud HPC cluster, you’ve almost certainly used Lustre. It’s designed for one thing: delivering maximum aggregate bandwidth to many clients simultaneously.
Lustre Architecture
┌─────────────────────────────────────────────────────────┐
│ Lustre Filesystem │
├──────────────────┬──────────────────────────────────────┤
│ MGS │ Management Server │
│ (1 node) │ Stores configuration, startup info │
├──────────────────┼──────────────────────────────────────┤
│ MDS + MDT │ Metadata Server + Metadata Target │
│ (1–many nodes) │ Directory structure, file metadata │
├──────────────────┼──────────────────────────────────────┤
│ OSS + OST │ Object Storage Server + Target │
│ (many nodes) │ Actual file data, striped across │
│ │ multiple OSTs for parallel I/O │
├──────────────────┼──────────────────────────────────────┤
│ Clients │ Mount lustre:/ using Lustre client │
│ (thousands) │ Each file striped across N OSTs │
└──────────────────┴──────────────────────────────────────┘
A file in Lustre is striped across multiple OSTs. Reading a 10 GB file with stripe count 8 means 8 OSS nodes each serve 1.25 GB simultaneously — aggregate read bandwidth scales with the number of OSTs.
Lustre in a Homelab
Running full production Lustre requires at least 4–5 nodes (MGS, MDS, 2+ OSS, clients). That’s more than most homelabs have, but a minimal single-node Lustre setup is useful for learning and small experiments.
Minimum homelab Lustre cluster:
- 1 node: MGS + MDS + 2 OSTs (can all be on one server for testing)
- 1+ client nodes
|
|
Lustre Striping
The power of Lustre is striping. Set the stripe count based on your access pattern:
|
|
Lustre for ML/AI Workloads
Lustre is the storage choice for large-scale machine learning training — reading hundreds of gigabytes of training data at maximum speed. The key tunables:
|
|
Lustre in the Cloud
AWS FSx for Lustre: Fully managed Lustre on AWS. Integrated with S3 — you can transparently read S3 objects as Lustre files. Ideal for ML training jobs that read from S3.
|
|
Azure HPC Cache: Microsoft’s managed NFS/Lustre caching layer for HPC workloads on Azure. Sits in front of Azure Blob Storage or on-premises NFS servers and presents a cached NFS mount to compute nodes.
Google Cloud Lustre (via DDN, WekaFS): GCP doesn’t offer native managed Lustre but partners like DDN (EXAScaler) and WekaFS provide high-performance parallel filesystems on GCP for HPC and AI workloads.
Ceph: The Software-Defined Storage Platform
Ceph is the Swiss Army knife of distributed storage. It provides object storage (S3-compatible), block storage (RBD), and a POSIX filesystem (CephFS) from a single storage cluster. It’s designed to scale from a few nodes to thousands, with no single point of failure.
Ceph Architecture
┌─────────────────────────────────────────────────┐
│ Ceph Cluster │
├───────────────┬─────────────────────────────────┤
│ MON nodes │ Monitors — cluster map, quorum │
│ (3 or 5) │ (like etcd for Ceph) │
├───────────────┼─────────────────────────────────┤
│ MGR nodes │ Managers — metrics, dashboard │
├───────────────┼─────────────────────────────────┤
│ OSD nodes │ Object Storage Daemons │
│ (1 per disk) │ Store actual data, replication │
├───────────────┼─────────────────────────────────┤
│ MDS nodes │ Metadata Servers (CephFS only) │
└───────────────┴─────────────────────────────────┘
Access methods:
RADOS Gateway (RGW) → S3-compatible object storage
RBD (RADOS Block Device) → Block storage for VMs
CephFS → POSIX filesystem (NFS-like, usable as Kubernetes RWX PV)
Homelab Ceph with Rook
Rook is the most practical way to run Ceph in a homelab Kubernetes cluster — it deploys and manages Ceph as Kubernetes operators:
|
|
|
|
|
|
With these storage classes, Kubernetes pods can claim RWO (ReadWriteOnce) block volumes via rook-ceph-block and RWX (ReadWriteMany) shared volumes via rook-cephfs — the latter allows multiple pods on different nodes to share the same filesystem.
Cloud Network Storage: Azure, AWS, and GCP
Each cloud provider offers managed equivalents of the storage protocols above. Understanding the mapping helps you choose the right service.
Azure File Storage Options
Azure Files
Managed SMB and NFS file shares backed by Azure Blob Storage:
|
|
Azure Files tiers:
- Transaction Optimized: Standard HDD, cheap, high-latency — good for cold storage and backups
- Hot / Cool: Standard SSD-backed — general purpose file shares
- Premium: NVMe-backed, <1ms latency — databases, VMs, low-latency apps
Azure NetApp Files (ANF)
ANF is enterprise-grade NFS/SMB for latency-sensitive and high-throughput workloads. It’s based on NetApp ONTAP technology running natively in Azure datacenters.
|
|
ANF features relevant to enterprise homelab overflow:
- Snapshot policies: Automated hourly/daily/weekly snapshots with retention
- Cross-region replication: Async replication of volumes to a paired region
- Capacity pools: Pool of provisioned capacity; volumes carved from the pool
- Performance tiers: Standard (16 MiB/s per TiB), Premium (64 MiB/s per TiB), Ultra (128 MiB/s per TiB)
ANF pricing is high (~$0.245/GiB/month for Premium vs ~$0.06/GiB for Azure Files Premium) but justified for workloads needing Oracle, SAP HANA, or HPC performance.
Azure HPC Cache
For HPC workloads on Azure that read from on-premises NFS or Azure Blob Storage, Azure HPC Cache acts as a caching tier — presenting a fast NFS mount to compute VMs that caches data from slower backends:
On-premises NFS / Azure Blob → Azure HPC Cache → VM Compute Nodes (NFS mount)
The cache is sized in TiB (3–48 TiB) and handles cache invalidation, write-back, and namespace aggregation transparently.
AWS File Storage Options
Amazon EFS (Elastic File System)
EFS is fully managed NFSv4 — you mount it like any NFS server, it scales automatically, and you pay per GB stored:
|
|
EFS performance modes:
- General Purpose: Low latency, up to 35K IOPS — most workloads
- Max I/O: Higher aggregate throughput, slightly higher latency — parallel workloads with many clients
- Elastic throughput (new default): Automatically scales to workload, no provisioning needed
- Provisioned throughput: Set a specific throughput baseline for predictable workloads
Amazon FSx Family
AWS offers four managed FSx variants:
| FSx Type | Protocol | Best For |
|---|---|---|
| FSx for Windows | SMB | Windows workloads, AD-integrated |
| FSx for Lustre | Lustre | HPC, ML training, S3 integration |
| FSx for NetApp ONTAP | NFS + SMB + iSCSI | Multi-protocol, snapshots, tiering |
| FSx for OpenZFS | NFS | ZFS snapshots, clones, compression |
FSx for Lustre is particularly powerful for ML workloads — it can lazily import data from S3, so the first read of a file pulls it from S3 and caches it on the Lustre filesystem:
|
|
GCP File Storage Options
Google Cloud Filestore
Managed NFS — similar to EFS but for GCP:
|
|
Filestore tiers:
- Basic HDD: $0.20/GiB/month, 100 MiB/s, 600 IOPS
- Basic SSD: $0.30/GiB/month, 480 MiB/s, 25K IOPS
- High Scale SSD: Petabyte-scale, 10 GiB/s+, Lustre-like performance
- Enterprise: 99.99% SLA, multi-zone redundancy, snapshots
Kubernetes Persistent Volumes: Tying It Together
All of these storage options surface in Kubernetes as PersistentVolumes. Here’s how to use them:
NFS PersistentVolume (Static)
|
|
Dynamic NFS Provisioning with nfs-subdir-external-provisioner
|
|
|
|
CSI Drivers for Cloud Storage
|
|
Choosing the Right Protocol: A Decision Framework
What's the primary access pattern?
├── File access (open, read, write, seek)
│ ├── Linux/Unix clients only?
│ │ ├── Single server → NFSv4.2
│ │ ├── Kubernetes RWX volumes → CephFS or NFS
│ │ └── HPC / parallel I/O → Lustre (or FSx for Lustre on AWS)
│ └── Mixed Linux + Windows + macOS?
│ └── Samba (SMB 3.x)
│
├── Block access (raw disk, VM storage, databases)
│ ├── Local (same server) → LVM, ZFS zvol
│ ├── Network SAN → iSCSI
│ └── Cloud / Kubernetes RWO → Ceph RBD, EBS, Azure Disk
│
└── Object access (S3 API, unstructured data)
├── Self-hosted → MinIO, Ceph RGW
├── AWS → S3
├── Azure → Azure Blob Storage
└── GCP → Google Cloud Storage
Homelab Reference Architecture
A practical homelab storage stack combining multiple protocols:
NAS Server (ZFS pool: tank, raidz2, 4× 4TB HDDs)
├── NFS Server
│ ├── /export/media → All Pis and K3s nodes (media apps)
│ ├── /export/appdata → K3s nfs-provisioner (dynamic PVCs)
│ └── /export/k8s → Longhorn fallback, Kubernetes static PVs
│
├── Samba Server
│ ├── \\nas\media → Windows/macOS clients
│ └── \\nas\backups → Time Machine target (macOS)
│
├── iSCSI Target
│ └── LUN backed by ZFS zvol → Proxmox VMs (high-performance VM disks)
│
└── Litestream
└── SQLite WAL replication → Hetzner Object Storage (off-site)
K3s Cluster (Rook/Ceph on NVMe SSDs)
├── rook-ceph-block → RWO PVCs (databases, single-writer apps)
└── rook-cephfs → RWX PVCs (shared config, media mounts)
Cloud Overflow (Hetzner)
└── Hetzner Object Storage → Restic backups, Litestream, static assets
Network storage complexity scales with your needs. Start with a simple NFS share from a Linux box or NAS appliance — that covers 90% of homelab use cases. Add iSCSI when you need raw block devices for VMs. Add Ceph (via Rook) when you need distributed storage that survives node failures. Reach for Lustre only when you have genuine high-performance parallel I/O requirements and multiple storage nodes to dedicate to it.
The cloud equivalents mirror this ladder exactly: EFS/Azure Files for shared file storage, EBS/Azure Disk for block, and FSx for Lustre when you need HPC-grade parallel I/O. Knowing the on-premises version makes the cloud version trivial to understand and operate.
Comments