跳转到内容

赛博堡垒的外接大容量水库:接入 NFS 动态存储池

🌱 创建: 2026/04/18 ⏱️ 更新: 2026/05/22

📖 认识外接水库:有了 Longhorn,为什么还要 NFS?

Section titled “📖 认识外接水库:有了 Longhorn,为什么还要 NFS?”

在上一期工程中,我们部署了 Longhorn,它就像是赛博堡垒内部的企业级 NVMe 闪存阵列。它拥有 3 副本高可用,速度极快,是运行数据库(MySQL、PostgreSQL)和核心应用配置文件的完美地基。

但是,包工头们马上会面临一个非常现实的物理学问题:你的 Master 节点硬盘没那么大!

如果你要在集群里部署 Jellyfin 影视墙、Nextcloud 私有云盘,或者存放动辄几十 GB 的集群快照备份,把这些海量的“冷数据”塞进 Longhorn 里,不仅会瞬间把宿主机的系统盘撑爆,而且 3 副本机制会让你 NAS 上的空间被白白浪费 3 倍。

这时候,最优雅的云原生解法是:引入外挂大水库 —— NFS 动态供应器 (NFS Subdir External Provisioner)。

📜 动态供应器 (Provisioner) 工作原理

Section titled “📜 动态供应器 (Provisioner) 工作原理”

过去,要在 K8s 里挂载外部的 NFS,你需要手动写长篇大论的 PV(持久卷)配置文件,而且 NAS 上必须提前建好对应的文件夹,操作极其反人类。

引入 nfs-subdir-external-provisioner 后,相当于你在集群里雇佣了一个全自动水管工

  1. 当你的应用(比如 Jellyfin)提交了一个 500GB 的 PVC(存储申请)时,它只需要注明 storageClassName: nfs-client
  2. 水管工看到需求后,会自动跑到你的 TrueNAS/群晖 上。
  3. 它会在 NAS 的 NFS 共享根目录下,自动以 namespace-pvcName 的格式新建一个子文件夹。
  4. 然后自动把这根“水管”接到你的 Pod 底部。全程零人工干预!

官方安装指南

想要顺利接通这根大水管,外部的“水源地”和内部的“接水点”都必须准备就绪。

1. 水源地勘探:配置你的物理 NAS

Section titled “1. 水源地勘探:配置你的物理 NAS”

无论你用的是 TrueNAS SCALE、群晖 还是极空间,请务必在 NAS 后台完成以下配置:

  1. 创建一个专用的共享文件夹(例如 /mnt/nfs)。
  2. 开启 NFS 共享服务(强烈建议开启 NFSv4 支持)。
  3. 配置权限(Mapall User/Group):为了防止 K8s 里的容器因为权限问题无法写入数据,建议将该 NFS 共享的读写权限映射为 NAS 上的 root 用户,或者给予 Everyone 完全读写权限(在安全的纯内网环境下)。
  4. 记录情报:把你的 NAS IP 地址NFS 真实物理路径 记在图纸上,稍后浇筑时要用。

Longhorn 需要 open-iscsi,而挂载 NFS 则需要宿主机具备解析 NFS 协议的能力。

还记得我们在上一期部署 Longhorn 时的**“环境探勘”**步骤吗?我们当时已经让 3 台 Ubuntu 节点安装了“四大金刚”,其中就包含了 nfs-common。 如果你是按照教程顺序施工的,这一步可以直接跳过。如果不确定,可以在所有 Master 节点补一枪:

Terminal window
sudo apt-get update
sudo apt-get install -y nfs-common

🔨 核心施工流程 (Installation Steps)

Section titled “🔨 核心施工流程 (Installation Steps)”

步骤 1:添加官方 Helm 仓库并获取版本号

Section titled “步骤 1:添加官方 Helm 仓库并获取版本号”

再次掏出我们的云原生瑞士军刀 Helm,添加 Kubernetes SIGs(特别兴趣小组)维护的官方 NFS 供应器仓库:

Terminal window
helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
helm repo update

💡 查明最新大版本号: 老规矩,干工程绝不盲目用 latest。查一下当前最新的图纸版本号:

Terminal window
helm search repo nfs-subdir-external-provisioner -l | head -n 5

(假设输出中排名第一的版本是 4.0.18,请将它记下。)

步骤 2:定制 NFS 专属施工图纸 (values.yaml)

Section titled “步骤 2:定制 NFS 专属施工图纸 (values.yaml)”

创建一个名为 nfs-values.yaml 的文件。这份图纸的核心任务,就是告诉水管工你的 NAS 在哪里。

# 填入你勘探好的水源地情报
nfs:
server: 10.0.10.100 # ⚠️ 修改为你的 TrueNAS/群晖 IP
path: /mnt/pool/k8s_nfs # ⚠️ 修改为 NAS 上暴露的绝对路径
storageClass:
# 给这个大水库起个名字,以后业务申请硬盘就喊这个代号
name: nfs-client
# 是否将其设为集群默认存储?(强烈建议填 false,默认存储依然留给 Longhorn)
defaultClass: false
# 💡 核心防爆机制:删除 PVC 时,不要彻底删除 NAS 上的数据,而是重命名归档 (Archived)
archiveOnDelete: true
# 资源限制(水管工本身不需要吃太多性能)
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 10m
memory: 64Mi

图纸定稿后,执行安装指令。我们把它建在默认的 kube-system 园区,作为底层基础设施运行:

Terminal window
helm install nfs-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
--namespace kube-system \
-f nfs-values.yaml \
--version 4.0.18

敲下这条指令检查大水管是否接通:

Terminal window
kubectl get pods -n kube-system -l app=nfs-subdir-external-provisioner

(看到状态变为 Running,水管工就正式上岗了!)


🔬 竣工验收:造一个“假租客”试水

Section titled “🔬 竣工验收:造一个“假租客”试水”

大水库接好了,我们怎么知道水管工到底干不干活?最好的方法是写一张“假图纸”,随便拉一个容器来申请一块 NFS 硬盘测试一下。

创建一个名为 nfs-test.yaml 的文件:

# 1. 提交申请:要一块 10G 的硬盘,点名用 nfs-client
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-test-pvc
namespace: default
spec:
accessModes:
- ReadWriteMany # NFS 的绝杀特性:支持多个 Pod 同时读写
storageClassName: nfs-client
resources:
requests:
storage: 10Gi
---
# 2. 拉起一个测试租客,把硬盘挂上去,并写一段话
apiVersion: v1
kind: Pod
metadata:
name: nfs-test-pod
namespace: default
spec:
containers:
- name: test-container
image: alpine:latest
# 容器启动后,在硬盘里新建一个文件并写入内容,然后陷入沉睡
command: [ "/bin/sh", "-c", "echo 'Hello from K3s Cyber Fortress!' > /mnt/nfs/success.txt && sleep 3600" ]
volumeMounts:
- name: nfs-volume
mountPath: /mnt/nfs
volumes:
- name: nfs-volume
persistentVolumeClaim:
claimName: nfs-test-pvc

执行试水:

Terminal window
kubectl apply -f nfs-test.yaml

🎉 最终验证:见证魔法时刻 现在,请打开你物理 NAS (TrueNAS 或 群晖) 的后台文件管理器。 进入你当时设置的共享文件夹目录(例如 /mnt/pool/k8s_nfs),你会震撼地发现:

  1. 里面自动多出了一个以 default-nfs-test-pvc-xxx 命名的文件夹!
  2. 点进去,里面静静地躺着一个 success.txt
  3. 打开文本,上面写着:Hello from K3s Cyber Fortress!

测试完美通过!清理打扫试水现场:

Terminal window
kubectl delete -f nfs-test.yaml

最近更新: