Share Notes

chundev

View the Project on GitHub latteouka/share-notes

Synology NFS 給 Kubernetes 用的正確設定

日期:2026-05-21 環境:Synology DSM 7.x + K3s + NFS CSI Driver(nfs.csi.k8s.io


TL;DR

把 Synology NAS 當 Kubernetes 的 NFS 儲存時,最大的觀念陷阱是「NFS 不靠帳號密碼認證,靠的是 IP 白名單」。設定的關鍵不在開帳號,而在共享資料夾的 NFS 權限規則:放行 K8s 節點網段、squash 設成 map-to-admin、開「非特權連接埠」和「子資料夾存取」兩個選項,否則 CSI driver 動態建子目錄會 permission denied 或根本連不上。


背景

雲原生平台常用 NAS 當低 IOPS 大容量儲存(例如 Elasticsearch cold tier、資料庫備份)。比起在每個節點搞 Longhorn 之類的 replicated storage,直接用 NFS CSI 掛 NAS 更單純 —— NAS 本身有 RAID,不需要 K8s 層再做 replica,也避免多節點掛同一 NAS 造成的 disk UUID 衝突。

但 NFS 的權限模型跟 SMB/AFP 完全不同,第一次設定很容易卡在「掛得上但寫不進去」或「節點根本連不到」。


觀念釐清:NFS ≠ 帳號認證

  SMB / AFP NFS
認證方式 帳號 + 密碼 來源 IP / host 白名單
權限粒度 使用者 / 群組 export 規則 + UID/GID squash
K8s 怎麼連 掛載時帶 credentials 節點 IP 落在白名單內即可掛

所以「開一個新帳號讓 K8s 用」這個直覺對 NFS 不適用。K8s 節點能不能掛 NFS,取決於「Synology 共享資料夾的 NFS 權限規則有沒有放行該節點 IP」,跟帳號無關。

帳號還是會開(DSM 管理、SMB 存取、配額管理用),但對 K8s 的 NFS 掛載不是必要條件。


問題 / 常見錯誤訊息

# 節點掛載時:
mount.nfs: access denied by server while mounting <NAS-IP>:/volume1/<share>

# 或 CSI provisioner 建 PVC 時 pod event:
failed to provision volume: rpc error: code = Internal
  desc = failed to mount nfs server: permission denied

# 或 pod 掛上了但寫入失敗:
mkdir: cannot create directory: Permission denied

這三種症狀分別對應三個沒設好的地方:白名單、squash、子資料夾存取。


解法:DSM 7.x 完整設定

Step 1 — 建立共享資料夾

控制台 → 共享資料夾 → 建立

Step 2 — 啟用 NFS 服務

控制台 → 檔案服務 → NFS 分頁

Step 3 — 設定 NFS 權限規則(最關鍵)

控制台 → 共享資料夾 → 選資料夾 → 編輯 → NFS 權限 → 建立

欄位 設定 為什麼
伺服器 IP K8s 節點網段,如 10.x.x.0/24 NFS 靠 IP 白名單
權限 讀取/寫入 provisioner 要建目錄
Squash 將所有使用者對應到 admin 統一 UID,避免容器內 UID 與 NAS 不符
安全性 sys 標準 NFS 認證
允許非特權連接埠連線 CSI driver 不一定從 <1024 的特權埠連
允許存取已掛載的子資料夾 CSI subDir 模式會在 share 底下動態建子目錄

Step 4 — 確認掛載路徑

NFS 權限規則下方會顯示「掛載路徑」,類似 /volume1/dfaa。這就是 CSI share 參數的基底。

Step 5 — 對映到 K8s StorageClass

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-cold
provisioner: nfs.csi.k8s.io
parameters:
  server: "<NAS-IP>"
  share: "/volume1/dfaa/k8s-cold"   # 掛載路徑 + 子目錄
  # CSI 自動為每個 PVC 在 share 底下建子目錄
  subDir: "cold-storage/${pvc.metadata.namespace}/${pvc.metadata.name}"
  mountPermissions: "0755"
mountOptions:
  - nfsvers=4.1
  - hard
  - rsize=1048576
  - wsize=1048576
reclaimPolicy: Retain
volumeBindingMode: Immediate
allowVolumeExpansion: true

驗證(從任一 K8s 節點手動測)

sudo mkdir -p /mnt/nfstest
sudo mount -t nfs -o nfsvers=4.1 <NAS-IP>:/volume1/dfaa/k8s-cold /mnt/nfstest
echo "hello" | sudo tee /mnt/nfstest/test.txt   # 測寫入
cat /mnt/nfstest/test.txt
sudo umount /mnt/nfstest

寫得進去 + 讀得出來 = 設定成功。先用手動 mount 驗證,再讓 CSI 接手 —— 手動掛失敗時錯誤訊息比 K8s event 清楚很多,省去一層抽象的 debug。


學到的事


參考資料