当前位置: 首页 > news >正文

Ubuntu 22.04下用Tgt搭建iSCSI共享存储的完整流程(含多客户端配置)

在Ubuntu 22.04上构建企业级iSCSI共享存储:Tgt实战与多客户端并发访问深度指南

最近在为一个中小型开发团队搭建统一的测试数据存储环境时,我再次将目光投向了iSCSI。你可能听说过NFS或者Samba,但在需要块设备级别共享、追求更低延迟和更高性能的场景下,iSCSI往往是更专业的选择。尤其是在虚拟化环境、数据库集群或者需要共享同一块“物理”磁盘给多台服务器的场景里,iSCSI提供的是一种近乎直连的存储体验。而Ubuntu 22.04 LTS作为当前长期支持版本,其稳定性和软件生态使其成为部署这类服务的理想平台。今天,我们就来深入聊聊如何用Tgt这个轻量高效的iSCSI Target软件,在Ubuntu 22.04上打造一个不仅能用,而且好用、安全的共享存储系统,并重点攻克多客户端并发访问这一常见痛点。

1. 理解iSCSI与Tgt:为何选择这个组合?

在动手之前,我们有必要先理清几个核心概念。iSCSI(Internet Small Computer System Interface)本质上是一种将SCSI命令封装在TCP/IP网络包中进行传输的协议。它允许客户端(Initiator)通过网络访问远程服务器(Target)上的存储设备,就像访问本地硬盘一样。这种架构带来的最大好处是解耦了计算与存储,使得存储扩容、数据迁移和维护变得异常灵活。

那么,在Linux世界里实现iSCSI Target的工具有不少,比如LIO(Linux-IO Target)、SCST和Tgt。我偏爱Tgt的原因在于它的“简单直接”。Tgt(STGT的继承者)配置语法直观,文档清晰,对于大多数中小规模的应用场景来说,它提供了恰到好处的功能集,而不会引入不必要的复杂性。它的后台服务tgt在Ubuntu仓库中维护良好,安装和后续升级都省心。

注意:选择存储方案时,需要明确你的需求。如果你需要极致的性能调优和最丰富的企业级功能(如完整的SCSI-3持久预留支持),可能需要评估LIO。但对于开发测试、中小型文件服务器、虚拟机共享存储等场景,Tgt的易用性和稳定性已经绰绰有余。

一个典型的Tgt iSCSI架构包含以下组件:

  • Target(目标端):运行Tgt服务的Ubuntu服务器,它“导出”一个或多个存储块设备(LUN)。
  • Initiator(发起端):需要连接并使用这些存储的客户端,可以是另一台Ubuntu服务器、Windows机器,甚至是ESXi主机。
  • IQN(iSCSI Qualified Name):每个Target和Initiator的唯一标识符,格式通常为iqn.YYYY-MM.倒序域名:自定义标识

理解了这些,我们就可以开始动手搭建了。

2. 目标端(Target)部署:从安装到精细配置

我们的旅程从存储服务器开始。假设你有一台安装了Ubuntu 22.04 LTS的机器,并准备好了一块用于共享的磁盘(例如/dev/sdb)。如果使用虚拟机,可以添加一块新的虚拟硬盘。

2.1 安装与基础服务管理

首先,更新软件包列表并安装tgt。在Ubuntu 22.04上,这个过程非常简洁。

sudo apt update sudo apt install tgt -y

安装完成后,系统会自动启动tgt服务并启用开机自启。我们可以检查一下服务状态,确保它正在健康运行。

sudo systemctl status tgt

你应该能看到类似“active (running)”的输出。如果服务没有启动,使用sudo systemctl start tgt手动启动,并用sudo systemctl enable tgt确保开机自启。

2.2 核心配置:定义你的存储目标

Tgt的配置文件主要位于/etc/tgt/conf.d/目录下。推荐的做法是为每个Target创建独立的配置文件,而不是全部堆在/etc/tgt/targets.conf里,这样管理起来更清晰。我们来创建一个名为mydatastore.conf的配置文件。

sudo nano /etc/tgt/conf.d/mydatastore.conf

接下来是配置的核心部分。我们将定义一个Target,并指定要共享的后端存储。这里假设我们使用整块磁盘/dev/sdb

<target iqn.2024-05.local.ubuntu:tgt.datastore> # 共享的存储设备,这里是一个完整的磁盘 backing-store /dev/sdb # 为LUN分配一个ID,默认为0,但显式声明是个好习惯 lun 1 # 设置厂商信息,便于客户端识别 vendor_id MyStorageCorp # 启用写缓存(根据硬件和需求谨慎设置) write-cache on # 可选的CHAP认证,增强安全性(后续详述) # incominguser myusername mysecretpassword </target>

对关键参数的解释:

参数说明建议值/示例
backing-store后端存储设备的路径。可以是物理磁盘(/dev/sdb)、分区(/dev/sdb1)、镜像文件或逻辑卷。根据实际设备填写
lun逻辑单元号。一个Target下可以有多个LUN。通常从1开始
vendor_id厂商标识字符串,会在客户端显示。自定义,便于识别
write-cache是否启用写缓存。启用可提升性能,但在断电等异常情况下有数据丢失风险根据数据安全性要求选择

保存并退出编辑器。然后,重新加载Tgt的配置,使其生效。这里有个小技巧:使用reload而不是restart,可以避免中断已建立的连接(如果有的话)。

sudo tgt-admin --update all # 或者使用systemctl重新加载服务 sudo systemctl reload tgt

现在,使用tgt-admin命令验证我们的Target是否已正确加载并在线。

sudo tgt-admin --show

输出应该会详细显示你刚定义的Target信息,包括它的IQN、状态以及关联的LUN详情。

2.3 网络与防火墙配置

iSCSI默认使用TCP 3260端口。确保你的防火墙允许该端口的入站流量。如果使用Ubuntu内置的ufw,命令如下:

sudo ufw allow 3260/tcp sudo ufw reload

如果你的服务器在云上(如AWS、Azure、GCP),别忘了在云服务商的安全组/防火墙规则中同样开放3260端口。

3. 发起端(Initiator)配置:单客户端连接

现在,切换到另一台作为客户端的Ubuntu 22.04机器上。我们需要安装open-iscsi软件包,它包含了iSCSI发起端所需的工具。

sudo apt update sudo apt install open-iscsi -y

安装后,服务open-iscsi会自动启动。接下来,我们将发现并登录到目标端。

  • 发现目标:使用iscsiadm命令,指定目标端服务器的IP地址进行发现。

    sudo iscsiadm -m discovery -t st -p 192.168.1.100

    请将192.168.1.100替换为你Tgt服务器的实际IP地址。成功后,你会看到类似下面的输出,其中包含了目标端的IQN:

    192.168.1.100:3260,1 iqn.2024-05.local.ubuntu:tgt.datastore

    这条信息会自动记录到/etc/iscsi/nodes/目录下。

  • 登录目标:执行登录命令,建立连接。

    sudo iscsiadm -m node --targetname iqn.2024-05.local.ubuntu:tgt.datastore --portal 192.168.1.100 --login

    看到“successful”的提示即表示登录成功。

此时,在客户端使用lsblkfdisk -l命令,你应该能看到一个新的磁盘设备,通常命名为/dev/sdX(如/dev/sdc)。它现在就像一块本地硬盘一样待你使用。

  • 格式化和挂载:你可以像操作普通硬盘一样,对其进行分区、创建文件系统并挂载。

    # 假设新磁盘是 /dev/sdc sudo mkfs.ext4 /dev/sdc sudo mkdir /mnt/iscsi_shared sudo mount /dev/sdc /mnt/iscsi_shared

    现在,/mnt/iscsi_shared目录就可以用来读写数据了。

  • 配置自动连接与挂载:为了让系统重启后能自动连接iSCSI磁盘并挂载,需要做两件事。

    1. 将iSCSI节点配置为自动登录:
      sudo iscsiadm -m node --targetname iqn.2024-05.local.ubuntu:tgt.datastore --portal 192.168.1.100 --op update -n node.startup -v automatic
    2. /etc/fstab中添加挂载项。这里有个关键点:不能直接用/dev/sdc,因为设备名可能变化。推荐使用磁盘的UUID。先用blkid命令获取UUID:
      sudo blkid /dev/sdc
      然后在/etc/fstab中添加一行:
      UUID=你的磁盘UUID /mnt/iscsi_shared ext4 _netdev,defaults 0 0
      注意_netdev挂载选项非常重要,它告诉系统这是一个网络设备,必须在网络就绪后再尝试挂载。

4. 多客户端并发访问:挑战与解决方案

让多个客户端同时连接同一个iSCSI Target很容易,但让它们安全、有序地并发读写同一块磁盘,则是另一个层面的挑战。这是很多初学者容易踩坑的地方。

4.1 问题本质:文件系统锁

当你将/dev/sdb通过iSCSI共享给客户端A和客户端B后,它们各自看到的是一块“物理”硬盘。如果两个客户端都在上面创建了ext4XFS这样的常规Linux文件系统,并同时挂载读写,后果将是灾难性的——文件系统元数据损坏,数据丢失。因为这些文件系统设计时假设只有一个操作系统在直接控制硬件,它们无法感知网络另一端还有另一个系统也在操作同一份元数据。

4.2 解决方案:集群文件系统

解决之道是使用集群文件系统。这类文件系统内置了分布式锁管理机制,允许多个节点同时安全地访问同一个块设备。常见的选择有:

  • OCFS2 (Oracle Cluster File System 2): 相对成熟,配置稍复杂,适合Oracle环境或需要稳定集群文件系统的场景。
  • GFS2 (Global File System 2): 通常需要配合Red Hat的集群套件使用。
  • GlusterFS / Ceph: 它们本身是分布式文件系统,架构上与iSCSI这种块存储共享不同,通常不建立在共享块设备之上。

对于我们的Tgt iSCSI环境,OCFS2是一个不错的起点。下面简述在两个客户端(ClientA和ClientB)上配置OCFS2的流程。

  1. 在所有客户端安装OCFS2工具

    sudo apt install ocfs2-tools -y
  2. 在一个客户端上格式化磁盘为OCFS2(只需要做一次):

    # 在ClientA上执行,假设iSCSI磁盘为/dev/sdc sudo mkfs.ocfs2 -N 2 -L "shared_data" /dev/sdc

    -N 2指定了最大集群节点数(即预计有多少个客户端会同时挂载),这里设为2。

  3. 配置集群节点信息: 在所有客户端上编辑/etc/ocfs2/cluster.conf,定义集群节点。两个节点的配置内容一致即可。

    sudo nano /etc/ocfs2/cluster.conf

    内容示例:

    cluster: node_count = 2 name = my_iscsi_cluster node: ip_port = 7777 ip_address = 192.168.1.101 number = 1 name = clientA cluster = my_iscsi_cluster node: ip_port = 7777 ip_address = 192.168.1.102 number = 2 name = clientB cluster = my_iscsi_cluster
  4. 加载OCFS2内核模块并启动集群服务

    sudo modprobe ocfs2 sudo service o2cb start sudo service ocfs2 start # 并配置为开机启动 sudo update-rc.d o2cb enable sudo update-rc.d ocfs2 enable
  5. 在所有客户端上挂载磁盘

    sudo mkdir /mnt/ocfs2_shared sudo mount -t ocfs2 /dev/sdc /mnt/ocfs2_shared

现在,ClientA和ClientB都可以安全地向/mnt/ocfs2_shared读写文件了。你可以在一台机器上创建文件,在另一台机器上立刻看到并修改它。

提示:生产环境部署OCFS2前,务必仔细阅读其文档,并充分测试。对于更高要求的环境,可以考虑使用基于分布式存储(如Ceph RBD)的方案,它提供了更强大的扩展性和可靠性。

4.3 替代思路:逻辑卷管理器(LVM)与多路径

在多客户端场景下,除了文件系统,存储管理本身也有讲究。一种更灵活的架构是:在Tgt服务器端,使用LVM(Logical Volume Manager)来管理物理磁盘,然后导出逻辑卷(LV)作为iSCSI LUN。这样做的好处是:

  • 灵活扩容:可以轻松扩展LV的大小,而客户端无需重新分区。
  • 快照功能:可以创建LV的快照,用于数据备份或测试。
  • 精简配置:可以创建大于实际物理空间的精简配置卷。

此外,对于要求高可用的客户端,可以配置iSCSI多路径(Multipathing)。即客户端通过多条网络路径(如两块网卡)连接到Target,当一条路径故障时,自动切换到另一条,同时还能实现负载均衡。这需要安装multipath-tools并进行相应配置。

5. 安全加固与性能调优

一个面向多客户端的存储系统,安全和性能不容忽视。

5.1 访问控制与CHAP认证

默认情况下,任何知道IP和IQN的发起端都可以连接你的Target。这显然不安全。Tgt支持使用CHAP(Challenge-Handshake Authentication Protocol)进行双向认证。

  • 配置Target端CHAP: 在Target配置文件中,为特定的Target启用CHAP。

    <target iqn.2024-05.local.ubuntu:tgt.datastore> backing-store /dev/vg_shared/lv_data lun 1 # 启用单向CHAP认证(Initiator向Target认证) incominguser alice secretpass123 # 启用双向CHAP认证(Mutual CHAP) # outgoinguser bob targetpass456 </target>

    修改配置后,记得sudo tgt-admin --update all

  • 配置Initiator端CHAP: 在发起端,需要将CHAP凭证添加到对应的节点记录中。

    sudo iscsiadm -m node --targetname iqn.2024-05.local.ubuntu:tgt.datastore --portal 192.168.1.100 --op update -n node.session.auth.authmethod -v CHAP sudo iscsiadm -m node --targetname iqn.2024-05.local.ubuntu:tgt.datastore --portal 192.168.1.100 --op update -n node.session.auth.username -v alice sudo iscsiadm -m node --targetname iqn.2024-05.local.ubuntu:tgt.datastore --portal 192.168.1.100 --op update -n node.session.auth.password -v secretpass123

5.2 网络与磁盘性能优化

iSCSI性能很大程度上取决于网络和磁盘I/O。以下是一些调优方向:

  • 专用网络: 如果条件允许,为iSCSI流量划分一个独立的VLAN或使用专用的物理网卡,避免与业务流量争抢带宽。
  • 巨型帧(Jumbo Frames): 在网络交换机、Target和Initiator的网卡上启用MTU 9000,可以显著降低CPU开销并提升大块数据传输效率。确保网络路径上所有设备都支持并配置一致。
  • 调整队列深度: 在发起端,可以尝试增加SCSI设备的队列深度以提升并发I/O能力。这可以通过udev规则或/sys/block/sdX/device/queue_depth文件来设置。
  • Target端缓存策略: 如前所述,write-cache选项需要权衡。在配有BBU(电池备份单元)的RAID卡或服务器上,启用写缓存通常是安全的,并能极大提升写性能。否则,在数据安全性和性能之间需要谨慎选择。

6. 监控、维护与故障排查

系统上线后,持续的监控和维护是保证其稳定运行的关键。

  • 监控Target状态: 定期使用sudo tgt-admin --show查看Target和会话状态。关注SESSION部分,可以看到哪些发起端已连接。
  • 查看系统日志: Tgt的日志通常输出到/var/log/syslog/var/log/messages。使用journalctl -u tgt可以查看服务的详细日志。
  • 发起端常用命令
    • sudo iscsiadm -m session -P 3: 显示当前所有iSCSI会话的详细信息,包括连接状态、传输统计等,是排查连接问题的利器。
    • sudo iscsiadm -m node: 列出所有已发现的节点。
  • 一个常见的连接问题: 如果发起端无法发现或登录目标,请按以下顺序检查:
    1. 网络是否通畅?ping <target_ip>
    2. 防火墙是否开放了3260端口?
    3. Target服务是否正在运行?sudo systemctl status tgt
    4. Target配置是否正确?IQN是否有拼写错误?
    5. 如果使用CHAP,用户名和密码是否匹配?

在最近一次为数据科学团队部署共享存储时,我们就遇到了因客户端网络MTU设置不一致导致的性能断续问题。使用iscsiadm -m session -P 3查看发现存在大量传输错误,最终通过统一配置巨型帧解决。这种基于块设备的共享存储,一旦调优得当,其稳定性和速度会给团队协作带来质的提升。

http://www.jsqmd.com/news/447302/

相关文章:

  • 向量量化(VQ)在语音处理中的应用:如何用Codebook提升语音识别准确率
  • PyQt5实战:用QComboBox打造动态下拉菜单(附QTdesigner.ui文件)
  • 用Python实战演示:二项分布如何随着样本量增大逼近正态分布(附完整代码)
  • EasyExcel实战:如何用滑动窗口思想优化10万+数据合并单元格性能?
  • 用C++实现激光炮遮挡算法:从数学建模到代码优化的完整过程
  • 用Echarts手把手教你绘制炫酷旭日图(附完整代码与避坑指南)
  • 滑模控制中的Hurwitz条件:为什么你的控制器总是不稳定?常见设计误区解析
  • Vue 3.0静态文件下载避坑指南:为什么你的Excel模板总是404?
  • 避坑指南:uniapp安卓隐私弹窗配置中的常见错误与解决方案
  • 从医疗到车联网:RM500Q模组的5种行业应用AT指令扩展方案
  • Spring全家桶版本选择指南:2023年最新Spring Boot/Cloud兼容性对照表(附Excel下载)
  • ACM论文标题太长导致重叠?5分钟教你修改acmart.cls文件搞定
  • 用Docker-Compose一键部署Hadoop集群(含数据持久化配置)
  • npm淘宝镜像失效?手把手教你更新registry.npmmirror.com的正确姿势
  • 手把手教你用Python实现无参考图像质量评估(附PIQE/BRISQUE/NIQE代码示例)
  • 从InRoads到OpenRoads:Bentley道路设计软件升级避坑指南(附新旧功能对比)
  • CATIA材料库批量导入全攻略:用Excel+MATLAB一键搞定(附避坑指南)
  • 用示波器抓包分析SPI和IIC时序:基于STM32CubeMX的通信调试技巧
  • EasyCode避坑指南:解决代码生成后Mapper.xml报错、依赖冲突等6个常见问题
  • SLF4J警告终结者:一招搞定‘multiple SLF4J providers‘的烦恼
  • Spring Boot 3.5.5 + Spring AI 1.0.1整合sglang模型避坑指南:解决HTTP 400的两种自定义配置
  • 避坑指南:XeLaTeX/BibTex混用导致文献引用失效?手把手教你多引擎协同工作流
  • Linux系统架构识别实战:从命令行到内核文件的5种方法(附常见误区解析)
  • MacBook Pro必备的10款小众神器:从音视频剪辑到代码开发全搞定
  • llama.cpp部署Hugginghub模型
  • FPGA图像处理实战:如何用FIFO实现3x3卷积窗口(附Verilog代码)
  • Overleaf新手必看:5分钟搞定会议论文LaTeX模板导入与配置
  • 思源笔记+Ollama:手把手教你搭建本地AI写作系统(含内网穿透教程)
  • Seaborn vs Matplotlib:绘制带误差带的曲线图对比指南(2023最新版)
  • rk3588升级Linux 6.1内核后声卡罢工?LT6911UXE录音修复实战记录