本文由 Codex 根据《iscsi使用》笔记辅助整理生成,并用 RFC 7143、Open-iSCSI、targetcli 与 Ubuntu 官方文档校正。命令以 Ubuntu Server 24.04 LTS 为例,用于演示标准流程,未在本文发布时的真实环境中执行验证

iSCSI 把 SCSI 命令、数据和状态封装进 iSCSI PDU,再通过 TCP/IP 传输。对客户端来说,远端 LUN 最终会表现为一块本地块设备,因此可以继续分区、创建文件系统、加入 LVM;也正因为它是块设备,选错盘执行 mkfswipefspvcreate 会直接破坏数据。

原理:网络上传输的是块 I/O

RFC 7143 将 iSCSI 定义为 SCSI 到 TCP 的映射:Initiator 发出 SCSI 命令,Target 返回数据、响应和状态。它不是 NFS 这类文件协议,不理解目录、文件或权限。

1
2
3
4
5
6
应用 / 文件系统 / LVM

SCSI 块 I/O

Initiator ── iSCSI/TCP ── Target ── Backstore
└─ /dev/vdc

关键对象如下:

对象 含义
Initiator 发起连接并使用块设备的客户端
Target 提供 SCSI 资源的服务端逻辑节点
Backstore Target 后端的真实存储,例如块设备、逻辑卷或文件
LUN Target 内逻辑单元的编号;一个 Target 可以提供多个 LUN
Portal Target 的监听地址,通常是 IP:TCP 端口;默认端口为 3260
TPG Target Portal Group,一组属于同一逻辑 SCSI Target Port 的 Portal 与策略
ACL 按 Initiator 名称控制其可以访问的 LUN
IQN iSCSI Qualified Name,用于标识 Initiator 或 Target,不是只标识客户端

IQN 常见格式为:

1
iqn.yyyy-mm.反写域名:自定义唯一名称

例如:

1
iqn.2026-09.com.example:storage.disk1

其中年月应是命名机构拥有该域名的时间。IQN 标识的是逻辑 iSCSI 节点,与某块网卡或 IP 地址无关;更换地址不应顺手更换 IQN。完整命名规则见 RFC 7143 第 4.2.7 节

实验架构与边界

本文沿用内部笔记的双机拓扑:

1
2
3
Target                                      Initiator
192.168.100.2 192.168.100.3
/dev/vdc ── LIO/targetcli ── TCP 3260 ── Open-iSCSI ── /dev/sdX

目标是将 192.168.100.2 上的 /dev/vdc 作为 LUN 0,只授权 192.168.100.3 使用。

开始前必须确认:

  • /dev/vdc 是专门用于实验的空闲盘,盘符、容量和序列号都已复核;
  • Target 本机没有挂载、没有加入 LVM,也没有其他程序使用 /dev/vdc
  • 同一个普通 ext4/xfs 文件系统不会被多台 Initiator 同时读写;多主机共享写入需要集群文件系统、锁与 fencing;
  • 生产环境已有数据时,先做备份和回滚方案,不照抄本文的格式化命令。

建议先做只读检查:

1
2
3
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS,SERIAL /dev/vdc
findmnt /dev/vdc
sudo wipefs -n /dev/vdc

操作:配置 Target

以下命令以 Ubuntu Server 24.04 LTS 为例,Target 与 Initiator 都使用具有 sudo 权限的普通用户操作。

安装 LIO 管理工具,并启用开机配置恢复服务:

1
2
3
sudo apt update
sudo apt install -y targetcli-fb
sudo systemctl enable target.service

先到 Initiator 读取真实名称:

1
2
3
4
sudo apt update
sudo apt install -y open-iscsi lsscsi netcat-openbsd
sudo systemctl enable --now iscsid.service
cat /etc/iscsi/initiatorname.iscsi

假设输出为:

1
InitiatorName=iqn.2026-09.com.example:client.initiator1

回到 Target 进入 targetcli

1
2
3
4
5
6
7
8
9
$ sudo targetcli
/> cd /backstores/block
/backstores/block> create name=disk dev=/dev/vdc
/backstores/block> cd /iscsi
/iscsi> create iqn.2026-09.com.example:storage.disk1
/iscsi> cd /iscsi/iqn.2026-09.com.example:storage.disk1/tpg1/luns
/iscsi/iqn.2026-09.com.example:storage.disk1/tpg1/luns> create /backstores/block/disk
/iscsi/iqn.2026-09.com.example:storage.disk1/tpg1/luns> cd /iscsi/iqn.2026-09.com.example:storage.disk1/tpg1/acls
/iscsi/iqn.2026-09.com.example:storage.disk1/tpg1/acls> create iqn.2026-09.com.example:client.initiator1

这里先建 LUN、后建 ACL,是为了让已有 LUN 只映射给明确的 Initiator。targetcli 默认启用 auto_add_mapped_luns,若在已有 ACL 后新增 LUN,可能自动映射到所有 ACL,带来意外授权风险。

检查 Portal:

1
/> ls /iscsi/iqn.2026-09.com.example:storage.disk1/tpg1/portals

若自动生成了 0.0.0.0:3260,它会监听所有地址。需要只监听存储网地址时,删除默认 Portal 后再创建明确地址:

1
2
/> /iscsi/iqn.2026-09.com.example:storage.disk1/tpg1/portals delete 0.0.0.0 3260
/> /iscsi/iqn.2026-09.com.example:storage.disk1/tpg1/portals create 192.168.100.2 3260

最后检查并显式保存配置:

1
2
3
/> ls /
/> saveconfig
/> exit

Ubuntu 中 saveconfig 默认写入 /etc/rtslib-fb-target/saveconfig.json,并由 target.service 在启动时恢复。不要只依赖“退出时可能自动保存”的默认行为,可用 sudo systemctl is-enabled target.service 确认已启用。

防火墙应只允许 Initiator 访问 Target 的 TCP 3260。如果 Ubuntu 已启用 UFW,可限制来源地址:

1
2
sudo ufw allow from 192.168.100.3 to 192.168.100.2 port 3260 proto tcp
sudo ufw status verbose

操作:发现、登录并使用 LUN

在 Initiator 上发现 Target:

1
2
sudo iscsiadm -m discoverydb -t sendtargets \
-p 192.168.100.2:3260 --discover

预期能看到 Portal、TPG Tag 和 Target IQN:

1
192.168.100.2:3260,1 iqn.2026-09.com.example:storage.disk1

发现只会创建 node 记录,不等于已经登录。继续建立会话:

1
2
3
sudo iscsiadm -m node \
-T iqn.2026-09.com.example:storage.disk1 \
-p 192.168.100.2:3260 --login

检查会话与设备映射:

1
2
3
4
sudo iscsiadm -m session -P 3
lsscsi
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS,SERIAL
ls -l /dev/disk/by-path/ | grep iscsi

不要假设新盘一定是 /dev/sda/dev/sdb/dev/sdX 会随发现顺序变化,应结合 Target IQN、LUN、容量和序列号确认,长期挂载使用文件系统 UUID。

可选:初始化一块确认无数据的新 LUN

⚠️ 下列 mkfs.ext4 会覆盖目标设备上的文件系统元数据。只有确认该 LUN 无需保留数据时才执行。

先从 /dev/disk/by-path/ 找到包含本实验 Target IQN 和 lun-0 的唯一链接,再解析真实设备:

1
2
3
ISCSI_DISK='/dev/disk/by-path/ip-192.168.100.2:3260-iscsi-iqn.2026-09.com.example:storage.disk1-lun-0'
readlink -f "$ISCSI_DISK"
lsblk -f "$ISCSI_DISK"

确认无误后才创建文件系统并挂载:

1
2
3
4
sudo mkfs.ext4 "$ISCSI_DISK"
sudo mkdir -p /mnt/iscsi
sudo mount "$ISCSI_DISK" /mnt/iscsi
findmnt /mnt/iscsi

持久化:重启后自动登录和挂载

Open-iSCSI 会将发现结果保存为 node 记录。将本节点设为自动登录:

1
2
3
4
5
6
7
8
9
10
11
sudo iscsiadm -m node \
-T iqn.2026-09.com.example:storage.disk1 \
-p 192.168.100.2:3260 \
--op update -n node.startup -v automatic

sudo iscsiadm -m node \
-T iqn.2026-09.com.example:storage.disk1 \
-p 192.168.100.2:3260 \
--op update -n node.conn[0].startup -v automatic

sudo systemctl enable open-iscsi.service iscsid.service

/etc/iscsi/iscsid.conf 中的默认值只影响之后发现的新节点,不会回写已有 node 记录,因此应直接用上面的 iscsiadm --op update。这是 Open-iSCSI 官方 README 明确说明的行为。

取得文件系统 UUID:

1
sudo blkid "$ISCSI_DISK"

再写入 /etc/fstab

1
UUID=<实际 UUID>  /mnt/iscsi  ext4  _netdev,nofail  0  0

_netdev 告诉系统这是依赖网络的文件系统;nofail 表示 Target 暂时不可达时不阻塞整机启动。修改后先在维护窗口验证:

1
2
3
sudo umount /mnt/iscsi
sudo mount -a
findmnt /mnt/iscsi

Ubuntu Server iSCSI Initiator 文档 给出了 open-iscsi 安装、服务启用、自动登录和 LUN 识别流程;_netdev 挂载说明参见 Open-iSCSI 官方 README

安全建议

ACL、CHAP 和加密解决的是不同问题:

  • ACL 按 Initiator IQN 授权,但 IQN 本身不是密码;
  • CHAP 用共享密钥认证对端,但 不加密业务数据
  • RFC 7143 指出,CHAP 在未加密链路上会受到离线字典攻击,应使用随机强密钥;
  • 需要机密性和抗窃听时,应在专用隔离存储网中部署,并使用 IPsec 等链路保护;
  • Portal 不要无必要监听 0.0.0.0,防火墙只放行所需 Initiator;
  • 不要在命令历史、博客或代码仓库中写真实 CHAP 密钥。

Ubuntu Initiator 的 CHAP 参数可查阅 Ubuntu Server iSCSI 文档;Target 的 TPG 和单 ACL 认证参数可查阅 targetcli-fb 手册

验收

一套最小验收应覆盖以下层次:

层次 检查命令 通过标准
网络 nc -vz 192.168.100.2 3260 TCP 3260 可达
发现 sudo iscsiadm -m node 能看到正确 IQN 和 Portal
会话 sudo iscsiadm -m session -P 3 会话为已登录,列出 LUN
SCSI lsscsilsblk 容量、LUN 与预期一致
文件系统 findmnt /mnt/iscsi 挂载源指向目标 LUN
读写 dd 或创建校验文件 写入、读取和校验一致;仅在测试盘执行
重启恢复 维护窗口重启后复查上述项目 自动登录和挂载成功

验收时不要只看 iscsiadm --login 返回成功;还要确认登录的是正确 Target、正确 LUN、正确容量,并完成文件系统层读写验证。

常见排障

现象 优先检查
Discovery 无结果 Target 是否监听正确 Portal;路由、防火墙和 TCP 3260 是否可达
Login denied / authorization failure ACL 中的 IQN 是否与 /etc/iscsi/initiatorname.iscsi 完全一致;CHAP 两端配置是否一致
登录成功但没有磁盘 iscsiadm -m session -P 3 是否出现 LUN;Target 是否已映射 LUN;执行 iscsiadm -m session --rescan 后查看 dmesg -T
重启后没有自动登录 node 记录的 node.startupnode.conn[0].startup 是否为 automaticiscsidopen-iscsi 服务是否启用
会话恢复但挂载失败 /etc/fstab 是否使用正确 UUID 与 _netdev;网络是否在挂载前就绪
Logout 报设备忙 仍有文件系统、LVM、multipath 或进程持有设备;先从上层依赖逐层释放
路径中断后 I/O 卡住 先恢复存储网络并确认 Target 状态,再做受控卸载;不要在 I/O 未收敛时强删 Target

常用日志与状态:

1
2
3
4
sudo journalctl -u iscsid -u open-iscsi --since '-30 min'
sudo dmesg -T | grep -Ei 'iscsi|scsi|blk|I/O error'
sudo iscsiadm -m node -o show
sudo iscsiadm -m session -P 3

正确退出与清理顺序

不要直接在 Target 上删除 LUN。正确顺序是先释放 Initiator 上层使用者,再断开会话,最后删除 Target 配置。

1. Initiator:停止 I/O 并卸载

1
2
3
4
sudo sync
findmnt /mnt/iscsi
sudo fuser -vm /mnt/iscsi
sudo umount /mnt/iscsi

如果配置过 /etc/fstab,先删除或注释对应行。取消自动登录:

1
2
3
4
sudo iscsiadm -m node \
-T iqn.2026-09.com.example:storage.disk1 \
-p 192.168.100.2:3260 \
--op update -n node.startup -v manual

2. Initiator:精确登出并删除 node 记录

1
2
3
4
5
6
7
sudo iscsiadm -m node \
-T iqn.2026-09.com.example:storage.disk1 \
-p 192.168.100.2:3260 --logout

sudo iscsiadm -m node \
-T iqn.2026-09.com.example:storage.disk1 \
-p 192.168.100.2:3260 --op delete

不要在有多个 iSCSI 盘时随意使用 --logoutall=all,它会影响无关会话。

3. Target:确认无会话后删除导出

1
2
3
4
5
6
$ sudo targetcli
/> sessions list
/> /iscsi delete iqn.2026-09.com.example:storage.disk1
/> /backstores/block delete disk
/> saveconfig
/> exit

删除 Target、ACL、LUN 或 Backstore 配置通常只是取消导出,不等于擦除 /dev/vdc 上的数据;但在仍有 I/O 时强制删除会造成错误甚至文件系统损坏。继续删除底层 LV、镜像文件,或对 /dev/vdc 执行 wipefsmkfs,才会进一步破坏或移除实际数据。

参考资料