TL;DR

NFS and CIFS/SMB are common shared filesystem backends for ReadWriteMany workloads. Most incidents are DNS/routing, export/share permissions, node missing mount tools, UID/GID mismatch, or stale mounts.

When To Use

BackendGood forWatch out
NFSLinux shared files, simple RWX, on-prem exports.UID/GID permissions, locking, server throughput.
CIFS/SMBWindows shares, Azure Files, mixed environments.Credentials, mount options, file mode behavior.
Block volumeDatabases needing low-latency RWO storage.Usually cannot mount RWX across nodes.

Static NFS PV

yamlnfs-static-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-reports-pv
spec:
  capacity:
    storage: 500Gi
  accessModes:
    - ReadWriteMany # Multiple Pods/nodes can mount read-write.
  persistentVolumeReclaimPolicy: Retain # Keep data if PVC is deleted.
  storageClassName: nfs-static
  mountOptions:
    - nfsvers=4.1 # Match what the server supports.
    - hard # Retry indefinitely; common for data integrity.
  nfs:
    server: 10.20.30.40 # NFS server IP or resolvable DNS name.
    path: /exports/reports # Exported directory on the NFS server.
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: reports
  namespace: app
spec:
  accessModes: ["ReadWriteMany"]
  storageClassName: nfs-static
  resources:
    requests:
      storage: 100Gi

CIFS / SMB PV

yamlsmb-pv.yaml
apiVersion: v1
kind: Secret
metadata:
  name: smb-credentials
  namespace: app
type: Opaque
stringData:
  username: DOMAIN\\svc-k8s # Use the service account provided by the client.
  password: change-me # Store real value in external secret manager when possible.
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: smb-share-pv
spec:
  capacity:
    storage: 100Gi
  accessModes: ["ReadWriteMany"]
  persistentVolumeReclaimPolicy: Retain
  storageClassName: smb-static
  csi:
    driver: smb.csi.k8s.io
    volumeHandle: smb-share-prod # Unique ID for this share in the cluster.
    volumeAttributes:
      source: //fileserver.example.com/shared # SMB UNC path.
    nodeStageSecretRef:
      name: smb-credentials
      namespace: app

Node-Level Checks

bashnode-mount-checks.sh
# Kubernetes-side symptoms.
kubectl describe pod <pod> -n app # Look for FailedMount and permission errors.
kubectl describe pvc reports -n app
kubectl get events -n app --sort-by=.lastTimestamp | grep -i -E 'mount|volume|nfs|smb|cifs'

# If you have node shell access:
which mount.nfs || rpm -q nfs-utils || dpkg -l nfs-common # NFS mount helper must exist.
which mount.cifs || rpm -q cifs-utils || dpkg -l cifs-utils # CIFS mount helper must exist.
showmount -e 10.20.30.40 # Lists NFS exports if server allows it.
sudo mount -t nfs4 10.20.30.40:/exports/reports /mnt # Manual NFS mount test.
sudo dmesg | tail -50 # Kernel mount errors often show real cause.

Permissions Pattern

yamlpod-fsgroup.yaml
apiVersion: v1
kind: Pod
metadata:
  name: report-writer
  namespace: app
spec:
  securityContext:
    runAsUser: 1000 # App process UID.
    runAsGroup: 1000 # App process primary GID.
    fsGroup: 2000 # Kubernetes asks the volume to be group-owned/readable where supported.
  containers:
    - name: writer
      image: busybox:1.36
      command: ["sh", "-c", "echo ok >> /reports/health.txt; sleep 3600"]
      volumeMounts:
        - name: reports
          mountPath: /reports
  volumes:
    - name: reports
      persistentVolumeClaim:
        claimName: reports

Gotchas

  • !NFS export permissions and Kubernetes Pod permissions both matter; fix both sides.
  • !Root squash can make root inside the container unable to write to the export.
  • !RWX does not mean infinite performance. Shared filesystems can become the bottleneck.
  • !CIFS credentials in Secrets need the same protection as database passwords.