open-iscsi 是一个实现 RFC3720 iSCSI 协议的高性能 initiator 程序。iSCSI 使得访问 SAN 上的存储不再只能依赖 Fibre Channel,也可以通过 TCP 协议和以太网络。在很多 Linux 平台都可以方便的下载到 open-iscsi 包。
有了它就可以在 Linux 上直接连接远端的 block device 了,就像使用本地 block device 一样方便。
目前是 open-iscsi 包含两个部分:内核部分和用户空间部分
实现了 scsi read/write 功能,包含 3 个内核模块 scsi_transport_iscsi.ko, libiscsi.ko and iscsi_tcp.ko,在安装了 open-iscsi 的 Linux 上,可以查看到。
- $ sudo lsmod | grep iscsi - i iscsi_trgt 101664 5 iscsi_tcp 17580 0 libiscsi_tcp 21554 1 iscsi_tcp libiscsi 48004 3 libiscsi_tcp,
- iscsi_tcp,
- ib_iser scsi_transport_iscsi 77478 4 iscsi_tcp,
- ib_iser,
- libiscsi scsi_mod 191405 12 sg,
- scsi_transport_spi,
- scsi_dh,
- scsi_transport_iscsi,
- libata,
- mptspi,
- sd_mod,
- sr_mod,
- iscsi_tcp,
- mptscsih,
- ib_iser,
- libiscsi
主要完成如:配置管理,iSCSI target 的自动发现,登录、登出,错误处理和连接保持等。用户通过 iscsiadm 来管理 initiator 端与 target 端的连接。下面是管理工具 iscsiadm 的使用帮助。
- $sudoiscsiadm --help
- iscsiadm -m discoverydb [ -hV ] [ -d debug_level ] [-P printlevel] [ -t type -p ip:port -I ifaceN ... [ -Dl ] ] | [ [ -p ip:port -t type] [ -o operation ] [ -n name ] [ -v value ] [ -lD ] ]
- iscsiadm -m discovery [ -hV ] [ -d debug_level ] [-P printlevel] [ -t type -p ip:port -I ifaceN ... [ -l ] ] | [ [ -p ip:port ] [ -l | -D ] ]
- iscsiadm -m node [ -hV ] [ -d debug_level ] [ -P printlevel ] [ -L all,manual,automatic ] [ -U all,manual,automatic ] [ -S ] [ [ -T targetname -p ip:port -I ifaceN ] [ -l | -u | -R | -s] ] [ [ -o operation ] [ -n name ] [ -v value ] ]
- iscsiadm -m session [ -hV ] [ -d debug_level ] [ -P printlevel] [ -r sessionid | sysfsdir [ -R | -u | -s ] [ -o operation ] [ -n name ] [ -v value ] ]
- iscsiadm -m iface [ -hV ] [ -d debug_level ] [ -P printlevel ] [ -I ifacename | -H hostno|MAC ] [ [ -o operation ] [ -n name ] [ -v value ] ] [ -Cping[ -a ip ] [ -b packetsize ] [ -c count ] [ -i interval ] ]
- iscsiadm -m fw [ -d debug_level ] [ -l ]
- iscsiadm -m host [ -P printlevel ] [ -H hostno|MAC ] [ [ -C chap [ -o operation ] [ -v chap_tbl_idx ] ] | [ -C flashnode [ -o operation ] [ -A portal_type ] [ -x flashnode_idx ] [ -n name ] [ -v value ] ] ]
- iscsiadm -k priority
- sudoapt-getinstallopen-iscsi
- yum installiscsi-initiator-utils
安装完成后,比较重要的配置文件有两个: /etc/iscsi/iscsid.conf 以及 /etc/iscsi/initiatorname.iscsi
这个文件包含 host 的 initiator IQN,在很多企业级存储上都要用到这个,否则无法访问存储上的资源。
- $sudo cat/etc/iscsi/initiatorname.iscsi
- ## 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.1993-08.org.debian:01:2b22ec4c44d
这个文件包含 open-iscsi 的配置,下面会提到一些个人经常遇到的一些设置
- # To request that the iscsi initd scripts startup a session set to "automatic".
- # node.startup = automatic
- #
- # To manually startup the session set to "manual". The default is manual.
- node.startup = manual
如果 node.start = automatic,所有 login 过的 session 在下次重启的时候都会再次被 login。
- node.conn[0].timeo.login_timeout = 15
上面是单次登录的超时时间
- node.session.initial_login_retry_max = 8
登录失败后的最大重试次数
当然 / etc/iscsi/iscsid.conf 的配置绝大多数都可以通过 iscsiadm --mode node --op <command> 来对特定的 node/session 针对性的配置,后面会提到。
iscsiadm 使用基本分 3 个步骤:发现 (discovery),登录 (login),扫描 (rescan)
在使用 iscsiadm 的过程中有两个名词要注意下
portal 和 IQN 可以唯一确定一个 storage 的 target。
discovery 只要知道 storage 上的 target portal 就可以发现所有暴露的 portal 和 iqn。
$ sudo iscsiadm -m discovery -t sendtargets -p 192.168.183.129192.168.183.129:3260,1 iqn.2001-04.com.example:storage.lun2192.168.183.129:3260,1 iqn.2001-04.com.example:storage.lun1
上面发现 绿色 的就是 storage 上的所有 target portals, 红色 就是 IQN
在第一步中发现的 target 都会保存在本地的数据库中,可以用 sudo iscsiadm -m node 看到。
如果你要登录第一步中所有的 portal,可以直接用下面的命令一键登录:
- $sudoiscsiadm -m node --login
- Logging into [iface: default, target: iqn.2001-04.com.example:storage.lun2, portal:192.168.183.129,3260] (multiple)
- Logging into [iface: default, target: iqn.2001-04.com.example:storage.lun1, portal:192.168.183.129,3260] (multiple)
- Login to [iface: default, target: iqn.2001-04.com.example:storage.lun2, portal:192.168.183.129,3260] successful.
- Login to [iface: default, target: iqn.2001-04.com.example:storage.lun1, portal:192.168.183.129,3260] successful.
- $sudoiscsiadm -m node -T iqn.2001-04.com.example:storage.lun1 -p192.168.183.129:3260--login
- Logging into [iface: default, target: iqn.2001-04.com.example:storage.lun1, portal:192.168.183.129,3260] (multiple)
- Login to [iface: default, target: iqn.2001-04.com.example:storage.lun1, portal:192.168.183.129,3260] successful.
- $sudoiscsiadm -m session
- tcp: [3]192.168.183.129:3260,1iqn.2001-04.com.example:storage.lun1 (non-flash)
注意,在默认配置下,登录的 session,重启是不会再次登录的,如果要想登录的 session 自动登录,一种方式是,前面提到的设置 node.start = automatic
- $sudoiscsiadm -m node -T iqn.2001-04.com.example:storage.lun2 -p192.168.183.129:3260--op update -nnode.startup-vautomatic
- # 查看session的设置
- $sudoiscsiadm -m node -T iqn.2001-04.com.example:storage.lun2 -p192.168.183.129:3260|grep node.startup
- node.startup = automatic
一旦登录成功,所有分配给当前主机的 LUN 都可以看到了,但有时,新分配的 LUN,LUN 的信息发生变化后,主要不能立即看到,这样就需要 rescan 了 --rescan 。
- $sudoiscsiadm -m session --rescan
- Rescanning session [sid: 3, target: iqn.2001-04.com.example:storage.lun1, portal:192.168.183.129,3260]也可以
$ sudo iscsiadm -m node --rescan Rescanning session [sid: 3, target: iqn.2001-04.com.example:storage.lun1, portal: 192.168.183.129,3260]
可以通过 session id
- $sudoiscsiadm -m session
- tcp: [3]192.168.183.129:3260,1iqn.2001-04.com.example:storage.lun1 (non-flash)
- tcp: [4]192.168.183.129:3260,1iqn.2001-04.com.example:storage.lun2 (non-flash)
上面的 [3], [4] 都是 session id,直接使用即可:
- $sudoiscsiadm -m session --sid3--rescan
- Rescanning session [sid: 3, target: iqn.2001-04.com.example:storage.lun1, portal:192.168.183.129,3260]
试了下,不可以通过 target 和 iqn 登录,不知道是 bug 还是参数问题:
- $sudoiscsiadm -m node -T iqn.2001-04.com.example:storage.lun1 -p192.168.183.129:3260--rescan
- Rescanning session [sid: 3, target: iqn.2001-04.com.example:storage.lun1, portal:192.168.183.129,3260]iscsiadm: invalid error code 65280
- iscsiadm: Could not execute operation on all sessions: (null)
- #ls-l /dev/disk/by-path/
- total 0
- lrwxrwxrwx 1root root9Jun3 03:01ip-192.168.183.129:3260-iscsi-iqn.2001-04.com.example:storage.lun1-lun-1-> ../../sdc
- lrwxrwxrwx 1root root9Jun3 03:08ip-192.168.183.129:3260-iscsi-iqn.2001-04.com.example:storage.lun2-lun-2-> ../../sdd
- lrwxrwxrwx 1root root9Jun3 01:26pci-0000:00:10.0-scsi-0:0:0:0-> ../../sda
- lrwxrwxrwx 1root root10Jun3 01:26pci-0000:00:10.0-scsi-0:0:0:0-part1 -> ../../sda1
- lrwxrwxrwx 1root root10Jun3 01:26pci-0000:00:10.0-scsi-0:0:0:0-part2 -> ../../sda2
- lrwxrwxrwx 1root root10Jun3 01:26pci-0000:00:10.0-scsi-0:0:0:0-part5 -> ../../sda5
- lrwxrwxrwx 1root root9Jun3 01:26pci-0000:00:10.0-scsi-0:0:1:0-> ../../sdb
可以看到,在我的测试中,连接的两个 target 分别暴露了一个 LUN 给 host,lun1 和 lun2,对应的 host 上的两个 device 是 /dev/sdc /dev/sdd
- $sudofdisk -l
- Disk /dev/sdb:20GiB,21474836480bytes,41943040 sectors
- Units: sectors of 1*512=512 bytes
- Sector size (logical/physical):512bytes /512 bytes
- I/O size (minimum/optimal):512bytes /512 bytes
- Disk /dev/sda:40GiB,42949672960bytes,83886080 sectors
- Units: sectors of 1*512=512 bytes
- Sector size (logical/physical):512bytes /512 bytes
- I/O size (minimum/optimal):512bytes /512 bytes
- Disklabel type: dos
- Disk identifier: 0xcaf795e0
- Device Boot Start End Sectors Size Id Type
- /dev/sda1 *2048 80383999 80381952 38.3G83 Linux
- /dev/sda280386046 83884031 3497986 1.7G5 Extended
- /dev/sda580386048 83884031 3497984 1.7G82Linux swap / Solaris
- Disk /dev/sdc:1GiB,1073741824bytes,2097152 sectors
- Units: sectors of 1*512=512 bytes
- Sector size (logical/physical):512bytes /512 bytes
- I/O size (minimum/optimal):512bytes /512 bytes
- Disk /dev/mapper/149455400000000003592265eae69d00a6e8560cd2833744e:1GiB,1073741824bytes,2097152 sectors
- Units: sectors of 1*512=512 bytes
- Sector size (logical/physical):512bytes /512 bytes
- I/O size (minimum/optimal):512bytes /512 bytes
- Disk /dev/sdd:1GiB,1073741824bytes,2097152 sectors
- Units: sectors of 1*512=512 bytes
- Sector size (logical/physical):512bytes /512 bytes
- I/O size (minimum/optimal):512bytes /512 bytes
- Disk /dev/mapper/149455400000000005277c9d1f32625c43968336de76fc205:1GiB,1073741824bytes,2097152 sectors
- Units: sectors of 1*512=512 bytes
- Sector size (logical/physical):512bytes /512 bytes
- I/O size (minimum/optimal):512bytes /512bytes
NOTE: /dev/mapper/*** 是我安装了 multipath-tools 后生成的 device
如果 disk 很多的话,还是推荐第一个方法来确定 disk 路径,否则搞错了,数据丢失可是来不及哭爹喊娘的哦:)
总的来说,iscsi 的使用还是比较方便,就是一旦长期不用,后面使用的话,一般都只能复制,粘贴了,枯燥不说,还容易出错。
由于我日常的工作中经常跟 open-iscsi、multipath、fc 等等打交道,经常觉得:要发现一个新的 device 步骤非常繁琐。
于是我自己决定开发一个方便的 tool/API,简化跟 stoage 打交道的步骤。项目地址是:https://github.com/peter-wangxu/goock
欢迎大家使用和提供宝贵的意见和建议。
参考资料
https://github.com/open-iscsi/open-iscsi
https://tools.ietf.org/html/rfc7143
来源: http://www.cnblogs.com/sting2me/p/6937578.html