学习一项技术最好的方法就是实际操练一把,但是一般人很难接触到SAN存储。主要是SAN存储一般是非常专业的存储系统,通常比较大型的企业才会使用。而且一般也是用于关键业务,所以一般人是很难接触到SAN存储的。
如下图是EMC公司中端存储Unity的一个GUI界面。左侧是导航栏,可以看出功能还是比较丰富的。主要是因为Unity其实不仅仅是一个SAN存储,而是融合SAN和NAS的统一存储系统。
前文说了,存储系统虽然功能丰富,但是我们一般人是接触不到的。即使一个低配置的Unity都要大几十万,所以也不可能自己买一个这样的存储系统来学习。那么如果想学习存储技术怎么办呢?
图片
得益于开源社区,我们可以借助一些开源项目来学习存储相关的技术。如下图是TrueNAS的一个GUI,可以看出其界面布局和基本功能与Unity有很多相似的地方。TrueNAS是一个免费的存储系统软件,我们可以在网上下载其安装镜像,并将其安装在虚拟机当中。TrueNAS基于FreeBSD操作系统,其存储功能基于ZFS文件系统实现。TrueNAS发源于FreeNAS,最早实现了NAS功能,现在不仅仅NAS,还可以支持SAN。也就是说,其实TrueNAS目前是一个统一存储系统了。
图片
TrueNAS的存储功能基于ZFS文件系统实现,ZFS是一个功能非常强大的文件系统。他不仅仅是一个文件系统,他能对多个硬盘实现池化管理,而且可以在池上创建逻辑卷。同时,他支持快照等高级功能。如图所示Storage是存储管理相关的功能,在这里我们可以基于硬盘创建一个存储池,并且在存储池的基础上创建逻辑卷。
图片
有了逻辑卷就相当于有了存储资源,然后我们就可以将存储资源导出,客户端通过网络就可以访问我们的存储资源了。在GUI的导航栏,Sharing目录是协议相关的配置功能,通过这里的配置可以将存储资源导出。我们可以看到这里既包含SAN相关的协议(如iSCSI),也包含NAS相关的协议(如AFP和NFS等)。
图片
可以说TrueNAS功能是非常强大的,但是我们并不打算深入介绍他,主要是这个系统基于FreeBSD实现,使用不太普遍,不便于后续深入学习。为了方便大家后续学习,我们这里不再继续介绍TrueNAS,而是以Linux操作系统及其下的软件为例进行介绍。
在Linux下有很多开源的软件,完全可以组建一个类似的功能。如果想构建一个IP-SAN环境,主要的软件是启动器软件和目标器软件。本节我们介绍一下如何基于Linux的开源软件构建一个IP-SAN存储系统。
IP-SAN基于以太网构建,所以从拓扑上来说至少应该包含两台计算机,一个充当存储系统的角色,其上运行目标器软件;另外一个充当计算节点,其上运行启动器软件,具体如下图所示。当然,这两台计算机也是可以合并为一台的。
图片
Linux环境下开源的目标器软件很多,比较有名的如LIO、SCST和TGT等。本文就以TGT为例进行介绍,其原因在于TGT是一个用户态的软件,门槛比较低,方便我们进一步的学习。大家可以自行从github下载TGT的源代码并进行编译(不需要安装),本文不再赘述。
作者这里代码在/root/tgt目录中。同时我们需要用一个100MB文件来模拟存储端的一个逻辑卷,具体生成文件的方法如下:
dd if=/dev/zero of=./lun bs=1M count=100
完成资源的准备后,我们首先需要将tgt程序运行起来,运行起来也比较简单,执行编译完成的程序即可。
./usr/tgtd
软件启动起来后,我们就可以进行目标器端的配置了。主要分为三步,分别是创建目标器、创建LUN和关联目标器与LUN。
1) 创建目标器,具体命令如下
./usr/tgtadm --lld iscsi --op new --mode target --tid 1 -T iqn.1996-05.com.redhat:target.zhang
上述命令的有些选项意义还是比较明确的。这里需要说的的是tid是目标器ID(target ID),T是目标器名称。
2) 创建LUN,具体命令如下
./usr/tgtadm --lld iscsi --op new --mode logicalunit --tid 1 --lun 1 -b /root/tgt/lun
想目标器添加LUN。这里是想我们前面创建的目标器中添加一个LUN,LUN ID是1,具体存储数据的单元是一个普通文件/root/tgt/lun。
3)绑定启动器地址,这个本身相当于权限管理,定义允许访问该目标器的IP地址。为了简单,我们这里允许所有的IP访问该目标器,具体命令如下:
./usr/tgtadm --lld iscsi --mode target --op bind --tid 1 -I ALL
完成上述配置后,启动器端就可以访问了。其实启动器可以是Windows操作系统上的软件,也可以是Linux上软件。以Windows上的软件为例,在启动器软件中输入目标器的IP地址,然后点击“快速连接”就可以建立与目标器的连接了。
图片
完成连接后,我们就可以在磁盘管理里面发现系统多出一块硬盘。打开“磁盘管理”的方法是“Windows” + X。此时可以看到一个菜单,其中某一项为“磁盘管理”。
图片
如下图所示为“磁盘管理”的管理界面。从界面上可以看到多出一块100MB的硬盘。这个硬盘其实就是目标器端我们创建的那个文件。从这里来看,我们看不出这块硬盘与本地硬盘有任何差异。
图片
这个硬盘虽然可以在“磁盘管理”里面看到,但是在“我的电脑”里面并看不到。需要我们做一些基本的操作才可以。如下图所示,右击左侧的文字可以弹出一个菜单,我们可以点击“初始化磁盘”对该硬盘进行初始化。
图片
初始化完成后可以基于该硬盘创建一个卷,这样才能在“我的电脑”看到该硬盘,并可以进行访问。
图片
在Linux操作系统下面需要命令行的工具完成相同的功能。这两行命令的作用是发现目标器,登录到目标器。
iscsiadm -m discovery -t sendtargets -p 192.168.2.194:3260
iscsiadm -m node –T iqn.1996-05.com.redhat:target.zhang -p 192.168.2.194 -l
登录成功后可以看到多出一个100MB的硬盘。我们就可以直接使用这个硬盘了。与Windows环境不同,这里不需要对硬盘做初始化的操作。
图片
经过上述配置后,实际上实现了将服务端的一个文件映射到客户端变成了一个硬盘,具体可以通过下图说明说明。
图片
对于IP-SAN来说,我们集中需要学习的自然是iSCSI协议。有了这个环境,学习iSCSI协议就相对简单和直观了。如果没有这个环境,我们可以通过阅读RFC来学习iSCSI协议,这种方式过于抽象和单调。有了这个环境,我们就可以通过WireShark来抓包。如下图是作者抓的登录过程的数据包,可以看到在该过程中涉及的CDB。
图片
我们再举一个具体的例子,比如我们在Linux直接通过dd命令将tgt中的Makefile文件拷贝到硬盘当中。如下是这个Makefile的文件的内容,执行如下命令可以实现数据拷贝。
dd if=./Makefile of=/dev/sdb
图片
在执行dd命令之前我们需要启动WireShark来捕获数据包。如下是我们捕获到的数据包的内容,可以看到数据包中的内容与文件内容的关系。当然,iSCSI命令本身是比较复杂的,我们后续会对每一个命令和tgt的源代码进行解析,让大家对iSCSI有一个比较深入的理解,这里的理解包括命令、体系结构和代码实现等多个层面。
图片