4、NFS服务搭建:在Linux上部署NFS Server、配置exports、防火墙与权限设置
说到Kubernetes的持久化存储,NFS绝对是个老朋友了。虽然现在有各种分布式存储方案,但NFS在实验室环境、小规模集群中依然很能打。特别是我们要跑vLLM模型推理,模型文件动不动几十G,用NFS共享给多个节点,是最省事的方案。
我个人习惯在Ubuntu 22.04上部署NFS Server。当然CentOS也差不多,就是包管理器换成yum。嗯,这里要注意,生产环境我建议用CentOS Stream或者RHEL,稳定性更好。
4.1 安装NFS Server
先更新包索引,然后安装nfs-kernel-server。这个包包含了NFS服务端的所有组件。
# Ubuntu/Debian
sudo apt update
sudo apt install nfs-kernel-server -y
# CentOS/RHEL
sudo yum install nfs-utils -y
sudo systemctl enable nfs-server
sudo systemctl start nfs-server
安装完成后,检查一下服务状态:
sudo systemctl status nfs-server
看到 active (running) 就对了。我记得有一次在CentOS 7上装完发现服务没起来,排查了半天,原来是rpcbind没启动。所以这里提醒一下,NFS依赖rpcbind,务必确保它也在运行。
4.2 创建共享目录
我们要给vLLM模型文件准备一个专门的目录。我个人习惯把共享数据放在 /data 下,结构清晰。
sudo mkdir -p /data/vllm-models
sudo chown nobody:nogroup /data/vllm-models
sudo chmod 755 /data/vllm-models
为什么用nobody?因为NFS默认的匿名用户映射就是nobody。你想想看,如果多个Kubernetes节点上的Pod用不同的UID访问,权限会乱成一锅粥。用nobody统一映射,省心。
4.3 配置exports文件
这是NFS的核心配置文件。说白了,就是告诉NFS:哪些目录可以共享,共享给谁,有什么权限。
sudo vim /etc/exports
添加以下内容:
/data/vllm-models 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)
我来解释一下这几个参数:
| 参数 | 说明 |
|---|---|
| rw | 读写权限。如果只读,用ro |
| sync | 同步写入。数据写完才返回,安全但慢一点 |
| no_subtree_check | 禁用子树检查。提升性能,我一般都会加上 |
| no_root_squash | 允许root用户保留权限。Kubernetes Pod有时需要root权限写文件 |
配置完以后,执行以下命令生效:
sudo exportfs -a
sudo systemctl restart nfs-server
检查共享是否成功:
sudo showmount -e localhost
输出应该类似:
Export list for localhost:
/data/vllm-models 192.168.1.0/24
4.4 防火墙设置
NFS依赖多个端口。除了2049这个主端口,还有rpcbind的111端口,以及mountd、lockd等动态端口。我曾经在项目中遇到过,防火墙没配好,客户端挂载时一直卡住,超时后才报错。
最稳妥的做法是直接放行NFS服务:
# Ubuntu (ufw)
sudo ufw allow from 192.168.1.0/24 to any port nfs
sudo ufw allow from 192.168.1.0/24 to any port 111
sudo ufw reload
# CentOS (firewalld)
sudo firewall-cmd --permanent --zone=trusted --add-source=192.168.1.0/24
sudo firewall-cmd --permanent --zone=trusted --add-service=nfs
sudo firewall-cmd --permanent --zone=trusted --add-service=rpc-bind
sudo firewall-cmd --reload
如果你用的是云服务器,记得在安全组里也放行这些端口。嗯,这里要注意,有些云厂商的安全组规则不支持端口范围,那就得把NFS的端口固定下来。
固定NFS端口的方法:
# 编辑 /etc/nfs.conf
sudo vim /etc/nfs.conf
# 找到 [nfsd] 部分,添加:
[nfsd]
port=2049
# 找到 [mountd] 部分,添加:
[mountd]
port=20048
# 重启服务
sudo systemctl restart nfs-server
这样mountd就固定在了20048端口,防火墙规则就好写了。
4.5 权限设置详解
权限问题,是NFS使用中最容易踩坑的地方。我见过太多人挂载成功但读写失败,最后发现是权限没配好。
核心原则:服务端和客户端的UID/GID必须一致。或者用匿名映射。
对于vLLM模型文件,我建议这样设置:
# 在服务端创建专用用户
sudo useradd -r -s /sbin/nologin vllm
sudo chown -R vllm:vllm /data/vllm-models
sudo chmod 755 /data/vllm-models
然后在所有Kubernetes节点上创建相同UID的用户:
sudo useradd -r -u 999 -s /sbin/nologin vllm
这样Pod以UID 999运行时,就能正常读写NFS共享目录了。
4.6 客户端挂载测试
在任意一台Kubernetes节点上测试挂载:
# 安装nfs客户端
sudo apt install nfs-common -y
# 创建挂载点
sudo mkdir -p /mnt/vllm-models
# 挂载
sudo mount -t nfs 192.168.1.100:/data/vllm-models /mnt/vllm-models
# 验证
df -h | grep vllm
ls -la /mnt/vllm-models
如果一切正常,你就能看到共享目录的内容了。测试读写:
# 写测试
echo "hello vllm" | sudo tee /mnt/vllm-models/test.txt
# 读测试
cat /mnt/vllm-models/test.txt
# 清理
sudo rm /mnt/vllm-models/test.txt
读写都没问题的话,就可以配置开机自动挂载了:
echo "192.168.1.100:/data/vllm-models /mnt/vllm-models nfs defaults 0 0" | sudo tee -a /etc/fstab
4.7 性能调优建议
vLLM模型文件比较大,NFS的性能直接影响模型加载速度。我分享几个调优参数:
| 参数 | 推荐值 | 说明 |
|---|---|---|
| rsize/wsize | 1048576 (1MB) | 读写块大小,越大吞吐越高 |
| noatime | 启用 | 不更新访问时间,减少IO |
| hard | 启用 | 硬挂载,NFS服务重启后自动重连 |
| intr | 启用 | 允许中断挂起的NFS操作 |
挂载时加上这些参数:
sudo mount -t nfs -o rsize=1048576,wsize=1048576,noatime,hard,intr 192.168.1.100:/data/vllm-models /mnt/vllm-models
- NFS Server安装后务必检查rpcbind服务
- exports配置中no_root_squash要谨慎使用
- 防火墙放行NFS相关端口(2049、111、mountd)
- 权限问题:服务端和客户端UID保持一致
- 性能调优:增大rsize/wsize,启用noatime
好了,NFS服务端就搭好了。接下来我们就可以在Kubernetes里创建PV和PVC,让Pod用上这个共享存储了。