Panduan Lengkap Deploy NFS Server di Kubernetes

Dalam artikel ini kita akan membahas bagaimana cara deploy NFS Server di Kubernetes untuk penyimpanan bersama (shared storage). Kali ini kita tidak menggunakan DNS service name, tapi langsung menggunakan ClusterIP agar lebih stabil di baremetal. 🔒
🔹 Kenapa NFS?
NFS (Network File System) memungkinkan beberapa pod di Kubernetes mengakses volume yang sama secara bersamaan. Ini cocok untuk aplikasi seperti WordPress, Nextcloud, atau microservices yang butuh shared storage.
Kelebihan NFS di Kubernetes:
- ✅ Support ReadWriteMany (RWX) ➝ bisa diakses banyak pod sekaligus.
- ✅ Lebih fleksibel untuk cluster baremetal.
- ✅ Integrasi langsung dengan PersistentVolume (PV) & PersistentVolumeClaim (PVC).
📂 Struktur File
Kita akan menggunakan folder nfs-server
berisi file berikut:
nfs-server/
├── nfs-server.yaml # Deployment & Service untuk NFS server
├── pv-test.yaml # PersistentVolume (PV)
├── pvc-test.yaml # PersistentVolumeClaim (PVC)
└── pod-test.yaml # Pod dummy untuk testing
🛠️ Step 1 – Install NFS di Node Worker
Sebelum menjalankan NFS server di dalam Kubernetes, pastikan node worker yang akan dipakai sudah punya package NFS:
🔧 Untuk Ubuntu/Debian
apt-get update && apt-get install -y nfs-common
🔧 Untuk CentOS/RHEL
yum install -y nfs-utils
Lalu buat direktori untuk shared storage di host:
mkdir -p /srv/nfs
chown nobody:nogroup /srv/nfs
chmod 755 /srv/nfs
📌 Dengan cara ini, direktori aman tapi tetap bisa diakses pod melalui NFS.
🛠️ Step 2 – Deploy Namespace & NFS Server
File: nfs-server.yaml
apiVersion: v1
kind: Namespace
metadata:
name: nfs
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-server
namespace: nfs
spec:
replicas: 1
selector:
matchLabels:
app: nfs-server
template:
metadata:
labels:
app: nfs-server
spec:
containers:
- name: nfs-server
image: k8s.gcr.io/volume-nfs:0.8
ports:
- containerPort: 2049
- containerPort: 20048
- containerPort: 111
securityContext:
privileged: true
volumeMounts:
- name: nfs-data
mountPath: /exports
volumes:
- name: nfs-data
hostPath:
path: /srv/nfs
type: DirectoryOrCreate
---
apiVersion: v1
kind: Service
metadata:
name: nfs-service
namespace: nfs
spec:
selector:
app: nfs-server
ports:
- name: nfs
port: 2049
targetPort: 2049
- name: mountd
port: 20048
targetPort: 20048
- name: rpcbind
port: 111
targetPort: 111
👉 Setelah apply:
kubectl apply -f nfs-server.yaml
kubectl get svc -n nfs nfs-service
Contoh hasil:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nfs-service ClusterIP 10.98.3.153 <none> 2049/TCP,20048/TCP,111/TCP 27m
📌 Simpan ClusterIP (10.98.3.153
) ➝ akan dipakai di PV.
🛠️ Step 3 – Buat PersistentVolume (PV)
File: pv-test.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs-test
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
nfs:
server: 10.98.3.153
path: "/"
persistentVolumeReclaimPolicy: Retain
Apply:
kubectl apply -f pv-test.yaml
🛠️ Step 4 – Buat PersistentVolumeClaim (PVC)
File: pvc-test.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-nfs-test
namespace: nfs
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
Apply:
kubectl apply -f pvc-test.yaml
Cek binding:
kubectl get pv
kubectl get pvc -n default
Hasilnya harus Bound ✅
[root@master ~]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
pv-nfs-test 1Gi RWX Retain Bound nfs/pvc-nfs-test <unset> 26m
[root@master ~]# kubectl get pvc -n nfs
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
pvc-nfs-test Bound pv-nfs-test 1Gi RWX <unset> 27m
🛠️ Step 5 – Test dengan Pod Dummy
File: pod-test.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-nfs
namespace: default
spec:
containers:
- name: busybox
image: busybox
command: [ "sleep", "3600" ]
volumeMounts:
- name: nfs-test
mountPath: /mnt/nfs
volumes:
- name: nfs-test
persistentVolumeClaim:
claimName: pvc-nfs-test
Apply:
kubectl apply -f pod-test.yaml
Masuk ke pod dan coba:
kubectl exec -it test-nfs -- sh
/ # echo "halo-nfs" > /mnt/nfs/test.txt
/ # cat /mnt/nfs/test.txt
halo-nfs
✅ Berhasil! Data tersimpan di /srv/nfs
pada node host.

🔐 Kesimpulan
Dengan cara ini:
- 📦 NFS server jalan di dalam cluster.
- 🔑 Semua aplikasi bisa share data via PVC.
- 🛡️ Kita pakai ClusterIP langsung ➝ lebih simpel, tidak tergantung DNS.
- 🔒 Permission direktori lebih aman (
nobody:nogroup
,755
) dibanding777
.
🔥 Jadi setiap kali deploy aplikasi (WordPress, Nextcloud, dsb), tinggal claim PVC ini dan langsung dapat shared storage.

🚀 Apa itu K3s? K3s adalah distribusi Kubernetes ringan dari Rancher yang dirancang untuk mempermudah proses instalasi dan penggunaan Kubernetes….

Buat kamu yang lagi Deploy aplikasi dengan Next.js dan pengen jalan di Kubernetes dengan domain custom + SSL otomatis, artikel…
Nice mas, thanks ya
siap mas