有时候真正搞懂一个技术问题往往是从一个让人抓狂的报错开始的。最近逛技术社区的时候看到有位朋友在折腾 Windows 安装报错信息大概是“windows 无法安装到这个硬盘空间分区是一个 NFS 分区”。他原本想着既然 iSCSI 能通过网络把远端存储变成“本地磁盘”来装系统那 NFS 是不是也能这么干结果直接被安装程序拦在门外。这个场景特别典型也特别好地引出了存储领域一个绕不开的核心问题NFS 和 iSCSI 到底差在哪儿文件级共享和块级共享的根本区别是什么什么时候该选谁这篇文章不打算给你念协议标准也不打算堆一堆术语装高深。我会从实际使用场景切入把这两种协议的底层逻辑、搭建过程、性能边界、以及那些文档里不会写的“坑”都摊开来聊一遍。无论你是刚入行的运维、只有一台 NAS 的个人玩家还是在给虚拟化平台选型存储的工程师这篇内容应该能帮你少走不少弯路。1. 内容整体设计与思路拆解1.1 先搞清楚你要解决的是“共享文件”还是“共享硬盘”我见过太多人一上来就问“NFS 和 iSCSI 哪个快”这个提问方式本身就说明还没有理清需求。这两者根本不是同一个层次的东西强行对比性能意义不大。用一个生活化的类比来解释NFS 像是网盘/共享文件夹。你在电脑上访问它看到的是一个目录里面是一个个文件。你可以新建 Word 文档、删掉某个视频但你碰不到“这块盘的分区表”或者“文件系统的格式化”。所有底层操作都是服务器端替你完成的。iSCSI 像是给你一根很长的 SATA 线把你家硬盘接到别人家电脑上。你的操作系统看到的是一块“裸盘”准确说是 LUN你需要自己给这块盘分区、格式化、分配盘符。操作系统认为这块盘就是一块本地物理硬盘完全不知道数据通过网线绕了一圈。这个区别直接决定了它们能干什么、不能干什么。最典型的例子就是文章开头那个报错Windows 安装程序必须把一个操作系统引导到“块设备”上因为它要在磁盘最前面的扇区写引导记录。NFS 是文件协议操作系统根本没有把它识别成磁盘的抽象层所以安装程序直接拒绝。而 iSCSI 在系统眼里就是货真价实的 SCSI 磁盘Windows 完全可以装在 iSCSI 目标盘上——实际上很多无盘工作站、 SAN 启动就是这么干的。所以做技术选型之前先问自己一个问题你需要的是一堆文件还是一个能承载操作系统的磁盘这个问题回答清楚了选型方向就错不了。1.2 一句话概括两种协议的本质差异如果一定要用一句话说清楚我倾向于这样总结NFS 是“远程文件系统”解决的是“多台机器如何共享同一份文件数据”的问题iSCSI 是“远程块设备”解决的是“如何把远端存储当成本地硬盘用”的问题。从这个定义出发两种协议的应用场景天然不同维度NFSiSCSI共享粒度文件级块级操作系统感知看到一个挂载点/目录看到一块未初始化的磁盘是否可格式化不能格式化操作由服务端完成可以由发起端自由分区、格式化是否可作启动盘不能作为 Windows 系统盘可以启动操作系统典型使用场景NAS 共享、虚拟机磁盘文件存储、HPC 家目录共享数据库裸设备、虚拟化数据存储、远程启动后面所有的对比、实操、坑点都会围绕这个表格展开。2. 核心细节解析与实操要点2.1 NFS 的运作机制与配置要点NFSNetwork File System诞生于几十年前经过 NFSv3、NFSv4 的迭代到今天依然是 Linux/Unix 世界里最通用的文件共享协议。它的核心思路是通过 RPC 调用让客户端像访问本地目录一样访问远端目录。服务端把某个目录通过/etc/exports文件导出客户端用 mount 命令挂载完事儿。NFS 最大的优势是运维模型简单、共享语义强。比如你在家组了一台 NAS想给客厅的电视、书房的工作站、卧室的笔记本共享电影和文档用 NFS 是最省心的方案。服务端把家目录/home直接 export 出去客户端统一挂载到/mnt/home用户登到任何一台机器上看到的 home 目录都是一模一样的。这种“用户无感漫游”体验是块级协议很难给的——如果你用 iSCSI两块机器同时挂载同一块裸盘分分钟就会遇到文件系统损坏的问题因为没有任何协同机制。配置 NFS 时最容易踩的坑一个是权限一个是锁定一个是端口防火墙。权限问题NFS 在 v3 时代默认使用 AUTH_SYS也就是基于 UID/GID 的认证它要求所有客户端的用户 UID 必须保持一致。比如服务端有个用户的 UID 是 1001客户端另一个用户名也用 UID 1001那这两个用户实际上就是“同一个人”哪怕用户名完全不同。这是一个经常让人困惑的点。文件锁NFSv3 本身不带锁管理需要额外开启 rpc.statd 和 rpc.lockd 服务否则某些数据库程序或者频繁读写小文件的场景会报 lock 错误。NFSv4 在这方面要完善很多所以新项目建议直接用 NFSv4。端口防火墙NFSv3 除了 2049 端口还会动态开启一堆 rpc 相关端口比如 rpc.mountd 的端口是随机分配的你得在防火墙上把这些端口一并放行这常常让新手抓狂。NFSv4 通常只固定用 2049 端口配置起来清爽很多。所以我的建议一贯是新环境能用 NFSv4 就别用 v3。NFS 的简单之处在于它的挂载命令和一个普通本地挂载几乎没区别mount -t nfs 192.168.1.100:/volume1/media /mnt/media就这么一条命令目录就共享过来了。配合 fstab 或者 autofs可以实现开机自动挂载。这也是为什么 NAS 厂商和超算中心特别钟爱 NFS简单、透明、直接可用。2.2 iSCSI 的运作机制与关键概念iSCSIInternet Small Computer System Interface从名字就能看出来它的本质是在 TCP/IP 网络上传输 SCSI 协议。SCSI 是传统企业级磁盘和服务器之间通信的老牌协议iSCSI 做的事情就是把这个“老运输队长”请到以太网这张“高速公路”上来跑。整个体系里有几个名词你一定会遇到先把它们记牢Initiator发起端主动发起存储请求的一方一般就是需要加盘的服务器、台式机、工作站。Target目标端对外提供存储资源的一方可以是存储阵列、NAS 设备、也可以是随便一台 Linux 服务器跑个 target 软件。IQNiSCSI Qualified Name全宇宙唯一的设备标识通常长这样iqn.2024-01.com.example:storage-lun1。不要被它吓到它就是一个规范化的名字用来在网络上唯一定位 initiator 和 target。LUNLogical Unit Numbertarget 上开放出来的一块逻辑磁盘可以理解成一个“虚拟的硬盘”。iSCSI 的工作流程大概是在 target 端把一块物理磁盘或文件可以理解为“把一个镜像文件当作磁盘”通过 target 软件暴露出去然后在 initiator 端“发现”这个 target登录之后 initiator 的操作系统就会多出来一块全新的、什么都没格式化的“硬盘”。在 Windows 里你需要去“磁盘管理”里把它初始化、分区、格式化在 Linux 里你要用fdisk或者parted去分区然后格式化挂载。这种“裸盘”体验正是 iSCSI 最核心的竞争力。虚拟机要建集群文件系统比如 VMware 的 VMFS、微软的 CSVFS它要求参与共享的所有主机都能直接操作底层块设备。这时候 NFS 反而不好使了——因为 VMFS 这种集群文件系统必须直接跑在裸设备上。而 iSCSI 提供的这种 LUN 正好满足需求。配置一个 iSCSI 连接并不复杂以 Linux initiator 为例# 安装 initiator 软件 apt install open-iscsi # 发现 target iscsiadm -m discovery -t sendtargets -p 192.168.1.200 # 登录 target iscsiadm -m node -T iqn.2024-01.com.example:storage-lun1 -p 192.168.1.200 --login登录成功后你会看到系统里多出一个/dev/sdX设备然后就可以像正常磁盘一样去分区、格式化了。2.3 同为存储性能表现为什么截然不同很多人关心的一个核心问题是同样走网络、同样走 TCP/IPNFS 和 iSCSI 在性能上到底有没有差异坦诚讲在几乎没有并发压力的场景下两者差距没有想象中那么大。但如果并发访问量上来了差异就出来了。NFS 的性能瓶颈通常集中在协议解析、文件锁、inode 缓存一致性、元数据操作。读大文件、顺序传输时表现不错但如果是海量小文件并发读写NFS 的元数据开销会比较明显很容易造成延迟抖动。iSCSI 的性能瓶颈则集中在网络延迟、TCP 队列深度、以及底层磁盘的 IOPS 能力。因为它传输的是原始 SCSI 命令和块数据不涉及文件系统解析所以 CPU 开销相对低但对网络质量更敏感任何丢包、乱序都会导致整体性能雪崩。我自己在虚拟化平台上做了不少沟通。简单总结一下个人经验如果平台上主要跑的是 Linux 虚拟机虚拟机磁盘文件放在 NFS 数据存储上完全可行VMware 官方也支持 NFS 数据存储运维上还因为“文件级可见”而多了一层便利——可以直接通过 NFS 把虚拟机的 vmdk 文件拷贝出来。但如果虚拟机是 Windows或者是 Oracle、SQL Server 这类对随机 IO 敏感的数据库应用我会更倾向于把数据存储配置成 iSCSI。原因无他Windows 的系统内部对块设备响应非常敏感文件级协议带来的额外延迟在数据库高并发场景下会被放大。不要迷信“iSCSI 一定比 NFS 快”这种一刀切的说法。真正常见的性能杀手是网络拥塞和小文件随机写协议本身的差异在万兆网时代已经被大幅削弱了。2.4 Windows 安装报错“NFS 分区”问题的原因分析讲到这我们再回到文章开头那个报错“windows 必须安装在格式化为 NTFS 的分区windows 无法安装到这个硬盘空间分区是一个 NFS 分区”。这句话直接透露了一个事实Windows 安装程序在启动阶段只认它能直接从底层块设备访问的磁盘。它需要往磁盘的 MBR或 GPT区域写入引导代码并在指定分区写入 Windows 引导管理器。NFS 挂载出来的空间在 Windows 眼里是一个网络位置Windows 安装程序没有为它提供文件系统驱动来当启动介质更不可能通过它加载引导扇区。iSCSI 则不同因为 Windows 在系统启动早期就内置了微软 iSCSI Initiator 驱动可以建立会话、枚举 lun、把远端 LUN 当作普通本地磁盘来初始化。所以 Windows 可以装在 iSCSI 目标盘上却不能装在 NFS 共享目录上。往后你如果再看到类似报错第一反应就应该是是不是我把网络文件系统当成本地磁盘来用了如果是那就需要把存储协议换成块级方案或者调整存储架构——比如采用 SMB 3.0 挂载共享虽然 Windows 支持从 SMB 共享启动需要支持 SMB Direct 和适当的网络适配器但生产环境里还是 iSCSI 最稳。3. 实操过程与核心环节实现光讲理论不行。下面我带大家完整走一遍两种协议的搭建和调试过程你可以直接照着做。为了演示方便假设我们有两台 Ubuntu 22.04 服务器服务器 A192.168.1.100提供存储服务器 B192.168.1.101作为客户端挂载和使用存储。3.1 搭建一个 NFSv4 服务端生产环境里我推荐使用 NFSv4省去一堆兼容性麻烦。在服务器 A 上操作# 安装 NFS 服务端 apt update apt install nfs-kernel-server -y # 创建一个用于共享的目录 mkdir -p /srv/nfs/data # 给共享目录分配合理的权限 chown nobody:nogroup /srv/nfs/data chmod 755 /srv/nfs/data接着编辑/etc/exports文件添加 NFS 导出规则/srv/nfs/data 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)这里我特别说明一下几个选项的含义避免你只知道抄配置rw客户端可读可写。sync服务端只在数据写入稳定存储后才返回响应这对一致性很重要虽然会损失部分性能。no_subtree_check禁用子树检查降低协议复杂度、提升性能。现在不太推荐用 subtree 检查反而容易出问题。no_root_squash允许客户端的 root 用户保留 root 权限访问共享目录。生产环境不建议这样这里只是演示。默认的root_squash会把 root 映射成 nobody这能提升安全性。建议再添加一条安全加固规则/srv/nfs/data 192.168.1.101(rw,sync,no_subtree_check,root_squash)改完配置后导出并重启服务exportfs -ra systemctl restart nfs-server在客户端服务器 B上挂载apt install nfs-common -y mount -t nfs4 192.168.1.100:/srv/nfs/data /mnt/data挂载成功后df -h里会出现对应的记录。开机自动挂载的话把这一条加进/etc/fstab192.168.1.100:/srv/nfs/data /mnt/data nfs4 defaults,_netdev 0 0_netdev很关键。它告诉系统网络就绪后再挂载避免因为网络还没起来导致挂载失败。3.2 把一块“网路硬盘”切给 iSCSI Target在服务器 A 上用 target 软件比如tgt或者targetcli把一块磁盘或文件导出成 LUN。最简单的方式是先用一个文件充当“虚拟磁盘”。我平时调试环境就这么干# 创建一块 10GB 大小的文件模拟磁盘 dd if/dev/zero of/srv/iscsi/disk01.img bs1M count10240 # 安装 targetcli apt install targetcli -y进入 targetcli 交互界面敲下面的命令targetcli # 进入 backstores 目录创建一个 fileio 后端存储 cd /backstores/fileio create disk01 /srv/iscsi/disk01.img 10G # 创建 target并绑定 IQN cd /iscsi create iqn.2024-01.com.example:storage-lun1 # 在 target 下创建 LUN 映射 cd iqn.2024-01.com.example:storage-lun1/tpg1/luns create /backstores/fileio/disk01 # 配置 ACL只允许指定 initiator 登录 cd /iqn.2024-01.com.example:storage-lun1/tpg1/acls create iqn.2024-01.com.client:initiator1 # 设置监听 IP 和端口默认 3260 cd /iqn.2024-01.com.example:storage-lun1/tpg1/portals create 192.168.1.100 3260把 IQN 记下来后面客户端登录要用。然后保证机器防火墙放行 TCP 3260否则客户端的 discovery 会直接超时ufw allow 3260/tcp在客户端服务器 B上操作apt install open-iscsi -y # 发现 target iscsiadm -m discovery -t sendtargets -p 192.168.1.100:3260 # 登录 iscsiadm -m node -T iqn.2024-01.com.example:storage-lun1 -p 192.168.1.100:3260 --login登录完成后用lsblk就能看到一个新的磁盘比如/dev/sdb。然后就可以像操作本地磁盘一样分区、格式化了fdisk /dev/sdb mkfs.ext4 /dev/sdb1 mount /dev/sdb1 /mnt/iscsi_data这套流程跑通后你会感受到 iSCSI 和 NFS 在“使用体验”上的天壤之别NFS 挂载完直接就是一个目录iSCSI 挂载完还要自己建分区、格式化多了一步但换来的是“这块盘完全归我管”的掌控感。3.3 选型决策指南一张表帮你快速判断当你需要快速确定用哪种协议时可以对照下面的表格勾选需求特征推荐协议原因Linux/Unix 机器间共享文件、目录NFS文件级共享天然适合零客户端兼容负担跨平台文件共享Windows/Linux/macOSNFSv4或 SMBNFS 在 Linux 生态体验更佳SMB 在 Windows 生态更佳给虚拟机提供数据存储跑 VMware/KVMNFS 或 iSCSI 均可取决于虚拟化平台特性和运维习惯需要启动远程操作系统无盘启动/集中部署iSCSI必须使用块级协议数据库、核心业务应用对随机 IO 敏感iSCSI块级路径开销更低更趋近本地磁盘体验需要多台主机同时读写同一文件的场景如共享工作目录NFS配合分布式文件系统文件级锁机制和一致性更成熟需要低成本、维护简单的普通文件备份NFS结构透明便于 rsync 等工具直接管理一句话总结选型思路只要不是特别需要“裸盘”能力优先考虑 NFS只要有“格式化分区、启动系统、跑专属文件系统”的需求大概率要用 iSCSI。4. 常见问题与排查技巧实录4.1 挂载 NFS 时出现 “Permission denied” 怎么办NFS 的权限问题九成是两种原因一是/etc/exports没配对。比如导出的网段只允许了192.168.1.101而你自己从192.168.1.102去挂载肯定被拒。修改 exports 文件后要记得exportfs -ra重新导出。二是客户端的 UID/GID 和服务端不一致。NFSv3 的认证本质上只看数字 ID不看用户名。检查方法很简单在服务端看共享目录的属主 UID然后在客户端用同名 UID 的用户去访问问题就解决了。这类问题可以通过在服务端用tail -f /var/log/syslog实时观察 RPC 请求的拒绝日志来定位到底卡在哪一步。4.2 iSCSI 登录超时或连接断开iSCSI 是一个基于 TCP 的长连接会话对网络稳定性要求极高。我遇到过比较多的情况是客户端和服务端之间有防火墙拦截了 3260 端口导致 discovery 阶段就超时。MTU 不匹配尤其是启用了巨型帧jumbo frame后交换机某个端口没开 9000 MTU导致数据包被丢弃。这个问题最隐蔽表现就是 ping 通、TCP 建连成功但传输大文件时随机断连或卡死。排查手段在两端同时执行ping -M do -s 8972 目标IP如果通说明巨型帧链路OK。多路径MPIO配置错误导致 I/O 路径切换时中断。如果你有多根网卡参与 iSCSI建议先把 MPIO 配好不要裸用多个网卡直接访问同一个 target。另外很多人在iscsiadm -m node --login后发现重启就掉线忘了设置自动登录。把下面这条加进去iscsiadm -m node -T iqn.2024-01.com.example:storage-lun1 -p 192.168.1.100:3260 --op update -n node.startup -v automatic这样登录状态会自动持久化重启服务器后客户端会自动重连。4.3 NFS 文件锁和缓存一致性NFS 在代码编译、数据库小文件读写等场景下偶尔会遇到 “No locks available” 或缓存不一致的情况。NFSv3 时代的锁服务不稳定是出了名的。如果真的要用 NFS 跑数据库类应用有几个要点强制使用 NFSv4锁管理集成进协议内部比 v3 稳得多。在挂载时加入hard选项默认就是 hard避免网络抖动时应用返回 I/O 错误。soft选项虽然看起来“友好”但会导致数据库误判写入失败别用。对于极端的一致性需求可以考虑actimeo0来禁用 client 端的属性缓存但这样会显著降低性能。一般不用这么激进actimeo30左右是很多生产环境的平衡点。4.4 安全加固别把存储裸奔在网络上不少人在内网环境图省事把 NFS 和 iSCSI 的认证都关了直接 IP 白名单就上。内网环境不一定出事但养成良好的安全习惯总是好的NFSv4 可以配置 Kerberos 认证seckrb5p虽然配置略繁但对于想保护数据的场景非常值得。iSCSI 有 CHAP 认证。通过 CHAP 至少可以防止未知 initiator 随便登录 target。配置示例# 在 target 的 ACL 下配置创建用户 cd /iqn.2024-01.com.example:storage-lun1/tpg1/acls/iqn.2024-01.com.client:initiator1 create user username set auth useridusername set auth passwordPassw0rd!客户端登录时也要带上用户名密码否则会被拒绝。尽量让存储流量走独立 VLAN 或独立网卡不要把存储流量和管理流量混在一起。一个广播风暴整条存储链路都跟着遭殃这种事故我经历过不止一次。4.5 性能实测建议先压测再上线很多运维朋友在实际部署时习惯直接挂上就跑等业务反馈慢了才开始排查。我的习惯是任何新的存储链路在上线前都要做一轮压测。对 NFS可以用fio做顺序写、随机读、小文件创建等不同负载模式的测试。重点观察吞吐量MB/s、IOPS、延迟的 P99 值。对 iSCSI同样可以用fio或 Windows 下的crystaldiskmark测试。重点观察多队列深度下的 IOPS 以及延迟抖动。压测时别忽略元数据操作的负载很多存储系统跑大文件读写没问题一遇到成千上万的小文件就原形毕露。所以测试负载一定要模拟实际业务。5. 写在最后的一些个人经验存储协议选型从来不是一道简单的二选一题。我见过很多公司把数据库跑在 NFS 上最后因为锁问题天天加班也见过有人非要用 iSCSI 来共享家目录结果因为多客户端并发写同一目录把文件系统搞得一塌糊涂。根据过往经验我再总结三条实实在在的建议没把握时先跑 POC。拿真实业务的数据集分别挂在 NFS 和 iSCSI 上跑一轮压测和真实业务模拟。性能看数据选型看需求不要拍脑袋。存储网络要舍得投入。不管选哪种协议万兆网卡和配套交换机带来的性能提升比纠结协议本身大得多。千兆网络下NFS 和 iSCSI 都容易成为瓶颈。运维一致性思维更重要。对于一个团队来说熟悉 NFS 的运维模式和熟悉 iSCSI 的运维模式完全不同。考虑方案时也要把团队的经验和能力考虑进去。NFS 在文件可见性、排障直观性上有优势iSCSI 在块设备兼容性、性能一致性上有优势。没有绝对的好坏只有合不合适的场景。最后再分享一个小技巧当你搞不清楚一个应用到底适合哪种存储协议时去查一下官方文档里提到的“共享文件系统”还是“独立磁盘”的选型说明。官方推荐的存储类型往往就直接标明了答案。希望这篇文章能让你对 NFS 和 iSCSI 有一个更立体的认识。技术选型的路上少踩几个坑项目推进就顺畅得多。