SAN存储的概念与基于iSCSI的操作实战
前面我们介绍了NAS存储和NFS协议,知道网络文件系统可以将远端(存储系统)的文件系统映射到主机端,并在主机端的目录树中形成一个子目录树。如下图是网络文件系统映射的示意图,在Linux操作系统中,这种映射关系的建立是通过mount(挂载)命令完成的。本文我们继续存储技术的另外一个领域SAN存储相关技术的介绍。
不同于NAS将文件系统从存储端映射到主机端的技术,SAN技术是将存储资源从存储端映射到主机端,并在主机端呈现为一个硬盘的技术(如下图所示)。在存储端的存储资源可以是一个硬盘、RAID甚至是一个文件。当然,为了提供数据的可靠性,存储端通常有非常复杂的实现,我们后续会详细介绍。
SAN存储是一种基于客户端-服务端架构的系统,其中客户端在SAN中称为启动器,服务端在SAN称为目标器。SAN存储有很多种,比如FC-SAN和IP-SAN等,其区别是底层的传输(Transport)协议不同。其中IP-SAN是我们本文要介绍的内容,IP-SAN运行的协议就是iSCSI协议。iSCSI协议是通过TCP/IP协议承载SCSI协议的一种SAN存储协议。iSCSI协议与TCP和SCSI协议的关系如下图所示。
要想访问存储资源,启动器和目标器之间必须建立连接(connection),对于iSCSI来说,这个连接其实就是一个TCP连接。连接两端分别称为启动器入口(portal)和目标器入口,上述入口可以是HBA卡或者网卡。对于SAN存储来说,入口是门户,所有命令请求都要经过入口。
在iSCSI中,无论是运行启动器的Linux客户端还是存储系统都称为iSCSI节点(iSCSI Node)。为了区分不同的节点,每个节点都有一个名称,称为iSCSI名称(iSCSI Name)。其中启动器的名称称为iSCSI 启动器名称(Initiator Name),目标器的名称称为iSCSI目标器名称(Target Name)。无论是启动器名称还是目标器名称都符合一定的规范,我们在后面具体操作的时候会看到。
照例,我们具体操作一下,看看如何在客户端映射一个硬盘。在进行具体操作之前,我们重点介绍一下目标器软件相关的内容。目前有很多开源的目标器软件,比如SCST、LIO、TGT和IET(iSCSI Enterprise Target)等。其中前两者可以支持多种协议,比如FC-SAN和IP-SAN等,而后两者只支持IP-SAN。
目前用的最多的是SCST和LIO,而且LIO已经集成到Linux内核的源码目录树中了。因此,安装和使用起来都比较简单。LIO的整体架构如下图所示,LIO分为网络模块、存储模块和通用目标器引擎三个核心组件。其中网络模块是前端模块, 负责收发来自启动器的请求,网络模块采用插件架构,可以支持iSCSI、FCP、iSER等协议。存储模块属于后端模块,用于数据的持久化。存储模块也是基于模块化设计,可以支持普通文件、块设备或者其它一些设备。我们可以开发自己的插件来支持自己的设备类型。
接下来我们基于Ubuntu 20.04介绍一下如何搭建一个IP-SAN存储。我们搭建的IP-SAN很简单,只有一个客户端(启动器)和一个服务端(目标器)。如果大家没有足够的硬件,大家可以基于虚拟机来模拟操作。
在进行具体配置之前,我们最好将机器的IP地址配置为静态IP地址,后续操作会方便一些。否则,每次重启机器后IP都有可能发生变化。在Ubuntu 20.04中,静态IP地址的配置比较简单,只需要将/etc/netplan/01-netcfg.yaml文件的内容修改为如下内容即可。
network:
version: 2
renderer: networkd
ethernets:
enp0s9:
dhcp4: no
addresses:
- 192.168.2.200/24
gateway4: 192.168.2.110
nameservers:
addresses: [8.8.8.8, 1.1.1.1]
上述配置中enp0s9是网卡的名称,不用厂商的网卡名称可能不同,这一点需要注意。我们可以通过如下命令查看我们的网卡名称。
ip addr
如下是作者虚拟机的网卡信息。完成上述配置文件的修改后可以通过sudo netplan apply命令是配置生效。
虽然LIO的源代码已经在内核树中,但是我们需要一个命令行工具来进行配置。因此,我们首先安装一下LIO的管理工具,在Ubuntu环境需要执行如下命令进行安装。
apt -y install targetcli-fb
安装完成后,通过targetcli命令可以进入交互模式进行配置。Targetcli采用目录树的方式进行配置管理。当我们进入交互模式后,可以通过ls命令查看一级目录的名称如下。其中backstores对应着架构图中的存储模块,可以支持块、文件和内存等方式的存储资源。本文通过文件来模拟一个存储资源。
其他一级目录则对应着不同类型的前端,比如我们将要实操的iSCSI则是在目录iscsi中进行。vhost是与虚拟机相关的前端,loopback则是为了方便二次开发的前端模块。本文以iscsi模块为例进行介绍。
首先我们创建一个文件类型的存储资源,这个存储资源在启动器端会被映射为一个硬盘,创建文件资源的命令如下所示(需要先切换到/backstores/fileio目录下):
create lun01 /mnt/test/lun01.bin 2G
这条命令有3个参数,分别是资源名称、文件路径和大小。其中文件的路径要求目录必须存在,而文件则会被自动创建。创建成功后可以看到在目录fileio下面会多出一些内容,具体如下所示。
我们知道iSCSI的存储资源是挂载目标器下面的。为了能够让启动器访问存储资源,我们接下来需要创建一个目标器。首先切换到/iscsi目录,创建目标器的命令如下所示。
create iqn.2023-12.sunnyzhang.srv:test.target01
执行上述命令后,可以查看一下iscsi目录的内容,具体如下所示。可以看出,在iscsi目录下多出很多内容,而且成层级结构。其中最上层是目标器的名称,也就是我们上述命令的参数。目标器的名称有一定的规范,大家创建时需要注意一下。
在目标器的名称下面还有acls、luns和portals等信息。其中acls是权限相关的配置,他用来配置允许访问该目标器的启动器的信息。Luns则是后端资源相关的配置,我们需要将上一步创建的资源在这里建立与目标器的关联。另外,我们可以创建多个目标器,大家可以自己试试。
创建成功目标器后我们就可以进行相关配置了。首先建立目标器与存储资源的映射关系,切换到目标器的luns目录下,执行如下命令:
create /backstores/fileio/lun01
成功后可以通过ls命令查看一下效果。
可以看到,执行上述命令后目标的luns下面有了lun相关的信息。接下来我们需要配置访问权限相关的信息,切换到acls目录下,执行如下命令可以将允许访问的启动器添加到acl中。
create iqn.2023-12.sunny.clt:node01.initiator01
添加完启动器的名称后可以看到acls中新增的启动器相关的信息。启动器名称也有相关的规则,大家在命名的时候需要注意。
至此,我们已经完成了目标器端的所有配置。最后,我们可以在根目录通过ls命令看一下整体的配置信息。可以看到配置信息分为两个主要部分,也就是后端存储资源和前端协议。
完成目标前端的配置后,我们可以通过另外一台虚拟机验证一下。接下来是配置一下启动器端的信息,首先需要修改一下启动器的名称。打开文件/etc/iscsi/initiatorname.iscsi,将其中的启动器名称改为我们在目标器配置中acls中的名称,修改后的内容如下:
## DO NOT EDIT OR REMOVE THIS FILE!
## If you remove this file, the iSCSI daemon will not start.
## If you change the InitiatorName, existing access control lists
## may reject this initiator. The InitiatorName must be unique
## for each iSCSI initiator. Do NOT duplicate iSCSI InitiatorNames.
InitiatorName=iqn.2023-12.sunny.clt:node01.initiator01
完成上述配置后,重启open-iscsi服务就可以连接目标器了。首先需要发现目标器,具体命令如下所示:
iscsiadm -m discovery -t sendtargets -p 192.168.2.201
执行上述命令输出如下。可以看到我们这里有两个目标器,其中第一个目标器是我们配置的目标器。
完成上述操作后就可以登录该目标器了,具体执行的命令如下。这里面需要注意的是targetname必须是我们上面创建的目标器名称。
iscsiadm --mode node --targetname iqn.2023-12.sunnyzhang.srv:test.target01 --login
回车后可以看到登录成功的信息,具体如下图所示。
我们可以通过fdisk命令来查看一下硬盘列表,可以看到sdi是新增加的硬盘。
前面我们只是介绍了启动器访问目标器资源的最简单的方式,实际生产环境要复杂一些,其主要原因是保证可用性。SAN源于企业级架构,在设计之初就保证了可用性。为了保证可用性,主机到存储系统之间的链路被设计成冗余的。这种冗余设计可以保证在某个链路故障的情况下仍然通过其他健康链路访问存储资源。基于多链路映射的硬盘将会变得比较复杂,如下图是基于2条链路建立的映射关系。可以看到通过两个独立的链路会将存储端的一个存储资源(LUN)映射到主机端后会变成两个硬盘,经过多路径软件后两个硬盘会聚合成一个硬盘。
多路径软件在高可用方面发挥着非常重要的作用,当然也是需要存储端来配合的。多路径软件有两个核心的功能,一个是将存储端相同的存储资源聚合为同一个硬盘,第二个功能是依照策略实现IO的转发。具体策略比如最简单的轮询策略、最小队列深度和最小延时等。
在IP-SAN中(iSCSI),将启动器与目标器之间的连接状态称为一个会话(Session),会话可以包含一个或者多个连接。为了区分会话中的不同的连接,每个连接都有一个连接ID(Connection ID),简称CID。在后续的文章中我们将继续深入iSCSI的相关内容,看看如何配置一个冗余链路的SAN存储。
在配置目标器的时候,大家如果删除存储资源的时候可能会遇到如下错误。这是因为targetcli有个bug,大家可以参考https://github.com/open-iscsi/rtslib-fb/pull/183/files?w=1自行修改。