资讯详情

资讯详情

iSCSI网络存储详解:从块存储原理到生产环境调优与排障

iSCSI这个词只要做过服务器运维或者数据中心相关工作应该都不陌生。它本质上是把SCSI存储协议封装到TCP/IP网络里传输让远端主机像插着一块本地硬盘一样使用网络上的存储设备。说白了就是用网线把存储空间“拉”到服务器上成本和复杂度都比传统光纤SAN低一大截。给虚拟化集群做共享存储、给数据库服务器扩盘、给备份系统挂大容量池iSCSI都能派上用场。这篇文章从最基础的概念讲到生产环境的调优和排障适合刚接触网络存储的新手也适合已经在用但想再抠一抠细节的老手。我尽量把配置命令、参数含义、踩坑经验都写到看完可以直接照着折腾。1. 为什么选iSCSI它到底解决了什么问题1.1 从“买存储”和“用存储”的差别说起很多刚接触存储的人会有个误区存储不就是一块大硬盘嘛。真到业务侧其实完全两码事。虚拟化平台要求多台物理机共享同一份存储数据库要求存储支持SCSI锁和原子写备份系统要求容量能弹性扩展。这些东西不是拿个USB硬盘就能糊弄过去的。iSCSI的切入点就在这里。它给网络上的服务器提供的是“块设备”也就是LUN。从操作系统的角度看这就是一块完整的磁盘可以随便分区、格式化、做LVM、跑文件系统。本地磁盘能做的操作它基本都能做只不过数据通过网卡和交换机传输。这个特性让它和NFS、SMB这类文件共享协议有本质区别——文件共享给你的是一个目录块存储给你的是整块磁盘。那为什么不直接上光纤SAN因为贵。光纤交换机、HBA卡、专用存储阵列一套下来动辄几十万起。iSCSI只需要普通千兆/万兆以太网交换机和服务器自带网卡软件方式就能把一台普通的Linux服务器变成存储目标端。部署成本可能只有光纤方案的十分之一。对于预算有限的实验室、中小公司集群、边缘机房这是非常现实的方案。1.2 iSCSI的适用场景与不适用场景以我实际接触过的项目来看iSCSI主要适合这几类场景虚拟化集群的共享存储。多台虚拟化宿主机通过iSCSI连接同一台存储服务器配合集群文件系统或虚拟化平台自带的分布式文件系统使用能实现虚拟机在线迁移和故障转移。数据库服务器的远程磁盘扩展。数据库对块设备的随机读写能力要求高服务器本地盘不够用时通过iSCSI挂载一个性能足够的存储池比迁移整个库简单得多。备份系统的集中存储池。备份数据量大但访问频率不高对性能和时延要求宽泛iSCSI挂个大容量存放数据非常合适。不太适合的场景也得说清楚。如果主存储设备本身性能一般千兆网络带宽又只有100MB/s出头那整条链路的瓶颈会很明显给数据库这种高IOPS业务用就有点勉强了。还有就是跨三层路由的远端挂载延迟容易抖SCSI协议本身对超时很敏感乱序或丢包会导致磁盘报错甚至文件系统损坏。iSCSI推荐放在二层直连或同机房低延迟网络内不要想着在公网或跨城域网上挂块盘那是给自己挖坑。1.3 与同类协议的横向对比做过存储方案选型的人应该经常在这几个协议之间纠结。我简单整理了一张对照表协议类型客户端形态典型场景成本iSCSI块存储磁盘虚拟化、数据库、共享盘低NFS文件存储目录文件共享、无状态应用低SMB/CIFS文件存储目录办公共享、Windows文件服务低FC SAN块存储磁盘核心数据库、高可靠存储高NVMe-oF块存储磁盘高吞吐低延迟存储高NFS虽然用起来简单但对数据库这类需要自己管理锁的应用不友好。FC SAN性能最稳可“稳”的背后是昂贵的专用硬件。iSCSI处在中间位置牺牲了一部分性能和绝对稳定性换来了极低的部署门槛和不错的兼容性。尤其现在万兆网卡越来越便宜iSCSI的性能已经不像早年那么拉胯很多非核心生产环境都能扛得住。2. 核心概念Target、Initiator、LUN与IQN的梳理2.1 三个角色名词一次搞清楚iSCSI网络里有三个基本角色目标端、发起端和LUN。目标端就是提供存储的那台机器通常叫Target。它把自己的一块磁盘、一个分区、一个LVM卷或者一个文件作为块设备后端发布到网络上等待别人来连接。发起端是使用存储的那台机器叫Initiator比如正在跑虚拟化的物理服务器只要系统里装了iSCSI发起程序就能主动连上Target并把LUN识别成一块本地磁盘。LUN则是Target上实际对外提供的那块逻辑磁盘一个Target可以包含多个LUN每个LUN就是一个独立磁盘设备。用生活化的方式理解Target就是仓库管理员Initiator就是取货的货主LUN就是仓库里编号的货架。货主货车开到仓库门口管理员把对应货架推到装货口货主就觉得这是自己仓库的一部分完全不用关心仓库里具体怎么摆放。操作系统看到LUN之后也完全不关心这块盘在远端怎么组成的。2.2 IQN命名规则与唯一性IQN是iSCSI里用来标识目标端和发起端的名字全称叫iSCSI Qualified Name。格式看起来有点古怪比如iqn.2024-05.local.storage:target01拆开看也很简单iqn是固定前缀2024-05是域名注册时间的年份和月份local.storage是反向写的域名或组织名最后冒号后面是自定义的设备标识。这套规则借鉴了DNS反解的逻辑目的是让名字在全球范围内尽量不冲突。我的建议是命名规则从一开始就定好。比如所有Target统一叫iqn.年份-月份.公司内部域名:role-用途-编号所有Initiator统一叫iqn.年份-月份.公司内部域名:initiator-用途-编号。命名规则一旦乱了后续几十台机器连来连去你会疯掉的。我就见过有人随手起了iqn.test123这种名字结果另一台设备也有一个类似的两者直接在日志里互相干扰排查了半天才明白是命名冲突。2.3 LUN、Target与ACL的关系一个Target上可以挂多个LUN而一个Initiator可以连接多个Target。为了安全Target上还必须有访问控制列表ACL。ACL里面记录哪些Initiator的IQN允许连进来以及连接时使用的CHAP用户名密码。ACL在iSCSI里的地位很容易被忽略。很多人图省事把Target的认证设成“允许所有人”结果在同一二层网络里的任何机器只要装个iSCSI发起程序就能把整块盘挂走。这不是危言耸听我真的见过某测试环境的存储被其他部门服务器误连然后对方格式化分区把整组数据盘抹了的惨案。所以ACL和CHAP这两样东西从第一天就必须开。3. 环境准备与基础配置3.1 底层存储规划直接用磁盘还是文件模拟搭建iSCSI Target之前先解决最底层的存储从哪来的问题。常见做法有几种整块物理磁盘或分区共享给LUN。用LVM逻辑卷做LUN后端方便后续扩容。用RAID卡先做好阵列再用整盘映射。用稀疏文件模拟测试环境常用性能一般。生产环境我最推荐LVM逻辑卷或物理磁盘。LVM的好处是以后扩容时只需要扩展LV再让LUN变大比重新建Target省事得多。文件模拟听起来简单但性能损耗明显而且文件系统本身的页缓存机制会导致数据先写缓存、异步落盘这在某些数据库场景下会造成数据安全风险。测试玩可以生产别这么干。如果是用Linux系统做Target内核自带的LIO引擎配合targetcli工具就足够用了。LIO是内核级Target实现性能比早年的用户态方案好很多而且是各大Linux发行版默认集成的不需要买商业软件。targetcli则是一个命令行交互工具能帮你管理target和LUN的配置。3.2 目标端完整配置命令实录假设你有一台Linux服务器上面有一块空闲磁盘/dev/sdb我们要把它发布成iSCSI Target。安装targetcli之后进入交互界面sudo targetcli然后依次执行以下操作# 创建一个块设备后端的存储对象名字叫disk1指向 /dev/sdb cd /backstores/block create disk1 /dev/sdb # 查看一下当前状态确认backend已经创建好了 ls # 创建TargetIQN按之前定的规则写 cd /iscsi create iqn.2024-05.local.storage:target01 # 进入这个Target的TPG (Target Portal Group) cd iqn.2024-05.local.storage:target01/tpg1 # 把disk1挂成这个Target下的LUN 0 luns create /backstores/block/disk1 # 设置该Target监听在哪些IP和端口上默认3260 portals create 192.168.10.10 3260 # 设置允许连接的发起端IQN acls create iqn.2024-05.local.client:initiator01 # 查看当前完整配置 ls # 保存配置 saveconfig上面的操作看起来琐碎但每一步都有意义。backstores是存储后端的池子block类型表示真正的块设备TPG是Target的配置组里面的LUN、ACL、监听端口都归它管理portals create指定了客户端要连接的IP和端口一台机器尤其是多网卡的这一步不指定的话Linux会默认监听所有地址存在一定的暴露风险。配完Target还不能忽略CHAP认证。在targetcli里做如下设置cd /iscsi/iqn.2024-05.local.storage:target01/tpg1/acls/iqn.2024-05.local.client:initiator01 set auth useridstorageuser set auth passwordStr0ngPss2024这里设置的是一个单向CHAP客户端连接Target时要向Target证明自己知道这个用户名和密码。如果还想做双向CHAP让Target也向客户端证明身份还需要在Target的TPG级别配置cd /iscsi/iqn.2024-05.local.storage:target01/tpg1 set auth useridtargetuser set auth passwordTrgetPss2024 set attribute authentication1配置完成后用saveconfig把配置持久化到文件。很多新手漏了这一步重启机器后配置全没追悔莫及。targetcli的配置默认保存在/etc/target/saveconfig.json建议保存完再cat一眼确认文件没问题。3.3 防火墙与服务的启动细节Target端的端口是TCP 3260。生产环境肯定有防火墙别配置了Target发现客户端怎么都连不上最后把防火墙关了才通这种操作在运维现场不可取。正确做法是在防火墙上放行特定来源IP对3260端口的访问sudo firewall-cmd --permanent --add-rich-rulerule familyipv4 source address192.168.10.0/24 port protocoltcp port3260 accept sudo firewall-cmd --reload同时把Target服务设为开机自启避免重启后没人去手动拉起来。这里我还想多说一句尽量把存储流量隔离到独立网段不要和业务网络、管理网络混在一起。原因后面性能部分我会细讲。4. 发起端连接实操Windows与Linux两条路线4.1 Windows系统发起端配置步骤Windows系统自带iSCSI发起程序使用起来比大多数人想象中简单得多。打开“iSCSI发起程序”第一次运行会提示是否要启动服务选是即可。然后在“目标”标签页填入Target服务器的IP地址点击“快速连接”系统会自动发现该IP上的Target。如果配置了CHAP认证就需要在“连接”按钮的下拉菜单里选择“高级”在弹出的窗口里勾选“启用CHAP登录”填入用户名和密码。这里有个细节某些场景下Windows发起端要求填入Target侧名称并指定目标门户——但大多数情况下只要用户名密码正确连接是秒通的。连接成功之后你在“磁盘管理”里看不到盘的话别慌张。打开“磁盘管理”点击菜单栏的“操作”选择“重新扫描磁盘”新挂载的iSCSI LUN就会出现在磁盘列表里。接下来就是常规操作初始化磁盘、新建卷、分配盘符、格式化文件系统。还有一个关键点Windows的iSCSI发起程序服务必须设为“自动”。如果没有设自动机器重启后服务没起来挂载的盘符也不会自动恢复。虽然登录系统后可以手动连接但跑业务的服务器哪有时间去手工干预。检查一下“服务”里的“Microsoft iSCSI Initiator Service”确保启动类型是自动。4.2 Linux发起端与持久化配置Linux客户端最常用的工具是iscsiadm。包名叫什么不重要发行版软件源里搜iscsi相关包名装好就行。客户端配置文件通常在/etc/iscsi/iscsid.conf先确认里面默认的CHAP设置是不是符合你的环境。先做发现sudo iscsiadm -m discovery -t sendtargets -p 192.168.10.10:3260如果CHAP已配置执行之前要先改配置文件或者在登录时用--interface、--op参数显式带上CHAP用户名密码。实际更推荐的做法是写进配置文件的node部分这样后续自动登录时也能用上。发现成功后系统会生成一条node记录。登录目标sudo iscsiadm -m node -T iqn.2024-05.local.storage:target01 -p 192.168.10.10:3260 --login登录成功后用lsblk查看新出现的磁盘。接下来分区格式化就直接操作。关键是持久化配置。Linux这边不设置的话重启后还是不会自动连接。把node的启动方式设为自动sudo iscsiadm -m node -T iqn.2024-05.local.storage:target01 -p 192.168.10.10:3260 -o update -n node.startup -v automatic这样iscsi服务会在启动时自动登录并挂载。但如果使用了文件系统自动挂载也就是写入/etc/fstab挂载选项里必须加_netdev告诉系统这个设备依赖网络等网络就绪后再挂载。UUIDxxxxxx /data ext4 _netdev,defaults 0 0别把_netdev漏了否则启动顺序不对系统会报“挂载设备不存在”严重时Linux会在等设备超时期间卡很久。这个坑我踩过不止一次。4.3 多路径挂载与高可用考虑生产环境如果有多块网卡、多台存储可以做多路径。多路径的意思是主机和存储之间有不止一条物理路径操作系统把它们合并成一个虚拟磁盘设备既能提高带宽还能在单链路故障时自动切换。Windows那边需要启用“多路径I/O”功能然后在iSCSI发起程序里把目标门户地址都添加好让同一个Target通过多个IP都能发现。在“磁盘管理”里确认新盘是否被识别为多路径磁盘。Linux则需要装multipath-tools并配置/etc/multipath.conf把iSCSI设备加入黑名单过滤规则让dm-multipath接管。多路径配置不是必须的但凡是跑虚拟化、数据库这种7x24业务建议还是配上。毕竟单根网线、单个交换机、单台存储任何一个节点挂了服务都会断。多路径可以在不改变上层应用的情况下把底层故障的感知降到最低。5. 性能调优与安全加固别让存储变成瓶颈5.1 网络层优化与MTU设置很多iSCSI性能问题根本原因不在存储服务器而是网络。千兆环境下iSCSI理论最大吞吐约125MB/s去掉TCP/IP开销实际跑到100MB/s就算不错。想突破这个上限要么升级万兆要么做链路聚合。万兆网卡这几年价格已经很低值得投入。开启巨型帧MTU 9000是提升性能的常见手段。注意MTU必须端到端全链路支持Target网卡、发起端网卡、所有交换机端口统统设成9000。只要有一台交换机还停留在1500就会触发分片重组性能反而下降甚至出现超时。配置前先确认交换机型号和端口支持情况这种基础问题最容易忽略。我在调优时习惯先做基准测试用工具测一下存储吞吐和IOPS再调整参数对比。没有基线数据所谓的优化都是盲人摸象。5.2 存储侧参数缓存、对齐与调度存储侧几个参数值得关注。文件系统对齐。传统机械盘和现代SSD都要求分区对齐到4K边界。如果LUN在创建文件系统时没对齐性能损失可能达到20%以上这是最容易被忽略的隐性损耗。文件系统IO调度器。SSD后端可以选择none或noop调度器来减少CPU开销机械盘则保留mq-deadline。这个参数在/sys/block/sdX/queue/scheduler里可以临时改生产环境建议通过内核引导参数或配置管理工具固化。写缓存。如果LUN后端是真正的RAID卡阵列硬件写缓存能大幅提升小文件写入性能。但服务器意外断电时如果RAID卡电池或缓存保护模块状态不佳就存在数据丢失风险。强烈建议定期检查阵列卡缓存状态别让写缓存成为隐患。还有iSCSI协议层的一个参数MaxRecvDataSegmentLength控制单次SCSI数据段的最大长度默认值往往偏保守。在发起端和Target两侧都调大到256K能减少传输次数对大块顺序读写有明显改善。但注意这个参数不是所有网卡、驱动都完美兼容修改后务必跑一遍读写测试。5.3 安全加固CHAP、ACL与网络隔离安全这一块字字都是经验教训换来的。CHAP认证必须开。用户名密码不要用弱口令密码长度至少12位以上包含大小写字母、数字和特殊符号。更进一步可以做双向CHAP让客户端也校验Target的身份防止中间人伪造设备。ACL白名单必须配。确保只有明确允许的IQN才能连入Target。IQN不要用默认的iqn.1993-08.org.debian:01:xxxx这类自动生成的名字长期维护阶段你会分不清这是哪台机器。存储专用VLAN。iSCSI流量和普通业务流量分开跑配合交换机上的PVLAN或ACL规则让存储网段和其他网段二层隔离。三层路由要严格控制一般存储网段不应该对业务网段开放路由只有同属存储系统的主机才能互相通信。还有一点容易被忽略管理接口安全。targetcli或者存储管理页面如果暴露在业务网段一旦被攻破存储系统直接沦陷。管理口单独走带外网络或者用堡垒机跳转访问是基本的安全底线。6. 常见故障排查与避坑指南6.1 连接失败从防火墙到名称全梳理连接失败是最常见的故障。我的排查顺序一般是网络连通性。发起端和目标端之间先ping通不通注意MTU大小的差距必要时用ping -s 8972测试巨型帧链路。防火墙。确认目标端3260端口对源IP放行。曾在客户现场排查半天最终发现是云安全组规则没加。发现命令执行结果。如果sendtargets发现不到重点检查Target是否在监听正确网卡IP以及portals配置里填的地址是否有误。IQN和ACL。确认发起端的IQN确实在ACL列表里。大小写写错、末尾多了个冒号这类低级错误真的经常发生。CHAP认证。确认用户名密码无误特殊字符时注意shell转义问题。6.2 连接后看不到磁盘或丢失磁盘连接成功但系统里没有新盘多半是磁盘扫描的问题。Windows里手动“重新扫描磁盘”Linux里用partprobe或blockdev --rereadpt重新读取分区表一般就能解决。重启后掉盘又是另一个高频问题。Windows检查iSCSI服务是否自动启动Linux检查node.startup是否为automatic同时确认/etc/fstab的挂载项有没有_netdev。还有一个坑是网络和iscsi服务的启动顺序某些发行版上需要开启iscsid和iscsi两个服务漏一个都不行。如果出现LUN“看起来连着但读写就报IO错误”多半是链路不稳定或者Target端存储后端出了状况。这时先看系统日志dmesg里通常会有connection timed out或session recovery相关记录同时关注Target端存储的磁盘健康状态。6.3 性能不达标时从哪里查起性能问题排查比连接问题复杂不少我的经验是分层排查法。网络层先测用iperf跑一下Target和发起端之间裸吞吐。如果裸网络本身就跑不到预期说明瓶颈在网卡、交换机或网线存储层面背不了这个锅。测的时候注意多线程单线程TCP流测出来的数值往往偏低。存储层再测在存储服务器本地对后端设备做读写测试确认后端存储本身性能达标。本地都慢那没必要查iSCSI了。协议层最后查确认MTU、QueueDepth、MaxRecvDataSegmentLength这些参数在两侧保持一致。不同厂商的实现细节有差异别一边改了另一边没改那样反而制造瓶颈。我在实际调优时遇到过一种情况测试工具单队列跑时吞吐很差但多队列就正常。原因是发起端网卡没有开启多队列或者RSS哈希配置不准导致所有流量都压在一个CPU核上。这种问题不看mpstat的软中断信息很难发现。6.4 扩容LUN与在线调整的注意点业务跑着跑着空间不够了扩容是绕不开的话题。如果LUN后端是LVM卷扩容流程是先在Target端把LV扩容再让对应LUN也变大最后在发起端执行磁盘重新扫描或文件系统扩容。以targetcli为例扩大LUN的办法是先在后端存储上扩容sudo lvextend -L 200G /dev/vg01/lun01然后重新设置backstore的size。targetcli里的/backstores/block下的条目通常会自动感知块设备变化但保险起见还是显式执行一次resize。Linux发起端用rescan-scsi-bus.sh或blockdev --rereadpt让系统识别新容量最后ext4用resize2fs在线扩张xfs用xfs_growfs。整个过程强调一个原则先扩后端再扩LUN最后扩文件系统顺序不能乱。扩LUN前强烈建议先做快照或备份。在线扩容本身有风险断电、断网、操作失误都有可能让文件系统挂掉。别拿生产数据赌运气。最后再聊几句iSCSI这些年能一直有一席之地靠的不是炫技而是实用。它把一个企业级存储的概念拉到了中小团队甚至个人实验室都能折腾的层次。我自己在实际操作中的体会是iSCSI的上限不取决于协议本身而取决于你对网络和存储基础的理解水平。网络不稳再好的存储阵列也白搭存储规划乱再高的带宽都救不了延迟。刚开始折腾时不用追求一步到位的多路径、万兆、双活先把一台存储、一个客户端、一条CHAP认证链路跑通再慢慢往里加复杂度。等哪天真出了故障你会发现当初每一步打牢的基础都是排障时的救命线索。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →