iSCSI多路径配置实战:双网卡双交换机实现链路冗余与负载均衡
发布时间:2026/10/22 15:34:36 锦皓数字建站

1. 项目缘起与整体设计思路存储这玩意儿单点永远是最脆弱的一环。我最早接触 iSCSI 是在一台老旧的备份服务器上单网线单路径跑了大半年平时风平浪静直到某次机房交换机例行重启备份任务直接挂死恢复的时候发现卷已经只读了。那次之后我就下定决心只要上 iSCSI必须做多径。这次实验的目标很明确用两台存储端或者一台存储的两个网口配合客户端的两块网卡搭一套能扛链路故障、能聚合带宽的 iSCSI 多径环境并且把链路切换、负载均衡、故障恢复这几个关键行为全部验证一遍。所谓 iSCSI 多径说白了就是客户端到存储端之间同时存在多条可达路径操作系统层面通过 multipath 子系统把这些路径聚合成一个逻辑设备。单条路径断了I/O 自动切到其他路径业务基本无感。它解决的核心问题是链路单点故障和单路径带宽瓶颈。适合谁来参考我觉得三类人最需要一是中小机房运维预算有限上不起光纤 SAN想用千兆或万兆以太网凑一套靠谱存储网络二是虚拟化平台管理员ESXi、KVM 这类宿主对共享存储的稳定性要求极高三是做数据库或备份的工程师对 I/O 连续性有硬性要求。哪怕你只是想在实验室里把原理跑通这套流程也能直接抄。整体设计上我选择的是“双网卡 双交换机 双存储口”的对称结构。为什么不用单交换机双网卡因为交换机本身也是单点一旦它挂了两条路径同时失效多径就失去意义了。双交换机虽然成本翻倍但换来的是一整条链路层面的冗余。存储端我用的是某开源存储方案导出两个 target 门户分别绑定两个不同网段的 IP。客户端两块网卡也分属这两个网段形成两条完全独立的路径。multipath 层用 Linux 自带的 device-mapper-multipath策略选的是 round-robin也就是轮询分发 I/O。这个选择后面会详细讲原因。提示实验环境里如果只有一台交换机也可以先把多径跑通但一定要清楚这只是功能验证不具备真正的链路冗余能力。2. 核心细节解析与实操要点2.1 多径的三种典型拓扑与选型逻辑在动手之前先把拓扑想清楚。我总结下来常见的有三种。第一种是单主机双网卡接双交换机存储端双口分别接两台交换机这是最标准的冗余结构任何一条链路断掉都不影响。第二种是单交换机双网卡客户端和存储都接同一台交换机这种只能防网卡故障防不了交换机故障但胜在成本低。第三种是客户端双网卡、存储单口这种严格来说不算完整多径因为存储端还是单点只适合做客户端侧的链路聚合测试。我这次选第一种理由很直接多径的价值在于消除所有单点如果存储端只有一个口那存储口一挂全完前面做的冗余全是白费。选型的时候还要注意网卡类型我强烈建议用独立物理网卡不要用板载双口或者 VLAN 子接口凑数。板载双口很多时候共享同一个 PCIe 通道真出问题可能一起挂VLAN 子接口底层还是同一块物理网卡物理链路断了两个子接口同时失效多径形同虚设。2.2 网段规划与 IP 分配网段规划这块我踩过坑第一次做的时候两条路径用了同一个网段结果路由表里只有一条默认路由multipath 死活认不出两条独立路径。后来改成两个不同网段问题立刻解决。具体分配如下路径 A 用 192.168.10.0/24客户端网卡 A 是 192.168.10.10存储门户 A 是 192.168.10.20路径 B 用 192.168.20.0/24客户端网卡 B 是 192.168.20.10存储门户 B 是 192.168.20.20。两个网段之间不做路由互通保证路径完全隔离。为什么要隔离因为如果两个网段能互通操作系统可能会把去往存储 B 的流量从网卡 A 发出去这样路径就交叉了multipath 看到的路径状态会混乱。隔离之后每条路径的流量严格走各自的网卡和交换机状态清晰可判。另外 MTU 我统一设成 9000也就是巨帧。iSCSI 走巨帧能显著降低 CPU 中断次数提升吞吐实测千兆环境下顺序读能提升大概 15% 到 20%。但要注意路径上所有设备——网卡、交换机、存储端——MTU 必须一致有一个环节是 1500 就会导致分片甚至丢包。2.3 multipath 配置文件的关键参数multipath 的核心配置在/etc/multipath.conf。默认配置里很多参数是注释掉的需要自己放开。我重点调了这几个。path_grouping_policy设成multibus意思是所有路径放在一个组里一起参与负载均衡。如果设成failover就只有一条路径干活其他待命带宽聚合就没了。path_selector用round-robin 0这是轮询策略I/O 依次分发到各条路径。rr_min_io_rq我设成 1000表示每 1000 个请求切换一次路径。这个值太小会导致频繁切换增加开销太大又起不到均衡效果1000 是我在千兆环境下测出来比较舒服的值。no_path_retry设成queue意思是所有路径都失效时I/O 进入队列等待而不是直接报错。这个参数非常关键它决定了链路全断时业务是挂起还是崩溃。设成 queue 之后只要在超时时间内有一条路径恢复I/O 就能继续业务无感。fast_io_fail_tmo设成 5 秒表示路径失效后 5 秒内快速失败避免 I/O 长时间卡住。dev_loss_tmo设成 30 秒超过这个时间路径还没回来就从系统里移除。这几个超时参数需要配合业务容忍度来调数据库这类敏感业务可以适当放宽。2.4 存储端 target 的导出细节存储端我用的是 LIOLinux-IOtarget配置在/sys/kernel/config/target/iscsi下面。每个 target 门户绑定一个 IP两个门户分别绑 192.168.10.20 和 192.168.20.20。这里有个细节同一个 target IQN 可以导出多个门户客户端发现的时候会同时看到两个入口multipath 才能识别成同一设备的多条路径。如果导出成两个不同的 IQNmultipath 会当成两块不同的磁盘那就不是多径了。ACL 配置也要注意客户端的两个发起端 IQN 都要加入 ACL或者干脆用同一个发起端 IQN 从两块网卡发起。我推荐后者因为同一个 IQN 对应同一个节点multipath 识别起来更干净。认证方面实验环境可以关掉 CHAP生产环境建议开启但要注意两个门户的 CHAP 凭据要一致否则一条路径认证失败会导致路径状态异常。3. 实操过程与核心环节实现3.1 基础网络与巨帧配置先配网络。客户端两块网卡分别命名为 ens33 和 ens34对应两个网段。用 nmcli 配置静态 IP命令如下nmcli con add type ethernet con-name pathA ifname ens33 ip4 192.168.10.10/24 nmcli con add type ethernet con-name pathB ifname ens34 ip4 192.168.20.10/24 nmcli con up pathA nmcli con up pathB配完 IP 之后设 MTU。用ip link set ens33 mtu 9000和ip link set ens34 mtu 9000然后ip link show确认。存储端两个网口同样设 9000。交换机如果是可管理的要在端口上开启巨帧支持很多默认是关闭的。验证巨帧是否通用ping -M do -s 8972 192.168.10.20-M do 表示禁止分片-s 8972 是 9000 减去 IP 头和 ICMP 头的开销。能 ping 通说明整条路径巨帧没问题。注意巨帧配置错误是 iSCSI 性能问题的高频原因。如果 ping 大包不通但小包通基本就是路径上某个设备 MTU 没改。3.2 存储端 target 创建与门户绑定存储端先创建后端块设备我用的是一个 100G 的逻辑卷。然后进入 configfs 创建 targetmkdir /sys/kernel/config/target/iscsi/iqn.2024-01.com.example:storage/tpgt1 mkdir /sys/kernel/config/target/iscsi/iqn.2024-01.com.example:storage/tpgt1/portal绑定两个门户echo 192.168.10.20:3260 /sys/kernel/config/target/iscsi/iqn.2024-01.com.example:storage/tpgt1/portal/10.20 echo 192.168.20.20:3260 /sys/kernel/config/target/iscsi/iqn.2024-01.com.example:storage/tpgt1/portal/20.20创建 LUN 并关联后端设备再配置 ACL 允许客户端 IQN 访问。完成后用targetcli ls检查结构确认两个门户都在同一个 tpgt 下面。这一步如果门户建到了不同的 tpgt客户端发现时会看到两个独立目标多径就失败了。3.3 客户端发现与登录客户端安装iscsi-initiator-utils和device-mapper-multipath。先启动 iscsid 服务然后发现目标iscsiadm -m discovery -t sendtargets -p 192.168.10.20:3260 iscsiadm -m discovery -t sendtargets -p 192.168.20.20:3260两条发现命令执行后iscsiadm -m node应该能看到同一个 IQN 对应两个门户。然后登录iscsiadm -m node -T iqn.2024-01.com.example:storage -l登录后lsblk会看到两块磁盘比如 sdb 和 sdc这其实是同一个 LUN 的两条路径。这时候还没做多径聚合直接挂载会有数据损坏风险千万别急着格式化。3.4 multipath 启用与聚合验证编辑/etc/multipath.conf加入设备配置defaults { path_grouping_policy multibus path_selector round-robin 0 rr_min_io_rq 1000 no_path_retry queue fast_io_fail_tmo 5 dev_loss_tmo 30 } blacklist { devnode ^sd[a]$ }blacklist 里把系统盘 sda 排除避免误聚合。然后启动服务systemctl enable --now multipathd multipath -llmultipath -ll的输出会显示一个 mpath 设备下面挂着 sdb 和 sdc 两条路径状态都是 active ready。这时候/dev/mapper/下会出现一个 mpathX 设备这才是真正要用的设备。格式化并挂载mkfs.xfs /dev/mapper/mpatha mkdir /mnt/iscsi mount /dev/mapper/mpatha /mnt/iscsi3.5 链路故障切换实测验证环节我做了三组测试。第一组拔掉路径 A 的网线观察multipath -ll输出sdb 状态变成 failedsdc 仍然是 active挂载点读写正常dd测试没有中断。第二组把路径 A 网线插回几秒后 sdb 自动恢复 active ready路径重新加入轮询。第三组两条网线同时拔掉I/O 进入 queue 状态dd命令卡住但不报错插回任意一条网线后 I/O 继续dd正常完成。这三组测试全部通过说明多径的故障切换和恢复机制工作正常。带宽聚合方面我用dd做顺序读测试单路径大概 110MB/s双路径轮询下跑到 200MB/s 左右接近千兆双口的理论上限。这里要注意聚合效果取决于 I/O 模式大块顺序读效果最好随机小 I/O 提升不明显因为轮询切换本身有开销。4. 常见问题与排查技巧实录4.1 多径识别失败排查表现象可能原因排查方法解决方式multipath -ll 只显示一条路径两条路径在同一网段检查 IP 配置和路由表改为不同网段显示两块独立磁盘存储端导出了两个 IQNtargetcli ls 检查合并到同一 target路径状态一直是 ghost门户绑定到了不同 tpgt检查 portal 目录结构重建到同一 tpgt聚合后设备无法挂载未格式化或文件系统损坏dmesg 查看报错重新 mkfs切换后 I/O 报错no_path_retry 设成了 fail检查 multipath.conf改为 queue4.2 几个容易忽略的坑第一个坑是rr_min_io_rq的单位。老版本内核里这个参数叫rr_min_io单位是请求数新版本改成rr_min_io_rq单位还是请求数但含义略有差异。如果配置里写错参数名multipathd 会静默忽略用默认值你以为调了其实没调。改完配置一定要multipathd reconfigure然后multipath -ll确认参数生效。第二个坑是 iSCSI 会话超时和 multipath 超时的配合。iSCSI 层有自己的node.session.timeo.replacement_timeout默认 120 秒。如果这个值比 multipath 的dev_loss_tmo还大路径失效后 iSCSI 层还在傻等multipath 已经判定路径丢失两边状态不一致会导致 I/O 异常。我的做法是把 replacement_timeout 设成 30 秒和 dev_loss_tmo 对齐行为就一致了。第三个坑是巨帧和 iSCSI 的交互。开了巨帧之后如果某条路径的交换机端口没开巨帧iSCSI 登录可能成功但大块 I/O 会超时重传表现为性能骤降而不是直接报错很难排查。我的经验是配好多径后先跑一轮dd大块读写确认吞吐正常再上业务。4.3 性能调优的几个实操心得除了巨帧和轮询还有几个参数值得调。max_sectors_kb可以适当调大默认 512我设成 1024让单次 I/O 传输更多数据减少切换次数。nr_requests队列深度也可以调但要看存储端能承受多少并发。另外网卡的中断亲和性建议绑定到不同 CPU 核避免两块网卡的中断挤在同一个核上。用ethtool -L可以调网卡队列数多队列配合多径效果更好。提示调优参数不要一次全上每改一项测一次否则出问题不知道是哪个参数导致的。5. 实验环境与生产环境的差异说明实验室里拔网线测切换很爽但生产环境有几个差异必须考虑。第一生产环境的交换机重启、固件升级、光模块老化都可能导致链路抖动multipath 的抖动抑制参数要调得更保守避免频繁切换。第二生产环境通常有多台客户端同时访问同一存储存储端的门户负载和会话数要提前规划别让一个门户过载。第三监控必须跟上multipathd show paths的状态、iSCSI 会话状态、路径切换次数都要纳入监控否则链路悄悄降级了你都不知道。我在实际使用中发现多径环境最怕的不是链路断而是链路“半死不活”——丢包率高但没完全断。这种情况下 multipath 可能认为路径还是 activeI/O 却大量重传性能暴跌。解决办法是开启 iSCSI 的 ping 检测或者用iscsiadm的node.conn[0].timeo.noop_out_interval参数定期发 noop 探测及时发现亚健康路径。这个细节常规文档很少提但生产环境里非常实用。最后再分享一个小技巧做多径实验的时候用watch -n 1 multipath -ll开一个窗口实时看路径状态另一窗口跑dd或fio拔插网线的瞬间能清楚看到状态变化和 I/O 行为比事后看日志直观得多。这套环境跑通之后后续扩展到四路径、跨交换机堆叠、甚至配合 RDMA 做 iSER思路都是一脉相承的。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。