iSCSI(Internet Small Computer System Interface) 是一种基于 IP 网络的存储协议,允许客户端(Initiator)通过网络访问远程服务器(Target)的块设备(如磁盘、LUN)。
简单的讲,iSCSI协议是用来共享块存储设备的,即直接共享硬盘。在讲iSCSI之前,我们先了解一下,文件写入的存储层级结构,以及常见的网络存储的几种共享形式。对于我们理解几种网络存储会有一定的帮助
文件存储的层级结构
这是文件、文件系统、磁盘分区、硬盘几者的关系。
文件系统:对于系统、软件及管理来讲,我们对于文件的创建、打开、写入、读取、删除(posix协议)等操作,并非直接操作的硬盘,而是文件系统,即,文件是文件系统中的概念,而不是硬盘的,这个很重要。文件系统需要挂载到系统的某一个目录下,才能被使用。
分区:将硬盘在逻辑上划分为多个不同的区域,在机械硬盘时代,分区是有实际意义的,靠近磁头的读写更快,这也是windows的C盘为什么始终是用户可见的第一个分区。在SSD时代,分区基本上只用来作为不同用途的文件隔离。所以,可有可没有。
硬盘:这就是我们最常见的块设备
通过以上分层结构,我们也就明白了,为什么硬盘需要进行格式化之后才能写入文件,格式化的操作实际上就是创建文件系统。这就是为什么Linux系统中,格式化的命令为mkfs了。
网络存储共享形式
根据上述的文件操作的分层架构,不难看出,当我们需要共享文件的时候,实际上就可以有多种方式了:
文件共享:直接共享文件,比如常见的FTP、HTTP的文件上传下载,还有云计算领域的对象存储都是直接共享文件
文件系统共享:将本地的一个文件系统(通常是一个目录)共享,在客户端使用的时候,就只需要进行挂载(mount),最常见的NFS,还有公有云提供的其他网络文件系统等
块设备共享:直接将一个块设备(通常就是硬盘)共享出去,在客户端使用的时候,必须在该共享块设备上创建文件系统(mkfs)、并挂载(mount)之后才可以进行文件读写。这个最常见的产品就是云计算领域的分布式块存储了,如阿里云的OBS,AWS的EBS等
从这个结构上可以看到,不管是本地存储还是网络存储,块存储之上是文件系统,文件系统之上才是文件,这个层级结构是不会变化的。
iSCSI-块存储共享
今天我们要讲的iSCSI实际上就是块存储共享领域的一种常用协议,用于替换Fibre Channel(FC)存储网络
iSCSI的核心组件
- iSCSI Target:存储服务器,服务端。对外提供存储共享服务,也就是我们常说的存储池
- iSCSI Initiator:客户端,挂载服务端共享的存储到本地
iSCSI是如何工作的
iSCSI是工作在TCP/IP协议之上的,客户端封装SCSI指令到TCP协议中,经网络传输到服务端,服务端解封装获取SCSI指令,完成对本地的磁盘进行操作,并将数据返回。
整个过程经过iSCSI的封装,会让客户端操作本地磁盘一样,使用远端的网络块存储。
-
SCSI指令:是计算机与存储设备之间通信的标准协议,如常见的READ,WRITE指令
-
iSCSI的TCP端口:默认3260端口
iSCSI环境搭建
服务端 | 客户端 |
---|---|
192.168.10.26 | 192.168.10.29 |
RockyLinux9.4/RHEL 9.4 | RockyLinux9.4/RHEL 9.4 |
关闭selinux,关闭防火墙 |
配置Target端
保证target端有未被使用的硬盘,实验环境使用的vmware虚拟机,在虚拟机配置中,新增硬盘即可。
[root@rockylinux9 ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 19G 0 part
├─rocky-root 253:0 0 17G 0 lvm /
└─rocky-swap 253:1 0 2G 0 lvm
sdb 8:16 0 8G 0 disk
安装环境依赖
[root@rockylinux9 ~]# dnf install iscsi-initiator-utils targetcli
配置target
[root@rockylinux9 ~]# targetcli # 进入到交互模式,targetcli的交互模式有点类似于linux的文件系统层级结构
/> ls # 使用ls命令查看菜单结构
o- / ..... [...] # 顶级目录
o- backstores ........................... [...] # 后端存储,需要要共享的块设备或分区需要添加到此处
| o- block ............... [Storage Objects: 0] # 块存储,backstores子目录
| o- fileio .............. [Storage Objects: 0] # 文件存储镜像img根据一个事先准备的文件提供存储功能
| o- pscsi ............... [Storage Objects: 0] # 真实物理scsi设备,不推荐使用
| o- ramdisk ............. [Storage Objects: 0] # 内存存储
o- iscsi ......................... [Targets: 0]
o- loopback ...................... [Targets: 0]
# 将需要共享的块设备添加到共享目录
/> /backstores/block create sharesdb dev=/dev/sdb
# 创建ISCSI Target,共享是从target出去的,其实就是启动了TCP的服务,启动之后可以netstat看到3260的listen
# 这里的IQN,可以简单的理解为服务名称,标准的格式为:
# iqn.YYYY-MM.domain:identifier domain多为反写形式
/> /iscsi create iqn.2025-06.com.nebula:iscsi-server-01
# 默认会监听在0.0.0.0:3260端口,如果为了安全,可以修改监听地址
/> cd /iscsi/iqn.2025-06.com.nebula:iscsi-server-01/tpg1/portals
/iscsi/iqn.20.../tpg1/portals> delete 0.0.0.0 3260
/iscsi/iqn.20.../tpg1/portals> create 192.168.10.26 3260 # 监听到特定IP
# 将target绑定到后端存储,完成共享
/> /iscsi/iqn.2025-06.com.nebula:iscsi-server-01/tpg1/luns create /backstores/block/sharesdb
# 到这一步,实际上我们的块设备的共享已经完成,接下来我们需要配置客户端来进行挂载,当然正常是会提示认证失败的,因为我们还没有配置acl
# 这一条的意思,是允许iqn.2025-06.com.nebula.client01这台主机能够挂载
# 注意iqn.2025-06.com.nebula.client01这个客户端的iqn一般都是随机生成的,所以需要在客户端这边进行修改,请查看后端客户端配置
/> /iscsi/iqn.2025-06.com.nebula:iscsi-server-01/tpg1/acls create iqn.2025-06.com.nebula.client01
# 配置target属性,通常可以不用配置
/iscsi/iqn.20...yigeek:target> cd tpg1/ # 设置共享存储组的属性
/iscsi/iqn.20...k:target/tpg1> set attribute authentication=0 demo_mode_write_protect=0 generate_node_acls=1 cache_dynamic_acls=1
Parameter demo_mode_write_protect is now '0'.
Parameter authentication is now '1'.
Parameter generate_node_acls is now '1'.
Parameter cache_dynamic_acls is now '1'.
/> exit
Configuration saved to /etc/target/saveconfig.json
关闭防火墙或开放防火墙端口
[root@rockylinux9 ~]# systemctl stop firewalld && systemctl disable firewalld
# 或开放端口
[root@rockylinux9 ~]# firewall-cmd --add-port=3260/tcp --permanent
[root@rockylinux9 ~]# firewall-cmd --reload
客户端配置
安装相关依赖
[root@rockylinux9 ~]# dnf install iscsi-initiator-utils -y
[root@rockylinux9 ~]# systemctl start iscsid && systemctl enable iscsid
发现共享块设备
[root@rockylinux9 ~]# iscsiadm -m discovery -t st -p 192.168.10.26
192.168.10.26:3260,1 iqn.2025-06.com.nebula:iscsi-server-01
修改客户端的IQN设置
这是因为在Target端,我们需要手动配置acl,就必须事先知道客户端的IQN。所以,这里必须配置成Target端授权的IQN。或者配置为自动ACL授权。
# 修改文件 /etc/iscsi/initiatorname.iscsi
InitiatorName=iqn.2025-06.com.nebula.client01
systemctl retart iscsid
执行挂载(login)
[root@rockylinux9 ~]# iscsiadm -m node -T iqn.2025-06.com.nebula:iscsi-server-01 -p 192.168.10.26 --login
配置免ACL认证-修改Target属性
/> cd /iscsi/iqn.2025-06.com.nebula:iscsi-server-01/tpg1/
/iscsi/iqn.20...erver-01/tpg1> set attribute authentication=0 demo_mode_write_protect=0 generate_node_acls=1 cache_dynamic_acls=1
# authentication=0: 禁用认证(无需 CHAP 用户名/密码即可连接)1 表示启用双向 CHAP 认证。
# demo_mode_write_protect=0: 禁用写保护,允许客户端写入数据 1 表示只读模式(用于演示环境)。
# generate_node_acls=1: 自动为连接的 Initiator 生成 Node ACL(动态授权),这个属性就不需要手动添加acl了
# cache_dynamic_acls=1: 缓存动态 ACL(提高性能)避免频繁重新生成 ACL,但可能需手动清除缓存(/iscsi/.../tpg1/cache_dynamic_acls delete)
# immediate_data=1: 启用“立即数据传输”,减少延迟
配置完自动生成acl授权之后,我们删除之前添加的acl信息
/> cd iscsi/iqn.2025-06.com.nebula:iscsi-server-01/tpg1/acls
/iscsi/iqn.20...-01/tpg1/acls> delete iqn.2025-06.com.nebula.client01
/iscsi/iqn.20...-01/tpg1/acls> ls # 可以查看当前所有的acl认证信息
客户端重新挂载,就会发现可以挂在成功,不会有认证错误
[root@rockylinux9 ~]# iscsiadm -m node -T iqn.2025-06.com.nebula:iscsi-server-01 -p 192.168.10.26 --login
[root@rockylinux9 ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 19G 0 part
├─rocky-root 253:0 0 17G 0 lvm /
└─rocky-swap 253:1 0 2G 0 lvm
sdb 8:16 0 8G 0 disk
多块磁盘共享
在服务端共享多块块设备,可以是一块硬盘,也可以是一个分区,这里我们使用一个分区
# 添加共享后端
/> /backstores/block create sharesdc1 dev=/dev/sdc1
# 关联target
/> cd iscsi/iqn.2025-06.com.nebula:iscsi-server-01/tpg1/luns/
/iscsi/iqn.20...-01/tpg1/luns> create /backstores/block/sharesdc1
/iscsi/iqn.20...-01/tpg1/luns> ls
o- luns .................................... [LUNs: 2]
o- lun0 .................................. [block/sharesdb (/dev/sdb) (default_tg_pt_gp)]
o- lun1 .................................. [block/sharesdc1 (/dev/sdc1) (default_tg_pt_gp)]
客户端执行挂载
[root@rockylinux9 ~]# iscsiadm -m node -T iqn.2025-06.com.nebula:iscsi-server-01 -p 192.168.10.26 -l
当我们之前已经在此客户端主机上执行过login挂载了服务端共享的块设备之后,那此时再次执行login挂载之后,就会发现,新的sdc1是无法被挂载回来的
需要使用--rescan
重新发现共享的LUN,就会发现共享的两个块设备都已经被挂载到客户端。
[root@rockylinux9 ~]# iscsiadm -m node -T iqn.2025-06.com.nebula:iscsi-server-01 -p 192.168.10.26 -R
或者先进行登出,再挂载
[root@rockylinux9 ~]# iscsiadm -m node -T iqn.2025-06.com.nebula:iscsi-server-01 -p 192.168.10.26 -u # 登出
[root@rockylinux9 ~]# iscsiadm -m node -T iqn.2025-06.com.nebula:iscsi-server-01 -p 192.168.10.26 -l
常见问题
上述多个块设备关联在一个Target上的时候,客户端在login挂载的时候,要么全部挂载回来,要么全部卸载。无法单独指定挂载某一个共享的块设备。
解决方案
使用多个Target实现多块设备共享
Target配置
# 将sdc1从刚才的Target删除
/> cd iscsi/iqn.2025-06.com.nebula:iscsi-server-01/tpg1/luns/
/iscsi/iqn.20...-01/tpg1/luns> delete lun1
Deleted LUN 1.
/iscsi/iqn.20...-01/tpg1/luns> ls
o- luns ........................................... [LUNs: 1]
o- lun0 .... [block/sharesdb (/dev/sdb) (default_tg_pt_gp)]
# 创建新的taget
/> /iscsi create iqn.2025-06.com.nebula:iscsi-server-02
# 关联到后端存储
/> /iscsi/iqn.2025-06.com.nebula:iscsi-server-02/tpg1/luns create /backstores/block/sharesdc1
# 创建portal监听,在创建第二个target的时候,是不会默认创建portal地址的,需要手动创建
/> /iscsi/iqn.2025-06.com.nebula:iscsi-server-02/tpg1/portals create 192.168.10.26 3260
# 配置自动acl授权
/> cd iscsi/iqn.2025-06.com.nebula:iscsi-server-02/tpg1/
/iscsi/iqn.20...erver-02/tpg1> set attribute authentication=0 demo_mode_write_protect=0 generate_node_acls=1 cache_dynamic_acls=1
客户端挂载
[root@rockylinux9 ~]# iscsiadm -m discovery -t st -p 192.168.10.26
192.168.10.26:3260,1 iqn.2025-06.com.nebula:iscsi-server-01
192.168.10.26:3260,1 iqn.2025-06.com.nebula:iscsi-server-02
[root@rockylinux9 ~]# iscsiadm -m node -T iqn.2025-06.com.nebula:iscsi-server-02 -p 192.168.10.26 --login
[root@rockylinux9 ~]# iscsiadm -m node -T iqn.2025-06.com.nebula:iscsi-server-01 -p 192.168.10.26 --login
[root@rockylinux9 ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 19G 0 part
├─rocky-root 253:0 0 17G 0 lvm /
└─rocky-swap 253:1 0 2G 0 lvm
sdb 8:16 0 4G 0 disk
sdc 8:32 0 8G 0 disk
iSCSI块设备使用警告
- iSCSI共享的是裸的块设备,永远不要在多个客户端挂载同一个LUN共享设备,并执行格式化操作,那将是一场数据灾难;
- 要想实现iSCSI的多点挂载、多点写入,需要配合使用集群文件系统,默认xfs,ext4都只支持单点操作;
- 如果你应用场景中只提供文件共享、下载的操作,请在Target端配置只读属性:set attribute demo_mode_write_protect=1
