坑边闲话:iSCSI 块共享协议在数据中心里应用非常广泛,许多 NAS 玩家也仅仅只会在群晖、TrueNAS 等系统上使用 GUI 进行配置。其实在标准的通用 Linux 上配置 iSCSI server 非常简单,理解了原理之后,配置所需的实际步骤其实非常少。本文详细介绍如何在 Debian 12 系统上配置 iSCSI target.
iSCSI 服务端被称为 target,在 Linux 生态中有不同的 target 代码实现,本文推荐使用现代内核支持的 LIO(Linux-IO Target),这是官方主流方案,稳定、灵活、内核级支持。
常见 target 实现的特性如下表所示。
实现方式 |
服务名称 |
管理工具 |
备注 |
LIO (Linux-IO Target) |
内核模块,服务名 rtslib-fb-targetctl |
targetcli / targetcli-fb |
默认、内核集成、现代系统首选 |
TGT (SCSI Target Framework) |
tgt 服务 |
tgtadm , tgt-admin |
老牌项目,用户态,简单轻量,但不再积极维护 |
SCST |
scst 内核模块 + 用户空间管理工具 |
scstadmin |
高性能、支持更复杂的 IO 策略,但配置复杂 |
IET (iSCSI Enterprise Target) 已废弃 |
iscsitarget |
编辑 /etc/ietd.conf |
Debian 已弃用,不推荐使用 |
从功能深度、性能调优能力上来说,SCST 确实比 LIO 更强一些,但也更复杂、更偏向专业/高性能场景。然而 SCST 仅以内核模块形式提供,由于笔者的 ZFS 已经是内核模块形式,因此笔者不打算引入过多的存储内核模块。
有关 iSCSI, ISER (iSCSI Extensions for RDMA), SRP (SCSI RDMA Protocol) 客户端的区别,参加下图。
1 2 3 4 5 6 7 8
| 普通 iSCSI: 基于 TCP/IP 传统网络的 iSCSI App → SCSI → iSCSI → TCP/IP → NIC
iSER: 对 iSCSI 的网络部分用 RDMA 网络做了替换 App → SCSI → iSCSI → **RDMA** → RDMA NIC
SRP: 直接用 RDMA 网络传输 SCSI 指令 App → **SCSI over RDMA** → RDMA NIC
|
1. 安装必要组件·
执行下列命令即可完成 target 所需组件的安装。
1
| sudo apt install targetcli-fb
|
2. 配置 target·
2.1 术语概览·
target
: 连接目标,即 iSCSI 服务器
initiator
: 连接发起人,即 iSCSI 客户端
2.2 配置具体的 target·
配置 LIO 的 target 需要使用 targetcli
命令行工具,该工具可以支持
- 在
targetcli
提供的环境里交互式执行;
- 也可以通过
targetcli
后缀指令的方式在 shell 中逐条执行。
本文以交互式方式展示。执行下列代码进入交互式环境。
随后按照注释分别执行各个步骤,完成后端存储存储创建、target 创建、门户监听、认证、ACL 鉴权等操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
/backstores/block create name=dropbox dev=/dev/zvol/Samsung_990Pro_Stripe/dropbox
/iscsi create iqn.2019-08.cn.littlenewton:gtr7-debian
/iscsi/iqn.2019-08.cn.littlenewton:gtr7-debian/tpg1/luns create /backstores/block/dropbox
/iscsi/iqn.2019-08.cn.littlenewton:gtr7-debian/tpg1/portals create 0.0.0.0 3260
/iscsi/iqn.2019-08.cn.littlenewton:gtr7-debian/tpg1/acls create iqn.2019-08.cn.littlenewton:gtr7-win10
/iscsi/iqn.2025-07.com.example:dropbox/tpg1 set attribute authentication=0
/iscsi/iqn.2019-08.cn.littlenewton:gtr7-debian/tpg1/acls/iqn.2019-08.cn.littlenewton:gtr7-win10 create mapped_lun=0 tpg_lun=0
saveconfig
|
2.2.1 准备后端存储·
后端存储一般指的是本地的某个块设备,比如
- 磁带机
- ZFS 的某个 ZVol
- LVM 的某个 LV
- 本地的某个具体的 HDD, SSD 等
只要该设备是块设备,即可通过 iSCSI 共享出去。
然而,在 targetcli
的上下文中,backstore 是一个关联到某个具体块设备的独立抽象概念,它有自己的名字。
2.2.2 设置 iSCSI target·
我们先想象一个更复杂的、高可用的存储环境:
- 你有一台存储服务器,但它有两个控制器(Controller A 和 Controller B),以防其中一个坏掉。
- 每个控制器都有自己的网络端口。
- 客户端(Initiator)可以看到通往同一个 LUN(磁盘)的多条路径(Path),一条通过 Controller A,另一条通过 Controller B。
这时问题来了:客户端应该使用哪条路径?两条路径的性能和状态一样吗?
ALUA 就是用来解决这个问题的。 它允许存储目标器(target)告诉客户端(initiator)每一条路径的状态。常见的状态有:
- Active/Optimized (活动/优化): 这是首选路径。读写速度最快,延迟最低。
- Active/Unoptimized (活动/非优化): 这条路径也能用,但是性能较差(例如,数据需要通过控制器之间的内部链接转发)。它通常作为备用路径。
- Standby (备用): 这条路径当前不可用,但如果主路径失效,它可以被激活。
- Unavailable (不可用): 路径已断开或有故障。
而 Target Port Group (目标端口组) 就是实现这个机制的工具。 服务器将所有具有相同路径状态的目标端口(Portals)放到同一个组里。例如:
tg_pt_gp_A
(我们自己命名的组) 可能包含 Controller A 上的所有端口,状态为 Active/Optimized。
tg_pt_gp_B
可能包含 Controller B 上的所有端口,状态为 Active/Unoptimized。
当客户端连接时,它会查询这些组的状态,然后智能地选择最优的路径(Active/Optimized)来发送 I/O 请求,同时知道如果主路径失效,可以切换到次优路径(Active/Unoptimized)。
即使在本文描述的如此简单的单路径环境中:
- 只有一台服务器。
- 只有一个 iSCSI Target。
- 只有一个 TPG (tpg1)。
- 只有一个 Portal (0.0.0.0:3260)
LIO Target(Linux 的 iSCSI 内核模块)仍然使用 ALUA 框架来描述路径状态。
2.2.3 设置 iSCSI ACL·
ACL(Access Control List,访问控制列表)用于控制哪些 initiator(发起端)有权限访问指定的 target(目标端)。iSCSI 默认采用“白名单”策略:只有被明确列入 ACL 的 initiator 名称,才被允许连接到对应的 target. 若 ACL 为空,则代表拒绝所有 initiator 连接该 target(即默认拒绝)。为了增强安全性,通常需要结合 CHAP(Challenge-Handshake Authentication Protocol)认证机制共同使用。
需要注意的是,这里的 ACL 控制 并不涉及身份验证,仅仅是基于 Initiator IQN 的访问限制。这意味着安全性有限,因为 initiator 名称是可以在客户端随意伪造或修改的,因此依赖 ACL 并不能提供真正的安全隔离。建议在生产环境中始终搭配 ACL 和 CHAP 双重机制,以避免伪造 initiator 名称所带来的潜在风险。
2.2.4 最终效果展示·
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| sudo targetcli ls o- / ......................................................................................................................... [...] o- backstores .............................................................................................................. [...] | o- block .................................................................................................. [Storage Objects: 1] | | o- dropbox ........................................... [/dev/zvol/Samsung_990Pro_Stripe/dropbox (2.0TiB) write-thru activated] | | o- alua ................................................................................................... [ALUA Groups: 1] | | o- default_tg_pt_gp ....................................................................... [ALUA state: Active/optimized] | o- fileio ................................................................................................. [Storage Objects: 0] | o- pscsi .................................................................................................. [Storage Objects: 0] | o- ramdisk ................................................................................................ [Storage Objects: 0] o- iscsi ............................................................................................................ [Targets: 1] | o- iqn.2019-08.cn.littlenewton:gtr7-debian ........................................................................... [TPGs: 1] | o- tpg1 .................................................................................................. [gen-acls, no-auth] | o- acls .......................................................................................................... [ACLs: 1] | | o- iqn.2019-08.cn.littlenewton:gtr7-win10 ............................................................... [Mapped LUNs: 1] | | o- mapped_lun0 ............................................................................... [lun0 block/dropbox (rw)] | o- luns .......................................................................................................... [LUNs: 1] | | o- lun0 ..................................... [block/dropbox (/dev/zvol/Samsung_990Pro_Stripe/dropbox) (default_tg_pt_gp)] | o- portals .................................................................................................... [Portals: 1] | o- 0.0.0.0:3260 ..................................................................................................... [OK] o- loopback ......................................................................................................... [Targets: 0] o- vhost ............................................................................................................ [Targets: 0] o- xen-pvscsi ....................................................................................................... [Targets: 0]
|
本文详细介绍了在 Linux 上部署 Linux-IO 类型的 iSCSI target 的全过程。
由于服务器性能比较复杂而且不需要特别高的性能,因此本文忽略了 benchmark 展示部分。实际上,本文所使用的软硬件架构非常复杂,不属于常规操作。
- 宿主机:零刻 GTR7
- CPU & Mem: AMD 7840HS, 32GB DDR5 5600MHz SODIMM *2
- 硬盘:Samsung 990 Pro 4TB
- 宿主机系统 & 虚拟化方案:Windows 10 Pro, Hyper-V
- 虚拟机:Debian 12
- 虚拟机磁盘:使用 Hyper-V 物理磁盘,将 Samsung 990 Pro 4TB 映射给虚拟机使用。
在该场景下,Windows 10 宿主机通过 Hyper-V 网络连接虚拟机的 iSCSI targe,存储吞吐可以达到 1.1GB/s 以上,足以满足 Dropbox 网盘的文件存储需求。不过后来在升级了 ZFS、宿主机之后,吞吐性能有很大下降,由于缺乏控制变量的条件,所以暂且不做深入分析。