因为iscsitarget已停止维护且不兼容现代内核,而targetcli(或targetcli-fb)基于lio子系统,是当前事实标准;需正确配置emulate_pr、acl、cache_type等参数才能支持多客户端安全访问。

为什么不用 iscsitarget 而要选 targetcli
因为 iscsitarget(即 ietd)早已停止维护,Ubuntu 20.04+ 和 RHEL 8+ 默认不提供包,强行编译会遇到内核模块签名、CONFIG_TARGET_CORE 依赖等一堆报错。真正能稳定跑在现代内核上的只有基于 target_core_user 和 lio_target 的 targetcli(或其继任者 targetcli-fb)。它直接对接 Linux 内核的 LIO 子系统,是当前事实标准。
实操建议:
- Debian/Ubuntu:安装
targetcli-fb(apt install targetcli-fb),不是targetcli(已弃用) - RHEL/CentOS 8+:启用
highavailability仓库后装targetcli(实际是targetcli-fb的软链) - 确认内核支持:
lsmod | grep target应输出target_core_mod、iscsi_target_mod
如何用 targetcli 创建可被多客户端并发挂载的块设备
关键不在“创建”,而在“配置为支持并发访问”——默认配置下,LIO 对同一 backend LUN 启用的是 ALUA 模式,但未显式开启 emulate_pr 和 emulate_3pc 时,Windows 或某些旧版 Linux initiator 会拒绝连接,或挂载后出现 I/O 错误。
实操建议:
- 后端用文件模拟块设备时,务必用
oflag=direct创建(dd if=/dev/zero of=/srv/iscsi/disk1.img bs=1M count=10240 oflag=direct),避免 page cache 干扰 - 在
targetcli中设置 LUN 属性:/backstores/fileio/disk1 set attribute emulate_pr=1 emulate_3pc=1 - 启用
tpg1/luns/ create /backstores/fileio/disk1后,必须执行/iscsi/iqn.2024-01.com.example:storage/tpg1/acls/ create iqn.2024-01.com.client:web1,ACL 不配则所有 initiator 都连不上
怎样让多个客户端安全地读写同一块 LUN
Linux iSCSI 本身不提供分布式锁,所谓“多客户端读写同一块设备”只有两种可行路径:要么上层用集群文件系统(如 GFS2、OCFS2),要么只读 + 一个写入者。试图裸设备多写 = 文件系统崩溃。
实操建议:
- 若真需共享写入,必须在 initiator 端部署 GFS2:格式化前用
mkfs.gfs2 -p lock_dlm -t cluster1:disk1 -j 4 /dev/sdb,且所有节点运行corosync+pacemaker - 若只是做高可用存储后端(如给 KVM 虚机用),应配置 ALUA:在
tpg1/portals/下绑定多个 IP,并设set attribute generate_node_acls=1,再用lun enable开启多路径感知 - 禁用
cache_type:在backstore层执行set attribute cache_type=0,否则 ext4/xfs 元数据可能因 write-back 缓存不一致而损坏
为什么客户端发现不到 target 或登录后看不到 LUN
最常见原因是防火墙和 ACL 两级拦截。systemd-firewalld 默认放行 iscsi-target 服务名,但该 service 只开 3260/tcp,没开 3260/udp(用于 iSNS 发现),而多数发行版的 iscsiadm -m discovery 默认走 UDP。
实操建议:
- 临时调试先关防火墙:
systemctl stop firewalld(RHEL)或ufw disable(Ubuntu) - 检查 target 状态:
targetcli ls输出中,enabled必须为True,且acls下有对应 initiator IQN - 客户端执行
iscsiadm -m node -T <iqn> -p <ip>:3260 --login</ip></iqn>后,用lsblk查看是否出现新盘;若无,检查dmesg | tail是否有connection reset(通常是 ACL 拒绝)或no route to host(网络不通)
复杂点在于 LIO 的配置模型是树状嵌套,改错一个层级(比如在 portals 下删了 IP 绑定),整个 TPG 就不可达,且错误日志极不直观。别信文档里的“reload config”,targetcli 没 reload 命令,改完必须 saveconfig 并重启 target 服务。











