什么是SAN

SAN(Storage Area Network)区域储存网络,简单来说,它提供的是一种共享存储空间,类似于samba,NFS。但它们主要有以下不同的地方:

samba和NFS在服务器端已经提供了文件系统,客户端挂载后直接可以使用;而SAN只负责提供存储设备,不负责文件系统的创建,使用什么文件系统由客户端自己决定(通过格式化创建)。

samba共享的目录挂载后表现为一个网络存储设备;而SAN设备连接后完全表现为一个本地磁盘。

它们的传输协议不同,SAN一般通过fibre channel传输,而其他两个则通过网络协议传输,通常是tcp协议。

SAN成本可能会比较高,虽然也有廉价的解决方案

SAN并不依赖于特定环境,无论是windows还是linux操作系统,都可以提供SAN服务和使用SAN设备。

Target和Initiator

target和initiator是SAN的两个核心概念。target是一个或多个存储设备(LUN)的集合,由服务器端创建;而initiator则是客户端使用的工具,用来连接服务器端创建的target

在centos7中安装iscsi环境

在centos7下面,target和initiator分别对应两个软件包,它们分别是scsi-target-utils和iscsi-initiator-utils。

安装scsi-target-utils

通过下面的命令安装scsi-target-utils

[centos7-server ~]# yum install -y scsi-target-utils

安装完毕之后,我们查看一下它提供了什么配置文件:

[centos7-server ~]# rpm -qc scsi-target-utils

/etc/sysconfig/tgtd

/etc/tgt/conf.d/sample.conf

/etc/tgt/targets.conf

/etc/tgt/tgtd.conf

可以看到,它提供的配置文件不多,在上面的文件中,我们主要关注/etc/tgt/targets.conf文件。

创建用于共享的设备

iscsi可以使用多种设备向外提供服务器:

用dd命令生成的文件

一个磁盘分区或者整个磁盘

LVM(logical volume manager)

下面我们分别创建两种类型的设备来共享出去,这两种类型是dd虚拟出来的磁盘和lvm创建的磁盘。

通过dd命令创建虚拟磁盘

下面我们使用dd命令创建一个500m的虚拟磁盘

[centos7-server ~]# dd if=/dev/zero of=/srv/iscsi/sharedisk.img bs=1M count=500

500+0 records in

500+0 records out

524288000 bytes (524 MB) copied, 0.828686 s, 633 MB/s

[centos7-server ~]# ls -lh /srv/iscsi/sharedisk.img

-rw-r--r--. 1 root root 500M Apr 14 17:28 /srv/iscsi/sharedisk.img

/srv/iscsi目录如果不存在的话请先创建出来。

创建lvm设备

lvm设备不难创建,只是比dd命令多几个步骤

首先通过gdisk命令(如果磁盘是mbr,则可以使用fdisk)分一个2g的分区:

[centos7-server ~]# gdisk /dev/sda

GPT fdisk (gdisk) version 0.8.6

Partition table scan:

MBR: protective

BSD: not present

APM: not present

GPT: present

Found valid GPT with protective MBR; using GPT.

Command (? for help): n

Partition number (6-128, default 6):

First sector (34-209715166, default = 146800640) or {+-}size{KMGTP}:

Last sector (146800640-209715166, default = 209715166) or {+-}size{KMGTP}: +2G

Current type is 'Linux filesystem'

Hex code or GUID (L to show codes, Enter = 8300): 8e00

Changed type of partition to 'Linux LVM'

Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING

PARTITIONS!!

Do you want to proceed? (Y/N): y

OK; writing new GUID partition table (GPT) to /dev/sda.

Warning: The kernel is still using the old partition table.

The new table will be used at the next reboot.

The operation has completed successfully.

[centos7-server ~]# partprobe -s

/dev/sda: gpt partitions 1 2 3 4 5 6

分区准备好就可以开始创建lv

[centos7-server ~]# pvcreate /dev/sda6

Physical volume "/dev/sda6" successfully created.

[centos7-server ~]# vgcreate vgdemo /dev/sda6

Volume group "vgdemo" successfully created

[centos7-server ~]# lvcreate -l 100%FREE vgdemo -n lvstarget

Logical volume "lvstarget" created.

整个过程不需要几分钟,一切准备就绪,下面正式开始配置target。

编写targets.conf

targets.conf在/etc/tgt目录下面,从它的文件名可以看出,文件里面必定是target的配置集合,target的配置语言类似于xml。

target和iqn

iqn全称ISCSI Qualified Name,它是target的唯一标识符,客户端正是通过这个标识符找到target的。IQN有一个命名标准,例如:iqn.2001-04.com.example:storage1。

当然这只是一个标准,尊不遵守还是由我们自己决定。上面的IQN分为4个部分,分别是:1,以iqn开头。2,年月组成的时间。3,域名的倒转写法。4,用冒号分隔的名称,这个名称有意义更好。这四个部分以点和最后的冒号连接。

一个最简单的target配置

要target可以完全工作,不需要太多的设置,例如:

default-driver iscsi

backing-store /srv/iscsi/sharedisk.img

backing-store /dev/vgdemo/lvstarget

除去targets.conf中的注释和空行,就只有上面的内容,其中target标签包裹的内容完全是我们自己添加上去的。

虽然配置文件就是这么多,但是一个重要的东西必须要注意,那就是selinux,由于selinux的限制,sharedisk.img文件现在是不能被tgtd访问的,必须把他的文件类型设置为tgtd_var_lib_t。

[centos7-server ~]# chcon -Rv -t tgtd_var_lib_t /srv/iscsi/sharedisk.img

changing security context of ‘/srv/iscsi/sharedisk.img’

[centos7-server ~]# ls -lZ /srv/iscsi/sharedisk.img

-rw-r--r--. root root unconfined_u:object_r:tgtd_var_lib_t:s0 /srv/iscsi/sharedisk.img

到这里为止,就可以重启tgtd服务,之后客户端就可以通过initiator连接这个target了。

targets.conf常用指令

targets.conf文件中的最高层标签是,它包含一系列配置指令,其中最常用的有:

backing-store:定义一个逻辑单元(LUN),这个LUN通常是一个普通文件或者块设备

direct-store:作用和backing-store相同,不同的是它的LUN类型通常是物理设备,例如整个硬盘

initiator-address:限制可以连接target的客户端地址范围

incominguser:限制可以连接target的客户端用户

限制客户端访问

处于安全考虑,我们可以只允许特定的ip地址或指定的用户才能连接target

backing-store /srv/iscsi/disk1.img

backing-store /dev/vgdemo/lvstarget

initiator-address 192.168.88.0/24 #只允许这个ip地址范围进行连接

incominguser testuser testpasswd #只允许这个用户访问

其中incominguser中定义的用户和/etc/passwd中的用户没有任何关系。

配置客户端

客户端的功能由iscsi-initiator-utils提供,它只有一个配置文件,就是/etc/iscsi/iscsid.conf。虽然它只提供了一个配置文件,但同时也提供了2个服务和一个主要命令:

iscsid:iscsi客户端守护进程,启动这个服务后iscsiadm命令才能正常工作

iscsi:自动登录target的程序,运行一次后退出

iscsiadm:客户端管理target的命令

启动服务

如上所述,客户端依赖iscsid和iscsi两个服务,因此必须先启动它们,还有设置它们开机自动启动

[centos7-server ~]# systemctl start iscsid

[centos7-server ~]# systemctl enable iscsid

Created symlink from /etc/systemd/system/multi-user.target.wants/iscsid.service to /usr/lib/systemd/system/iscsid.service.

[centos7-server ~]# systemctl start iscsi

[centos7-server ~]# systemctl enable iscsi

Created symlink from /etc/systemd/system/sysinit.target.wants/iscsi.service to /usr/lib/systemd/system/iscsi.service.

修改iscsid.conf配置文件

对iscsid.conf文件的修改不多,主要是添加账号验证:

# To set a CHAP username and password for initiator

# authentication by the target(s), uncomment the following lines:

node.session.auth.username = testuser

node.session.auth.password = testpasswd

这两个字段对应服务器的incominguser的用户和密码,如果服务器没有设置权限,我们甚至不需要修改iscsid.conf就可以使用iscsiadm命令连接target。

发现target

意思就是搜索服务器提供了什么target,它们的IQN是什么,如果你已经知道target的IQN,那么可以跳过这个步骤直接连接target。

[root@vmcentos7 ~]# iscsiadm -m discovery -t sendtargets -p 192.168.88.133

192.168.88.133:3260,1 iqn.2018-04.cn.sharpcode:testdisk

如果成功,返回服务器的target列表。

参数说明:

-m: mode,即模式,常用的有node和discovery

-t:通常都是使用sendtargets

-p:portal,指服务器的ip地址和端口,如果没有设置端口,使用默认的3260

从linux登录target(连接target)

通过上一个步骤取得target的名称之后,就可以进行target的连接,target连接之后,就可以对target进行操作。

[root@vmcentos7 ~]# iscsiadm -m node -T iqn.2018-04.cn.sharpcode:testdisk --login

Logging in to [iface: default, target: iqn.2018-04.cn.sharpcode:testdisk, portal: 192.168.88.133,3260] (multiple)

Login to [iface: default, target: iqn.2018-04.cn.sharpcode:testdisk, portal: 192.168.88.133,3260] successful.

参数说明:

-T:指定target名称(IQN)

--login:登录到target(也可以使用-l,小写L)

登录成功可以使用lsblk命令查看:

root@vmcentos7 ~]# lsblk -S

NAME HCTL TYPE VENDOR MODEL REV TRAN

sda 10:0:0:1 disk IET VIRTUAL-DISK 0001 iscsi

sdb 10:0:0:2 disk IET VIRTUAL-DISK 0001 iscsi

sr0 0:0:0:0 rom QEMU QEMU DVD-ROM 1.5\. ata

会发现多了一个磁盘sdb,到这一步,我们就可以使用这个磁盘进行常规操作,例如分区,格式化。

从windows登录target

windows提供了一个方便的target连接工具,名称为ISCSI发起程序,win7之后的系统默认自带,xp可以从官方网站下载相关程序。

首先打开发起程序,然后切换到发现标签,点击发现门户:

在发现目标门户中输入服务器的ip地址,点击确定,成功后切换回目标标签,选择要连接的目标,然后点击连接,会出现连接到目标对话框:

如果服务器有访问控制,则选择高级按钮:

勾选启用CHAP登录,输入名称和目标机密,确定后回到之前的窗口,继续进行连接即可。不过,windows下面的发起程序要求目标机密长度必须大于等于12为字符,否则会提示错误。

targetcli

targetcli是centos7之后用来替换scsi-target-utils的一个交互shell程序,因此,如果你的系统是centos7,那么推荐使用targetcli(scsi-target-utils依然可用)。

scsi-target-utils是通过配置文件来设置target的,targetcli虽然也有配置文件,但基本上我们都不需要手动去修改,而是通过targetcli的shell去完成这些工作。

它们之间还有不同的是:targetcli不需要重启守护进程,创建好后就马上生效,除非手动编辑了配置文件/etc/target/saveconfig.json。

安装targetcli

yum install -y targetcli

targetcli是通过目录树的方式管理iscsi对象的,安装好后可以启动targetcli

[centos7-server ~]# targetcli

targetcli shell version 2.1.fb46

Copyright 2011-2013 by Datera, Inc and others.

For help on commands, type 'help'.

/> ls

o- / ......................................................................................................................... [...]

o- backstores .............................................................................................................. [...]

| o- block .................................................................................................. [Storage Objects: 0]

| o- fileio ................................................................................................. [Storage Objects: 0]

| o- pscsi .................................................................................................. [Storage Objects: 0]

| o- ramdisk ................................................................................................ [Storage Objects: 0]

o- iscsi ............................................................................................................ [Targets: 0]

o- loopback

目录树的根是/,下面包含几个子目录:

backstores:存储对象,按照不同类型划分不同的子目录:

block:保存的是块设备

fileio:保存的是文件类型设备,类似于前面使用dd命令创建的文件

pscsi:本地实体scsi设备

ramdisk:内存磁盘

iscsi:保存target的相关属性,例如acl,portal等

创建target

和之前的一样,target的创建也是分几步走。

通过非交互的方式使用targetcli

第一步:要先创建虚拟磁盘,不过这次我们不用dd命令,targetcli包含了这个功能

[centos7-server ~]# targetcli backstores/fileio/ create testio /srv/iscsi/testio.img 1G

Created fileio testio with size 1073741824

第二步:创建target

targetcli在创建target的时候会默认创建一个TPG,并把该target放置于这个TPG下面,一个TPG可以包含多个target,TPG的作用类似分组,就是把多个需要使用相同设置(例如权限)的target集中管理

[centos7-server ~]# targetcli iscsi/ create iqn.2018-04.cn.sharpcode:target1

Created target iqn.2018-04.cn.sharpcode:target1.

Created TPG 1.

Global pref auto_add_default_portal=true

Created default portal listening on all IPs (0.0.0.0), port 3260.

这一步创建的target还不能被使用,因为它还没有被输出(export)

第三步:输出target

输出target的意思是利用第一步创建的虚拟磁盘来建立一个LUN

[centos7-server ~]# targetcli iscsi/iqn.2018-04.cn.sharpcode:target1/tpg1/luns/ create /backstores/fileio/testio

Created LUN 0.

第四步:关闭ACL验证

targetcli默认开启ACL,如果不需要这个功能,通过下面的方式关闭

[centos7-server ~]# targetcli iscsi/iqn.2018-04.cn.sharpcode:target1/tpg1 set attribute generate_node_acls=1

Parameter generate_node_acls is now '1'.

注意这里1是关闭acl验证,而0是开启验证;可以理解generate_node_acls为是否忽略acl验证。

第五步:查看最后结果

[centos7-server ~]# targetcli ls

o- / ......................................................................................................................... [...]

o- backstores .............................................................................................................. [...]

| o- block .................................................................................................. [Storage Objects: 0]

| o- fileio ................................................................................................. [Storage Objects: 1]

| | o- testio .............................................................. [/srv/iscsi/testio.img (1.0GiB) write-back activated]

| | o- alua ................................................................................................... [ALUA Groups: 1]

| | o- default_tg_pt_gp ....................................................................... [ALUA state: Active/optimized]

| o- pscsi .................................................................................................. [Storage Objects: 0]

| o- ramdisk ................................................................................................ [Storage Objects: 0]

o- iscsi ............................................................................................................ [Targets: 1]

| o- iqn.2018-04.cn.sharpcode:target1 .................................................................................. [TPGs: 1]

| o- tpg1 ............................................................................................... [gen-acls, no-auth]

| o- acls .......................................................................................................... [ACLs: 0]

| o- luns .......................................................................................................... [LUNs: 1]

| | o- lun0 ....................................................... [fileio/testio (/srv/iscsi/testio.img) (default_tg_pt_gp)]

| o- portals .................................................................................................... [Portals: 1]

| o- 0.0.0.0:3260 ..................................................................................................... [OK]

o- loopback ......................................................................................................... [Targets: 0]

到这一步位置,就可以通过客户端连接这个target。

第六步:服务器开机自动启动target服务

target服务通过targetctl恢复target的配置文件,即/etc/target/saveconfig.json文件。

[centos7-server ~]# systemctl enable target

Created symlink from /etc/systemd/system/multi-user.target.wants/target.service to /usr/lib/systemd/system/target.service.

通过交互shell创建target

通过交互方式使用targetcli可以获得更好的操作体验,因为交互方式可以使用两次tab来获得自动提示。除此之外,交互式和非交互式的使用方法并无不同的地方

交互创建target的完整例子:

[centos7-server ~]# targetcli #进入交互式shell
targetcli shell version 2.1.fb46
Copyright 2011-2013 by Datera, Inc and others.
For help on commands, type 'help'.
/> ls #查看节点信息
o- / ......................................................................................... [...]
o- backstores .............................................................................. [...]
| o- block .................................................................. [Storage Objects: 0]
| o- fileio ................................................................. [Storage Objects: 0]
| o- pscsi .................................................................. [Storage Objects: 0]
| o- ramdisk ................................................................ [Storage Objects: 0]
o- iscsi ............................................................................ [Targets: 0]
o- loopback ......................................................................... [Targets: 0]
/> backstores/fileio create disk1 /srv/iscsi/disk1.img 1G #创建虚拟磁盘
Created fileio disk1 with size 1073741824
/> iscsi/ create iqn.2018-04.cn.sharpcode:target1 #创建target
Created target iqn.2018-04.cn.sharpcode:target1.
Created TPG 1.
Global pref auto_add_default_portal=true
Created default portal listening on all IPs (0.0.0.0), port 3260.
/> ls #再次查看节点信息
o- / ......................................................................................... [...]
o- backstores .............................................................................. [...]
| o- block .................................................................. [Storage Objects: 0]
| o- fileio ................................................................. [Storage Objects: 1]
| | o- disk1 .............................. [/srv/iscsi/disk1.img (1.0GiB) write-back deactivated]
| | o- alua ................................................................... [ALUA Groups: 1]
| | o- default_tg_pt_gp ....................................... [ALUA state: Active/optimized]
| o- pscsi .................................................................. [Storage Objects: 0]
| o- ramdisk ................................................................ [Storage Objects: 0]
o- iscsi ............................................................................ [Targets: 1]
| o- iqn.2018-04.cn.sharpcode:target1 .................................................. [TPGs: 1]
| o- tpg1 ............................................................... [no-gen-acls, no-auth]
| o- acls .......................................................................... [ACLs: 0]
| o- luns .......................................................................... [LUNs: 0]
| o- portals .................................................................... [Portals: 1]
| o- 0.0.0.0:3260 ..................................................................... [OK]
o- loopback ......................................................................... [Targets: 0]
/> cd iscsi/iqn.2018-04.cn.sharpcode:target1/tpg1/luns #进入luns目录
/iscsi/iqn.20...et1/tpg1/luns> create #按两次tab获得命令提示
/backstores/fileio/disk1 [centos7-server anaconda-ks.cfg
initial-setup-ks.cfg add_mapped_luns= lun=
storage_object=
/iscsi/iqn.20...et1/tpg1/luns> create /backstores/fileio/disk1 #输出target
Created LUN 0.
/iscsi/iqn.20...et1/tpg1/luns> ls
o- luns .................................................................................. [LUNs: 1]
o- lun0 ................................. [fileio/disk1 (/srv/iscsi/disk1.img) (default_tg_pt_gp)]
/iscsi/iqn.20...et1/tpg1/luns> cd / #进入根节点
/> ls #查看节点信息
o- / ......................................................................................... [...]
o- backstores .............................................................................. [...]
| o- block .................................................................. [Storage Objects: 0]
| o- fileio ................................................................. [Storage Objects: 1]
| | o- disk1 ................................ [/srv/iscsi/disk1.img (1.0GiB) write-back activated]
| | o- alua ................................................................... [ALUA Groups: 1]
| | o- default_tg_pt_gp ....................................... [ALUA state: Active/optimized]
| o- pscsi .................................................................. [Storage Objects: 0]
| o- ramdisk ................................................................ [Storage Objects: 0]
o- iscsi ............................................................................ [Targets: 1]
| o- iqn.2018-04.cn.sharpcode:target1 .................................................. [TPGs: 1]
| o- tpg1 ............................................................... [no-gen-acls, no-auth]
| o- acls .......................................................................... [ACLs: 0]
| o- luns .......................................................................... [LUNs: 1]
| | o- lun0 ......................... [fileio/disk1 (/srv/iscsi/disk1.img) (default_tg_pt_gp)]
| o- portals .................................................................... [Portals: 1]
| o- 0.0.0.0:3260 ..................................................................... [OK]
o- loopback ......................................................................... [Targets: 0]
/> iscsi/iqn.2018-04.cn.sharpcode:target1/tpg1/ set #两次tab获得命令提示
attribute auth global parameter group=
/> iscsi/iqn.2018-04.cn.sharpcode:target1/tpg1/ set attribute #两次tab获得命令提示
authentication= cache_dynamic_acls= default_cmdsn_depth=
default_erl= demo_mode_discovery= demo_mode_write_protect=
generate_node_acls= login_timeout= netif_timeout=
prod_mode_write_protect= t10_pi= tpg_enabled_sendtargets=
/> iscsi/iqn.2018-04.cn.sharpcode:target1/tpg1/ set attribute generate_node_acls=1 #关闭acl
Parameter generate_node_acls is now '1'.
/

>