参考 :
【K8s】初识PV和PVC 章节《2.4.3 挂载NFS至容器》
前置结论先回顾: NFS 是网络文件系统 ,可以把远端服务器上的目录,通过网络挂载成本地目录。K8s 里可以把 NFS 挂载进 Pod,实现数据持久化。 ⚠️ 原文重点提醒:生产不推荐单机 NFS,因为 NFS 服务端是单点故障;测试 / 非生产环境用来快速验证存储挂载很方便。公有云场景优先用云厂商 NAS。
环境说明
- NFS 服务端:
k8s-node01,IP192.168.1.34,提供共享目录 - 集群其他节点(master、其他 node):NFS 客户端,只需要安装客户端工具,不需要启动 nfs-server
1. 每台机器安装 NFS 客户端
yum install nfs-utils -y
nfs-utils:NFS 全套工具包,所有 K8s 节点(master + 所有 node)都要装,因为 Pod 调度到任意节点,节点都要能挂载 NFS。- 包含:挂载命令
mount.nfs、查看共享showmount等工具。
注意:服务端也要装这个包,里面包含
nfs-server服务。
2. k8s-node01(NFS 服务端)启动 nfs 服务
systemctl start nfs-server
-
nfs-server:NFS 服务端守护进程,只有提供共享的那台机器才需要启动。cat /proc/fs/nfsd/versions
-2 +3 +4 +4.1 +4.2
查看内核 NFS 服务端支持协议版本:
-2:不支持 NFSv2+3 +4 +4.1 +4.2:支持 NFSv3、v4、v4.1、v4.2
K8s 挂载默认优先 NFS4,v4 性能更好,支持文件锁。
3. NFS 服务端创建共享目录
mkdir -p /data/nfs/test_nfs
-p:父目录不存在自动创建;/data/nfs就是对外共享的根目录。
4. 编辑 服务端NFS 授权配置文件 /etc/exports
vim /etc/exports
/data/nfs/ 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)
/etc/exports 是 NFS 核心配置,定义哪些客户端可以访问哪个目录、权限是什么 字段拆解:
/data/nfs/:本地要共享出去的目录192.168.1.0/24:允许访问的客户端网段(你的 K8s 集群机器都在这个网段)- 括号内选项:
rw:读写权限(read+write);如果是ro就是只读sync:同步写入,数据落盘后才返回成功,稳定性更高;async异步,性能高但断电丢数据风险no_subtree_check:关闭子树校验,提升性能,常用no_root_squash:重点! 默认 NFS 会把客户端root用户映射成匿名用户nobody;no_root_squash:客户端 root 保持 root 身份。 K8s 场景经常需要加这个,不然容器内 root 写入 NFS 目录会报权限不足;生产慎用,有安全风险。
5. 服务端配置生效:exportfs -r
exportfs -r
exportfs:NFS 管理共享的命令-r:reload,重新读取/etc/exports,加载共享配置,不用重启服务
常用配套查看命令:
exportfs -v查看当前已发布共享
6. 服务端重载 NFS 服务
systemctl reload nfs-server
- reload:平滑重载配置,不中断现有 NFS 连接;
新增 / 修改 exports 后,
exportfs -r+ reload 双重保险。
7. 在 k8s-master01(客户端)挂载测试
mount -t nfs 192.168.1.34:/data/nfs /mnt/
-
-t nfs:指定文件系统类型为 nfs -
192.168.1.34:/data/nfs:NFS 服务端地址 + 共享目录 -
/mnt/:本地挂载点,远端 NFS 目录挂载到本地 /mntcd /mnt/
touch test123
进入挂载目录,新建test123文件。
原理:写入
/mnt本质是通过网络写到远端k8s-node01:/data/nfs。
8. NFS 服务端验证文件
cd /data/nfs/
ls
test123 test_nfs
到 NFS 服务端的共享目录查看: ✅ 看到刚才 master 上创建的test123,说明 NFS 共享挂载成功。文件存在远端机器上。
9、和 K8s 容器挂载的关联(这几步只是底层 NFS 预验证)
上面全部是宿主机层面验证 NFS 通不通 ,还没到容器。 下一步才会写 K8s PV/PVC,在 Pod 资源清单里引用 NFS 存储,直接把 NFS 目录挂载进容器内部。
简单示例 PV:
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
nfs:
server: 192.168.1.34
path: /data/nfs
10、Pod Yaml 直接挂载 NFS(不使用 PV/PVC,简易方式)
K8s Pod 原生支持直接在
volumes字段指定nfs,不需要提前创建 PV、PVC,适合快速测试。 底层原理:Pod 调度到哪个节点,该节点就会调用宿主机mount.nfs挂载远端 NFS。 ⚠️ 前提:集群所有节点已经提前安装 nfs-utils(前面步骤已经做了)
pod-nfs-direct.yaml
apiVersion: v1
kind: Pod
metadata:
name: nfs-direct-pod
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
volumeMounts:
# 将 volume 挂载到容器内路径 /usr/share/nginx/html
- name: nfs-storage
mountPath: /usr/share/nginx/html
volumes:
# 直接定义nfs卷,无需PV/PVC
- name: nfs-storage
nfs:
server: 192.168.1.34 # NFS服务端IP,就是k8s-node01
path: /data/nfs # NFS服务端共享目录,/etc/exports里配置的目录
readOnly: false # false=读写;true=只读
字段解释
volumes.name: nfs-storage:卷名称,自定义,要和下面volumeMounts.name对应volumes.nfs.server:NFS 服务 IPvolumes.nfs.path:NFS 服务端导出的共享目录volumeMounts.mountPath:容器内部的挂载点,容器里这个目录就是 NFS 远端目录
优缺点(直接 NFS 挂载,无 PV/PVC)
✅ 优点
- 极简,一条 yaml 搞定,不用维护 PV/PVC 资源,适合临时测试
- 快速验证 NFS 在 Pod 中读写
❌ 缺点(生产严禁使用)
- 没有存储生命周期管理,无法做存储配额
- 无法复用:多个 Pod 不能统一声明存储,每个 Pod 都要硬编码 NFS 地址
- 没有抽象:NFS 地址写死在 Pod yaml,NFS 服务 IP 变更,所有 Pod yaml 都要改
- 不支持 StorageClass,不能动态供给