一次读懂 NFS、SMB、iSCSI、Ceph 与 FUSE:从一致性到挂载实战
真正的存储问题,80%不是磁盘,是协议、缓存和权限。
在团队里,我见过太多“明明已经写入”的数据却莫名消失,或“只有这台机器看不到最新文件”的离奇事故。溯源后,绝大多数都和共享/分布式存储的协议语义、缓存策略、身份与权限模型有关。本文把常见的五条路径捋顺:NFSv4(含 Kerberos)、SMB3、iSCSI 发起端(含 multipath)、CephFS/RBD 客户端,以及 FUSE 自定义挂载。目标是用一次阅读,建立统一的脑图和可落地的操作手册。特别说明:本文专注客户端与协议实践,不部署完整分布式存储集群。
目录
- 为什么是这五个
- 一致性与缓存:别把“看起来快”当“真的落盘”
- 权限与身份:POSIX、ACL 与域的“三体问题”
- 网络与安全:性能与风控的平衡
- 实战一:NFSv4 + Kerberos 客户端
- 实战二:SMB3 客户端(含加密与多用户)
- 实战三:iSCSI 发起端与 multipath 协同
- 实战四:Ceph 客户端(CephFS 与 RBD)
- 实战五:FUSE 自定义挂载最小实现
- 选型建议与常见陷阱清单
- 结语与互动
为什么是这五个
- NFSv4:Linux/UNIX 世界事实标准,语义接近 POSIX;v4 开始更“有状态”,支持 delegations 与 ACL,配合 Kerberos 可做到强认证与链路加密(krb5p)。
- SMB3:Windows 原生,和 AD/NTFS ACL 深度融合;3.x 带来签名、加密、持久句柄、多通道等能力。
- iSCSI:封装 SCSI 于 TCP/IP,让远端块设备像本地盘,适合数据库/虚机等要求稳定低抖动的场景。
- Ceph 客户端:CephFS 提供分布式 POSIX 语义文件系统,RBD 提供弹性块设备;云原生里的重要一环。
- FUSE:把任意用户态逻辑“挂成盘”,从对象存储桥接到加密覆盖层,实验与扩展的瑞士军刀。
一致性与缓存:别把“看起来快”当“真的落盘”
- NFSv4
- 模型:close-to-open 一致性。客户端可缓存数据与属性,但在 close() 与下一次 open() 之间保证可见性。
- 机制:delegation/lease 允许客户端独占缓存;冲突时服务器回收授权。
- 关键参数:acregmin/acregmax(文件属性缓存时间)、acdirmin/acdirmax(目录属性缓存)、lookupcache(目录查询缓存策略),rsize/wsize,nconnect(多 TCP 连接)。
- 结论:跨主机协作强依赖“正确使用 close/fsync”与合适的属性缓存窗口。
- SMB3
- 模型:oplocks/leases;客户端请求缓存许可,重命名/并发写入会触发租约打断(lease break)。
- 能力:持久句柄(durable handles)提高断线复原能力;签名与加密保障链路。
- 关键参数:cache=strict/none,actimeo,multiuser,seal(加密),sign(签名)。
- 结论:默认更激进缓存;需要 strict 缓存或显式 fsync 来保证跨主机可见性。
- iSCSI
- 模型:块级,不提供文件级一致性。上层文件系统负责一致性(journaling、barrier/FUA)。
- 风险:同一 LUN 被多个主机同时用本地文件系统(如 ext4/xfs)会数据灾难;多主机需使用集群文件系统(GFS2/OCFS2)。
- 关键:写缓存、flush、队列深度、MTU、延迟抖动。
- Ceph
- CephFS:客户端持有 capabilities(caps)管理数据/元数据缓存,强 POSIX 语义依赖 MDS;冲突时回收 caps 确保一致性。
- RBD:块语义;exclusive-lock + 客户端缓存(rbd_cache)提升性能,fsync/flush 保证落盘秩序。
- FUSE
- 用户态文件系统与内核页缓存配合。可选择 direct_io(绕过页缓存)、writeback_cache、attr/entry_timeout 等。
- 过于保守会慢,过于激进会“假快”。需按工作负载调。
权限与身份:POSIX、ACL 与域的“三体问题”
- NFSv4 ACL 与 idmap
- NFSv4 使用 NFSv4-ACL(与 POSIX ACL 不同),主体形如 user@domain。
- 需要 nfsidmap/idmapd 把 user@domain 映射到本地 uid/gid,或统一 UID/GID。
- Kerberos 模式:sec=krb5(认证)、krb5i(认证+完整性)、krb5p(认证+加密)。
- 服务器端 root_squash 务必了解:避免远端 root 直接变成本地 root。
- SMB3 与 AD/NTFS ACL
- 身份以 SID 为核心,和 AD 域无缝对接;NTFS ACL 精细且强大。
- Linux 客户端:可通过 mount.cifs 的 cifsacl、multiuser、sec=krb5 搭配 winbind/idmap 取得较好的兼容。
- iSCSI
- 不是文件共享,不提供文件 ACL。安全靠 IQN/LUN masking、CHAP/Mutual CHAP、网络隔离。
- CephX
- 客户端以 client.user 身份与能力(caps)鉴权;细粒度到池/路径/操作级。
- FUSE
- 权限模型由实现者决定。若做透传,需小心 uid/gid 映射、umask 以及 default_permissions。
网络与安全:性能与风控的平衡
- 端口与连通
- NFSv4:TCP 2049(通常无需 rpcbind);v3 还会用额外端口。
- SMB:TCP 445。
- iSCSI:TCP 3260。
- Ceph:MON 常用 3300(msgr2)/6789(msgr1);客户端一般连 MON 列表自动发现集群。
- 加密与签名
- NFS:Kerberos krb5p 提供链路加密。
- SMB3:签名默认常开;seal 开启加密(3.x)。
- iSCSI:原生无加密,建议内网、IPsec、VLAN 微隔离。
- Ceph:cephx 认证;msgr2 在新版本支持传输层加密(需端到端支持)。
- 性能提示
- MTU/Jumbo Frames 视链路与设备一致性决定,端到端一致才有收益。
- 避免 NAT;DNS/时间(NTP)要准确,Kerberos/SMB 对时钟与主机名敏感。
- 观察工具:nfsstat、mountstats、/proc/fs/nfsfs、dmesg|grep CIFS、iscsiadm -m session、multipath -ll、rbd status、ceph -s、fio。
实战一:NFSv4 + Kerberos 客户端
前提:已存在 NFSv4 服务器和 Kerberos KDC,服务器配置了 nfs/hostname@REALM 主体并放入 keytab,已导出 v4 伪根与目录;客户端与 KDC 可达且时间同步。
- 安装与基础
- Debian/Ubuntu:apt install nfs-common krb5-user nfs4-acl-tools
- RHEL/CentOS/Rocky:yum install nfs-utils krb5-workstation
- /etc/idmapd.conf 设置 Domain 与 Method;/etc/krb5.conf 配置 REALM/KDC。
- 获取票据并挂载
- kinit user@EXAMPLE.COM
- 创建挂载点:mkdir -p /mnt/nfs
- 挂载(Linux 5.3+ 可用 nconnect):
mount -t nfs -o vers=4.1,sec=krb5p,nconnect=4,clientaddr=客户端IP server.example.com:/export/projects /mnt/nfs
- 缓存与一致性调优
- 降低属性缓存窗口(更一致):-o acregmin=1,acregmax=5,acdirmin=1,acdirmax=5
- 遇到目录并发剧烈变更:-o lookupcache=positive 或极端 -o lookupcache=none
- 性能压测时可放宽:适度增大 rsize,wsize(现代内核自动协商较好)
- 权限与 ACL
- nfs4_setfacl/getfacl 管理 NFSv4 ACL:nfs4_setfacl -a A::user@EXAMPLE.COM:rwatTnNcCy /mnt/nfs/path
- 故障排查
- klist 确认票据;systemctl status rpc-gssd 或 gssproxy;nfsidmap -l 查看映射
- nfsstat -m 与 /proc/self/mountstats 观察重传/延迟
实战二:SMB3 客户端(含加密与多用户)
前提:已有 Samba/Windows 共享;若用 Kerberos,客户端已加入同域或可获取有效 TGT。
- 安装工具
- apt/yum install cifs-utils krb5-user
- Kerberos 凭据与多用户挂载
- kinit user@EXAMPLE.COM
- mkdir -p /mnt/smb
- 挂载(要求 SMB3.1.1 并启用链路加密):
mount -t cifs //fileserver/share /mnt/smb -o vers=3.1.1,sec=krb5,cruid=$(id -u),multiuser,seal,cache=strict - 多用户访问:不同用户使用各自 TGT 即可;如用密码而非 Kerberos,可配合 cifscreds 为多用户缓存凭据。
- 传统用户名口令挂载
- mount -t cifs //fileserver/share /mnt/smb -o vers=3.1.1,username=alice,domain=EXAMPLE,cache=strict,uid=1000,gid=1000,file_mode=0640,dir_mode=0750
- POSIX 兼容提示
- 建议 cache=strict;符号链接可用 mfsymlinks;Samba>4.19 双端可尝试 -o posix 获得更接近 POSIX 的语义。
- 故障排查
- dmesg | grep CIFS;mount.cifs -v 提高日志;确认 DNS/时间一致;如 Kerberos,确保 cifs.upcall 存在并可执行。
实战三:iSCSI 发起端与 multipath 协同
前提:存储阵列/目标端已创建 LUN 并允许客户端 IQN 访问,最好提供至少两条冗余路径(多网口或多控制器)。
- 安装与服务
- apt/yum install open-iscsi device-mapper-multipath
- systemctl enable --now iscsid iscsi multipathd
- 设置发起端名称:/etc/iscsi/initiatorname.iscsi
- 发现与登录
- 发现:iscsiadm -m discovery -t sendtargets -p 10.0.0.10
- 配置 CHAP(如需):
iscsiadm -m node -T iqn.2020-01.com.array:lun1 -p 10.0.0.10 --op=update --name node.session.auth.authmethod --value=CHAP
iscsiadm -m node -T iqn… --op=update --name node.session.auth.username --value=alice
iscsiadm -m node -T iqn… --op=update --name node.session.auth.password --value=‘s3cr3t’ - 登录并设置自动:
iscsiadm -m node -T iqn… --login
iscsiadm -m node -T iqn… --op=update --name node.startup --value=automatic
- 启用 multipath
- mpathconf --enable --with_multipathd y --find_multipaths yes
- 简要校验:multipath -ll 可见 mpatha(含多条路径);/dev/mapper/mpatha 成为聚合设备
- ALUA 环境可在 /etc/multipath.conf 指定 prio “alua”,并开启 features “1 queue_if_no_path”(需理解语义)
- 分区与文件系统
- mkfs.xfs -K /dev/mapper/mpatha 或 mkfs.ext4 -E lazy_itable_init=0,lazy_journal_init=0 /dev/mapper/mpatha
- 挂载:mount -o noatime,discard /dev/mapper/mpatha /mnt/iscsi
- 必知必会
- 切勿把同一 LUN 用本地文件系统在多台主机同时挂载;需要集群文件系统才安全。
- 测试故障切换:拔掉一条链路,multipath -ll 观察路径降级但卷仍可用。
- 性能:确保端到端 MTU 一致;适度调节队列深度与调度器;保持写屏障/flush(不要盲目 nobarrier)。
实战四:Ceph 客户端(CephFS 与 RBD)
前提:已有可用 Ceph 集群,拿到 ceph.conf 与客户端 keyring(cephx)。
- CephFS
- Kernel 客户端挂载:
mount -t ceph mon1,mon2,mon3:/ /mnt/cephfs -o name=client.alice,secretfile=/etc/ceph/ceph.client.alice.keyring,fs=cephfs - ceph-fuse(用户态,更新更灵活):
ceph-fuse -r / /mnt/cephfs --client_fs cephfs --name client.alice - 特性:支持 xattr 与 POSIX ACL;可用配额:
setfattr -n ceph.quota.max_bytes -v 1073741824 /mnt/cephfs/projects/a - 一致性:强 POSIX;高并发小文件对 MDS 压力较大,目录分片和客户端 caps 回收会影响延迟。
- Kernel 客户端挂载:
- RBD(块设备)
- 映射:
rbd device map pool1/img01 --id client.alice --keyring /etc/ceph/ceph.client.alice.keyring - 建议启用特性:
rbd feature enable pool1/img01 exclusive-lock,object-map,fast-diff,deep-flatten - 文件系统与挂载:mkfs.xfs /dev/rbdX;mount -o discard,noatime /dev/rbdX /mnt/rbd
- 缓存安全:
在 ceph.conf 或环境中设置
rbd_cache = true
rbd_cache_writethrough_until_flush = true - 多主机并发:RBD 是块设备;如需多主机同时访问,必须使用集群文件系统并正确配置锁特性,或改用 CephFS/NFS 网关。
- 映射:
实战五:FUSE 自定义挂载最小实现
目标:写一个只读“透传”文件系统,把真实目录挂载到新挂载点,演示 FUSE 工作流与缓存参数。示例基于 Python fusepy,便于快速试验。
-
准备
- apt/yum install fuse python3-pip
- pip install fusepy
- /etc/fuse.conf 取消注释 user_allow_other(允许 allow_other)
-
最小示例(保存为 passthrough.py)
-
代码要点:实现 getattr/readdir/open/read/release;透传到底层目录;只读更安全。
from fuse import FUSE, Operations
import os, stat, sysclass Passthrough(Operations):
def init(self, root):
self.root = root
def _full(self, path):
return os.path.join(self.root, path.lstrip(‘/’))
def getattr(self, path, fh=None):
st = os.lstat(self._full(path))
return {k: getattr(st, k) for k in (‘st_mode’,‘st_ino’,‘st_dev’,‘st_nlink’,
‘st_uid’,‘st_gid’,‘st_size’,‘st_atime’,‘st_mtime’,‘st_ctime’)}
def readdir(self, path, fh):
return [‘.’, ‘…’] + os.listdir(self._full(path))
def open(self, path, flags):
return os.open(self._full(path), flags & ~os.O_WRONLY & ~os.O_RDWR)
def read(self, path, size, offset, fh):
os.lseek(fh, offset, os.SEEK_SET)
return os.read(fh, size)
def release(self, path, fh):
os.close(fh)if name == ‘main’:
if len(sys.argv) != 3:
print(‘usage: python3 passthrough.py <real_dir> ’)
sys.exit(1)
FUSE(Passthrough(sys.argv[1]), sys.argv[2],
foreground=True, ro=True, allow_other=True,
attr_timeout=1, entry_timeout=1, negative_timeout=0)
-
-
运行与卸载
- mkdir -p /data/real /mnt/fuse
- python3 passthrough.py /data/real /mnt/fuse
- 测试后卸载:fusermount -u /mnt/fuse(有的发行版为 fusermount3)
-
缓存与权限
- 通过 attr_timeout/entry_timeout 控制属性与目录项缓存;ro+allow_other 避免写入风险且允许其他用户读。
- 若实现可写,建议开启 default_permissions,让内核先做权限校验,减少用户态往返。
选型建议与常见陷阱清单
- 如何选
- 主要是 Linux 到 Linux 文件共享:NFSv4(配 Kerberos)。需要与 Windows/AD 深度集成:SMB3。
- 单主机高一致性低抖动块存储:iSCSI(配 multipath)。
- 已有 Ceph 集群,需求 POSIX 语义与水平扩展:CephFS;需要“云盘”体验:RBD。
- 想把对象存储/加密/审计逻辑挂载成本地盘:FUSE 自定义。
- 常见陷阱
- 把 iSCSI LUN 同时挂多主机用 ext4/xfs,数据一定会坏。
- Kerberos/NFS/SMB 因为时钟或 DNS 配置漂移导致间歇认证失败。
- NFS 属性缓存窗口过大导致“另一个节点看不见最新文件”,误判为“丢数据”。
- 盲目关闭 SMB 签名/加密或使用过旧协议版本(如 SMB1),带来重大安全风险。
- multipath 未启用或配置不当,链路抖动即业务抖动;ALUA 优先级没用起来,读写走到了非优路径。
- CephFS/RBD 与客户端内核/工具版本不匹配,引发 obscure 的一致性或性能问题。
- FUSE 实现未处理好缓存与权限,表现“很快”但一掉电数据即丢。
结语与互动
存储共享不是“把目录挂上去”那么简单。协议语义、缓存策略、权限模型和网络安全,任一环短板都可能把你拖进“玄学问题”。希望这份横向梳理和纵向实战,能让你在 NFS、SMB、iSCSI、Ceph 与 FUSE 的交叉地带更游刃有余。
你在生产中踩过哪些与一致性、缓存或权限相关的坑?或者还有哪些协议/实践希望展开写一篇?欢迎在评论区交流。

4316

被折叠的 条评论
为什么被折叠?



