运维常见面试题_05_NFS 与共享存储

Q102. NFS v3 和 NFS v4 的主要区别是什么?

1. 是什么:NFS(Network File System)是网络文件共享协议。v3(RFC 1813)是经典的 RPC 版 NFS;v4(RFC 7530,含 v4.1/4.2)是一次协议重构,在传输、端口、认证、锁等方面做了大量简化与增强。

2. 为什么用它:选型直接影响性能、安全性和部署复杂度。理解 v3/v4 差异才能决定"防火墙复杂环境用什么、高安全/高性能场景用什么",也是排查挂载问题的前提------如 v3 报"portmap/rpc 相关错"、v4 报"不支持的协议"。

3. 怎么用它(关键差异对比):

维度 NFS v3 NFS v4
端口与 rpcbind 依赖 rpcbind/portmapper ,mountd/nlockmgr/statd 用动态端口,防火墙难放行 固定 TCP 2049,无需 rpcbind,防火墙只开 2049
传输协议 支持 TCP/UDP 仅 TCP(面向连接更可靠)
文件锁 独立 lockd + statd(NLM),服务重启会丢锁,需手工恢复 内置锁管理,无需额外服务
认证安全 基于 IP 的弱认证(sec=sys) 内置 RPCSEC_GSS(Kerberos 等) 强认证
性能 单次请求/响应、无状态服务器 COMPOUND 复合操作减少往返,元数据操作更高效
状态 无状态(stateless) 有状态(stateful),基于 lease 租约管理
大文件/挂载 需手工配 rsize/wsize 等参数 自动协商最优参数,挂载端口多路复用
  • 兼容性:NFSv4 服务端通常兼容 v2/v3(可 RPCNFSDARGS="-N 2 -N 3" 关闭);客户端 mount -t nfs 默认可能协商到 v3,需 -o vers=4 显式指定。
  • 选型建议:新环境优先 NFSv4(安全、简单、防火墙友好、性能好);v3 在存量老系统、部分仅支持 v3 的 NAS/集群文件系统上仍有使用。

4. 使用场景 :新旧环境选型、跨机房防火墙场景(v4 只需开 2049)、安全要求高的共享目录(v4 + Kerberos)。面试要点:核心差异四句话------v4 固定 2049 不需要 rpcbind、锁内置无需 statd、支持 Kerberos 强认证、COMPOUND 复合操作性能更好。

Q103. NFS 依赖的 rpcbind 服务的作用是什么?

1. 是什么 :rpcbind(早期叫 portmapper,端口映射器)是一个 RPC 服务,维护"RPC 程序号 → 端口号"的映射关系;NFS v3 的 mountd、nlockmgr、statd 等组件端口是动态分配的,客户端必须通过 rpcbind(UDP/TCP 111)查询它们实际监听的端口。

2. 为什么用它:NFSv3 的每个子服务(rpc.mountd 处理挂载请求、rpc.statd 处理锁恢复、nlockmgr 处理文件锁)启动时随机分配端口,客户端无法预先知道端口,只能先问 rpcbind"这个程序号现在监听哪个端口"。没有 rpcbind,客户端连"端口 111"都连不上,NFSv3 挂载必然失败。

3. 怎么用它:

bash 复制代码
# 1) 查看 rpcbind 服务状态与当前注册的 RPC 映射
systemctl status rpcbind
rpcinfo -p                                   # 列出所有注册的 RPC 程序、版本、协议、端口
# 输出示例:portmapper 100000 / nfs 100003 / mountd 100005 / nlockmgr 100021 / status 100024 ...
# 2) 服务器端必须启动 rpcbind(NFSv4 不依赖,但通常一起装)
systemctl enable --now rpcbind
# 3) 防火墙放行(v3 需要 111 + 动态端口范围)
firewall-cmd --add-service=rpc-bind --permanent
# 并固定 mountd/statd 端口(/etc/sysconfig/nfs 或 /etc/nfs.conf),便于防火墙精确放行

常见故障:mount: RPC: Port mapper failure 或 rpcbind: RPC: Remote system error------通常是 rpcbind 未启动 、防火墙挡了 111,或 mountd 等动态端口未放行;用 rpcinfo -p <server> 从客户端测即可确认。

4. 使用场景 :NFSv3 服务搭建、挂载失败排查("RPC: Port mapper failure")、防火墙放行规划。面试要点:一句话------"rpcbind 是 NFSv3 的'端口总机',把 RPC 程序号翻译成实际端口 ";答出 rpcinfo -p 查看、放行 111、NFSv4 不需要它这三点。

Q104. 如何配置 NFS 服务器和客户端?

1. 是什么 :NFS 服务器通过 /etc/exports 声明哪些目录共享给哪些主机/网段、以什么权限共享,并启动 nfs/rpcbind 服务;客户端用 mount 把远端共享目录挂载到本地,即可像本地目录一样读写。

2. 为什么用它:NFS 是 Linux/Unix 环境最常用的共享文件系统,用于多台机器共享同一份数据(源码、数据目录、共享磁盘、K8s PV),配置简单、原生支持、无需额外软件。

3. 怎么用它:

服务器端(CentOS/RHEL 为例):

bash 复制代码
# 1) 安装软件
yum install -y nfs-utils

# 2) 创建共享目录并设权限
mkdir -p /data/shared
chown nfsnobody:nfsnobody /data/shared

# 3) 编辑 /etc/exports 声明共享
cat >> /etc/exports <<'EOF'
/data/shared 192.168.1.0/24(rw,sync,no_root_squash)
/data/shared 10.0.0.5(rw,sync,all_squash)
EOF

# 4) 启动服务并生效配置
systemctl enable --now rpcbind nfs-server
exportfs -r                              # 重新读取 exports,使配置立即生效
exportfs -v                              # 查看当前生效的共享及权限
showmount -e localhost                   # 列出本机共享的目录

客户端:

bash 复制代码
# 1) 安装
yum install -y nfs-utils

# 2) 查看服务器共享了哪些目录
showmount -e 192.168.1.10

# 3) 挂载(v3/v4)
mount -t nfs 192.168.1.10:/data/shared /mnt/shared          # 自动协商版本
mount -t nfs4 192.168.1.10:/data/shared /mnt/shared         # 强制 NFSv4
mount -t nfs -o vers=4,rsize=1048576,wsize=1048576 192.168.1.10:/data/shared /mnt/shared

# 4) 验证
df -h /mnt/shared
mount | grep shared

配置要点:exports 语法为"共享目录 客户端(选项...)";客户端可用主机名、IP、网段(192.168.1.0/24)、通配符(*.example.com) ;每次改 /etc/exports 都要 exportfs -r 生效,无需重启服务。

4. 使用场景 :多台 Web/应用服务器共享上传目录、K8s NFS PV、开发环境共享代码、日志集中目录。面试要点:服务器端三步"装 nfs-utils → 写 /etc/exports → systemctl enable nfs-server + exportfs -r";客户端三步"装包 → showmount -e 看共享 → mount 挂载";记住 exports 语法与 exportfs -r。

Q105. 如何配置 NFS 的共享权限和用户映射?

1. 是什么 :NFS 的"权限"分两层------exports 的共享级权限 (ro/rw)控制客户端对共享目录整体能否写;用户映射(squash 机制)决定客户端访问时的 UID/GID 在服务器端被"翻译"成什么身份,避免客户端 root 在服务器端拥有 root 权限。

2. 为什么用它:不配置用户映射会带来两大问题:客户端 root 默认在服务器端仍以 root 写入(危险);客户端普通用户 UID 与服务器端不一致导致"属主错乱、没权限、写入变成 nobody"。映射是 NFS 安全与权限正确的关键。

3. 怎么用它(exports 选项):

bash 复制代码
# /etc/exports 示例
/data/shared 192.168.1.0/24(rw,sync,root_squash,all_squash,anonuid=1000,anongid=1000)
/data/readonly 10.0.0.0/24(ro,sync)

核心选项:

  • 共享权限 :ro(只读)/ rw(读写);sync(写请求同步落盘后才响应,数据更安全,生产推荐)/ async(先响应后落盘,性能好但掉电有丢数据风险)。
  • 用户映射(squash) :
    • root_squash(默认 ):客户端 root(UID 0)在服务器端被映射为 nfsnobody(匿名用户),禁止 root 越权;
    • no_root_squash:客户端 root 在服务器端保持 root 权限------仅限可信环境,否则客户端可随意写任意文件,危险;
    • all_squash:所有客户端用户一律映射为匿名用户,通常配合 anonuid/anongid 指定成特定 UID(如 app 用户 1000);
    • anonuid=1000,anongid=1000:指定匿名用户映射到的 UID/GID(默认是 nfsnobody)。
  • 固定映射的推荐做法 :客户端与服务器端用户 UID 不一致时,最稳妥是两侧统一 UID (创建相同 UID 的用户);做不到时用 all_squash,anonuid=1000 把所有客户端用户统一映射成服务器端同一个 UID,避免属主错乱。
    验证权限映射:
bash 复制代码
# 客户端侧创建文件后,在服务器端看属主,确认映射是否符合预期
touch /mnt/shared/test && ls -ln /mnt/shared/test   # 看 UID 是否被映射

4. 使用场景 :Web 应用共享上传目录(统一映射成 www 用户)、跨团队共享目录(控制只读)、多用户数据盘(避免 UID 错乱)。面试要点:区分两类选项------ro/rw/sync 管"能不能写",root_squash/all_squash/anonuid 管"以谁的身份写";强调默认 root_squash 是为了防客户端 root 越权,all_squash + anonuid 是解决 UID 不一致的通用手段。

Q106. 如何让客户端开机自动挂载 NFS?

1. 是什么 :把 NFS 挂载写入客户端的 /etc/fstab,系统启动时自动执行挂载;配合 _netdev 选项确保"网络就绪后才挂载",避免网络未通导致挂载失败拖慢开机。

2. 为什么用它 :mount 挂载是一次性的,重启后失效。生产环境共享目录必须开机自动挂载,否则服务器重启后应用因找不到挂载点而报错;fstab 是实现持久化挂载的标准方式。

3. 怎么用它:

bash 复制代码
# /etc/fstab 末尾追加一行
# 字段:文件系统 挂载点 类型 选项 备份(0) 检查顺序(0)
192.168.1.10:/data/shared   /mnt/shared   nfs   defaults,_netdev,noatime  0  0

常用选项说明:

  • _netdev:告诉 systemd"这是网络文件系统,等网络就绪后再挂载",防止开机时网络未起导致挂载失败阻塞启动(NFS 必须加);
  • noatime:不更新访问时间,减少 NFS 写开销,性能更好;
  • vers=4 / vers=3:指定协议版本,避免协商到预期外的版本;
  • auto (默认)表示开机自动挂载,noauto 表示不自动挂载;
  • bg :首次挂载失败后转入后台重试,fg(默认)前台重试会阻塞开机,生产常用 bg;
  • rsize,wsize :传输块大小,如 rsize=1048576,wsize=1048576,大文件传输场景可提升性能。
    验证与应用:
bash 复制代码
mount -a                 # 重新挂载 fstab 中所有未挂载的条目(改完 fstab 后立即验证)
df -h | grep shared      # 确认挂载成功
# fstab 写错可能导致开机失败/进入紧急模式,改完务必先 mount -a 验证再重启

注意:fstab 写错(IP、目录、选项错误)可能导致开机失败/进入紧急模式 ,因此改完 fstab 先 mount -a 验证再重启;若希望"访问时才挂载",可用 systemd automount 实现按需挂载。

4. 使用场景 :共享数据盘/上传目录持久挂载、Web 集群自动挂载共享存储、K8s 节点挂载 NFS 数据卷。面试要点:答出 fstab 三要素(远端路径、挂载点、nfs 类型)+ 两个关键选项------_netdev(网络就绪后再挂) 和 bg(失败后台重试不卡开机) ,并提醒"改完先 mount -a 验证再重启"。

Q107. NFS 客户端挂载失败,如何排查?

1. 是什么 :NFS 挂载失败即 mount -t nfs 报错,常见如 RPC: Port mapper failure、No route to host、Permission denied、mount.nfs: Connection timed out 等;排查按"网络 → rpcbind → exports 权限 → 挂载参数/日志"逐层定位。

2. 为什么用它:NFS 挂载故障是共享存储环境最高频问题,报错信息往往只给方向不给原因;掌握一套固定排查顺序,能快速区分是"网络不通、服务没起、防火墙拦截、权限被拒"还是"参数写错"。

3. 怎么用它(按序排查):

bash 复制代码
# ① 网络连通性
ping 192.168.1.10                    # 服务器 IP 是否可达
nc -vz 192.168.1.10 111              # TCP 111(rpcbind)是否通
nc -vz 192.168.1.10 2049             # TCP 2049(NFS)是否通(NFSv4 必需)

# ② 服务器端 RPC 服务是否正常
rpcinfo -p 192.168.1.10              # 应能看到 portmapper/nfs/mountd/nlockmgr/statd
# 连接失败 → 服务器上 systemctl status rpcbind nfs-server 看服务是否 running
# rpcinfo -p 里没有 mountd/nlockmgr 条目 → NFS 相关服务没起

# ③ 服务器端共享是否配置正确
showmount -e 192.168.1.10            # 客户端查询服务器共享了哪些目录
# Export list 为空 → /etc/exports 没写或 exportfs -r 没生效
# 报 Permission denied → 客户端 IP 不在 exports 允许范围内,或选项不匹配

# ④ 防火墙/安全组(很常见)
# 服务器端:NFSv4 放行 2049;NFSv3 放行 111 + mountd/statd/nlockmgr 动态端口
firewall-cmd --list-all              # 服务器上查看已放行服务
# 若为固定动态端口,在 /etc/sysconfig/nfs 指定 mountd/statd 端口并放行

# ⑤ 权限问题
# 客户端 IP 在 exports 里,但目录本身权限不对:
# 服务器端 chmod -R 755 /data/shared;确认映射用户(root_squash/all_squash)
# 客户端 mount -o rw 但 exports 是 ro → 报 Permission denied

# ⑥ 看日志定位
tail -f /var/log/messages             # 服务器端(含 rpc.mountd 报错)
journalctl -u rpc-mountd -u nfs-server
dmesg | grep -i nfs                   # 客户端内核日志

按报错归类(速查):

报错 主要可能原因
RPC: Port mapper failure / Remote system error rpcbind 未起、111 端口被防火墙拦、服务器 IP 错
mount.nfs: Connection timed out 2049/动态端口被防火墙拦、服务器 nfs 服务没起
Permission denied 客户端 IP 不在 exports 里、exports 是 ro、squash 映射导致没权限
No such file or directory 服务器共享路径拼错、或共享目录已删除
Operation not permitted 挂载点/参数问题,或 NFSv4 与 v3 版本不匹配

4. 使用场景 :任何"共享目录挂不上"的线上故障、新装环境首次挂载 NFS。面试要点:报错先对号入座,按"ping → rpcinfo -p → showmount -e → 防火墙 → exports 权限 → 日志 "六步排查;记住三类最常见根因------防火墙(111/2049/动态端口)、exports 里没包含客户端、rpcbind/nfs 服务没起。

相关推荐
雯宝6 小时前
mnt_init 函数
linux
律宏阔12 小时前
WSL Docker 端口明明空闲,但就是绑不上端口
linux·windows
律宏阔12 小时前
WSL 突然断网,无法 ping 内网或外网
linux·windows
穷人小水滴12 小时前
用容器编译 VirtualBox 虚拟机软件 (ArchLinux, podman)
linux·容器·virtualbox
乱码三千12 小时前
如何优雅地直连无公网 IP 的远程 GPU 服务器
linux·人工智能·程序员
yunwei3712 小时前
使用 eBPF 跟踪 Nginx 请求
linux·后端·性能优化
yunwei3712 小时前
使用 eBPF 跟踪 MySQL 查询
linux·后端·性能优化
yunwei3712 小时前
eBPF 示例教程:使用 XDP 捕获 TCP 信息
linux·后端·性能优化
judezh12 小时前
api 容器一直 unhealthy?我把一个 Agent 运行时的健康检查逐条拆了,查出四个问题
运维·docker
GeW12 小时前
制造业高端化,为什么必须重估Linux和数据库?
linux