赛博堡垒的外接大容量水库:接入 NFS 动态存储池
This content is not available in your language yet.
📖 认识外接水库:有了 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 后,相当于你在集群里雇佣了一个全自动水管工:
- 当你的应用(比如 Jellyfin)提交了一个 500GB 的 PVC(存储申请)时,它只需要注明
storageClassName: nfs-client。 - 水管工看到需求后,会自动跑到你的 TrueNAS/群晖 上。
- 它会在 NAS 的 NFS 共享根目录下,自动以
namespace-pvcName的格式新建一个子文件夹。 - 然后自动把这根“水管”接到你的 Pod 底部。全程零人工干预!
🧱 施工前置准备 (Requirements)
Section titled “🧱 施工前置准备 (Requirements)”想要顺利接通这根大水管,外部的“水源地”和内部的“接水点”都必须准备就绪。
1. 水源地勘探:配置你的物理 NAS
Section titled “1. 水源地勘探:配置你的物理 NAS”无论你用的是 TrueNAS SCALE、群晖 还是极空间,请务必在 NAS 后台完成以下配置:
- 创建一个专用的共享文件夹(例如
/mnt/nfs)。 - 开启 NFS 共享服务(强烈建议开启 NFSv4 支持)。
- 配置权限(Mapall User/Group):为了防止 K8s 里的容器因为权限问题无法写入数据,建议将该 NFS 共享的读写权限映射为 NAS 上的
root用户,或者给予Everyone完全读写权限(在安全的纯内网环境下)。 - 记录情报:把你的 NAS IP 地址 和 NFS 真实物理路径 记在图纸上,稍后浇筑时要用。
2. 接水点确认:检查底层依赖
Section titled “2. 接水点确认:检查底层依赖”Longhorn 需要 open-iscsi,而挂载 NFS 则需要宿主机具备解析 NFS 协议的能力。
还记得我们在上一期部署 Longhorn 时的**“环境探勘”**步骤吗?我们当时已经让 3 台 Ubuntu 节点安装了“四大金刚”,其中就包含了 nfs-common。
如果你是按照教程顺序施工的,这一步可以直接跳过。如果不确定,可以在所有 Master 节点补一枪:
sudo apt-get updatesudo apt-get install -y nfs-common🔨 核心施工流程 (Installation Steps)
Section titled “🔨 核心施工流程 (Installation Steps)”步骤 1:添加官方 Helm 仓库并获取版本号
Section titled “步骤 1:添加官方 Helm 仓库并获取版本号”再次掏出我们的云原生瑞士军刀 Helm,添加 Kubernetes SIGs(特别兴趣小组)维护的官方 NFS 供应器仓库:
helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/helm repo update💡 查明最新大版本号:
老规矩,干工程绝不盲目用 latest。查一下当前最新的图纸版本号:
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步骤 3:执行 Helm 一键打井指令
Section titled “步骤 3:执行 Helm 一键打井指令”图纸定稿后,执行安装指令。我们把它建在默认的 kube-system 园区,作为底层基础设施运行:
helm install nfs-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \ --namespace kube-system \ -f nfs-values.yaml \ --version 4.0.18敲下这条指令检查大水管是否接通:
kubectl get pods -n kube-system -l app=nfs-subdir-external-provisioner(看到状态变为 Running,水管工就正式上岗了!)
🔬 竣工验收:造一个“假租客”试水
Section titled “🔬 竣工验收:造一个“假租客”试水”大水库接好了,我们怎么知道水管工到底干不干活?最好的方法是写一张“假图纸”,随便拉一个容器来申请一块 NFS 硬盘测试一下。
创建一个名为 nfs-test.yaml 的文件:
# 1. 提交申请:要一块 10G 的硬盘,点名用 nfs-clientapiVersion: v1kind: PersistentVolumeClaimmetadata: name: nfs-test-pvc namespace: defaultspec: accessModes: - ReadWriteMany # NFS 的绝杀特性:支持多个 Pod 同时读写 storageClassName: nfs-client resources: requests: storage: 10Gi---# 2. 拉起一个测试租客,把硬盘挂上去,并写一段话apiVersion: v1kind: Podmetadata: name: nfs-test-pod namespace: defaultspec: 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执行试水:
kubectl apply -f nfs-test.yaml🎉 最终验证:见证魔法时刻
现在,请打开你物理 NAS (TrueNAS 或 群晖) 的后台文件管理器。
进入你当时设置的共享文件夹目录(例如 /mnt/pool/k8s_nfs),你会震撼地发现:
- 里面自动多出了一个以
default-nfs-test-pvc-xxx命名的文件夹! - 点进去,里面静静地躺着一个
success.txt。 - 打开文本,上面写着:
Hello from K3s Cyber Fortress!
测试完美通过!清理打扫试水现场:
kubectl delete -f nfs-test.yaml