chundev
日期:2026-05-21
環境:Synology DSM 7.x + K3s + NFS CSI Driver(nfs.csi.k8s.io)
把 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 完全不同,第一次設定很容易卡在「掛得上但寫不進去」或「節點根本連不到」。
| 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、子資料夾存取。
控制台 → 共享資料夾 → 建立
dfaa,位置選容量最大的 Volume/volume1/dfaa控制台 → 檔案服務 → NFS 分頁
nfsvers=4.1)控制台 → 共享資料夾 → 選資料夾 → 編輯 → NFS 權限 → 建立
| 欄位 | 設定 | 為什麼 |
|---|---|---|
| 伺服器 IP | K8s 節點網段,如 10.x.x.0/24 |
NFS 靠 IP 白名單 |
| 權限 | 讀取/寫入 | provisioner 要建目錄 |
| Squash | 將所有使用者對應到 admin | 統一 UID,避免容器內 UID 與 NAS 不符 |
| 安全性 | sys |
標準 NFS 認證 |
| 允許非特權連接埠連線 | ✅ | CSI driver 不一定從 <1024 的特權埠連 |
| 允許存取已掛載的子資料夾 | ✅ | CSI subDir 模式會在 share 底下動態建子目錄 |
NFS 權限規則下方會顯示「掛載路徑」,類似 /volume1/dfaa。這就是 CSI share 參數的基底。
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
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。
all_squash / map-to-admin 解 UID 不符:容器內 process 的 UID 通常跟 NAS 帳號 UID 不同,全部 squash 到 admin 最省事(代價是失去 per-user 權限粒度,但 K8s 場景通常不在意)