Linux 命令行配置 iSCSI target
坑边闲话: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 | 普通 iSCSI: 基于 TCP/IP 传统网络的 iSCSI |
1. 安装必要组件·
执行下列命令即可完成 target 所需组件的安装。
1 | sudo apt install targetcli-fb |
2. 配置 target·
2.1 术语概览·
target
: 连接目标,即 iSCSI 服务器initiator
: 连接发起人,即 iSCSI 客户端
2.2 配置具体的 target·
本节通过一个具体的案例展示如何配置 target.
配置 LIO 的 target 需要使用 targetcli
命令行工具,该工具可以支持
- 在
targetcli
提供的环境里交互式执行; - 也可以通过
targetcli
后缀指令的方式在 shell 中逐条执行。
本文以交互式方式展示。执行下列代码进入交互式环境。
1 | sudo targetcli |
随后按照注释分别执行各个步骤,完成后端存储存储创建、target 创建、门户监听、认证、ACL 鉴权等操作。
1 | # -------------------------------------------------------------------------------------- |
接下来详细解析每一步的具体含义。
2.2.1 准备后端存储·
使用 /backstores
路径(即命令)管理后端存储。后端存储一般指的是本地的某个块设备,比如
- 磁带机,
- ZFS 的某个 ZVol,
- LVM 的某个 LV,
- 本地的某个具体的 HDD, SSD 等。
只要该设备是块设备,即可通过 iSCSI 共享出去。前文已经有所提及,本处不再赘述。
targetcli
支持四种常见的块设备后端,具体解释如下:
block
- 使用系统中已经存在的块设备,性能好、直通底层块设备。
- 命令:
/backstores/block create name=myvol dev=/dev/sdb
fileio
- 使用一个普通的文件作为 LUN,性能一般,但是灵活。
- 命令:
/backstores/fileio create name=myfile file_or_dev=/var/iscsi/mydisk.img size=10G
pscsi
- 使用已有的 SCSI 设备(Pass-through SCSI),把现有的 SCSI 设备转发给 initiator,通常用于磁带库或光驱。设备必须支持并允许 SCSI 命令 pass-through.
- 命令:
/backstores/pscsi create name=psdev dev=/dev/sgX
ramdisk
:- 内存盘,一般是测试使用。在内存中创建一个虚拟设备,所有数据存在内存中,重启即丢失。。
- 命令:
/backstores/ramdisk create name=ram0 size=1G
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 (不可用): 路径已断开或有故障。
而 tpg(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 最终效果展示·
总结·
本文详细介绍了在 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、宿主机之后,吞吐性能有很大下降,由于缺乏控制变量的条件,所以暂且不做深入分析。