2021-05-12 14:32:11
Linux上設定使用iSCSI詳細說明
本文詳細介紹iSCSI相關的內容,以及在Linux上如何實現iSCSI。
第1章 iSCSI簡介
1.1 scsi和iscsi
傳統的SCSI技術是儲存裝置最基本的標準協定,但通常需要裝置互相靠近並用SCSI匯流排連線,因此受到物理環境的限制。
iSCSI(Internet Small Computer System Interface),顧名思義,iSCSI是網路上的SCSI,也就是通過網路連線的SCSI。它是由IBM公司研究開發用於實現在IP網路上執行SCSI協定的儲存技術,能夠讓SCSI介面與乙太網技術相結合,使用iSCSI協定基於乙太網傳送SCSI命令與資料,克服了SCSI需要直接連線儲存裝置的局限性,使得可以跨越不同的伺服器共用儲存裝置,並可以做到不停機狀態下擴充套件儲存容量。
iSCSI實現的是IP SAN,資料傳輸基於乙太網。
1.2 iSCSI資料封裝
initiator向target發起scsi命令後,在資料包文從裡向外逐層封裝SCSI協定報文、iSCSI協定報文、tcp頭、ip頭。
封裝是需要消耗CPU資源的,如果完全以軟體方式來實現iscsi,那麼所有的封裝過程都由作業系統來完成。在很繁忙的伺服器上,這樣的資源消耗可能不太能接受,但好在它是完全免費的,對於不是非常繁忙的伺服器採用它可以節省一大筆資金。
除了軟體方式實現,還有硬體方式的initiator(TOE卡和HBA卡),通過硬體方式實現iSCSI。由於它們有控制晶片,可以幫助或者完全替代作業系統對協定報文的封裝。
- TOE卡,作業系統首先封裝SCSI和iSCSI協定報文,而TCP/IP頭則交由TOE內的晶片來封裝,這樣就能減少一部分系統資源消耗。
- HBA卡,作業系統只需封裝SCSI,剩餘的iSCSI協定報文還有TCP/IP頭由HBA晶片負責封裝。
顯然,HBA卡實現iSCSI是最好的方案,但是它要花錢,還不便宜。
第2章 設定使用iSCSI
2.1 部署iscsi前的說明和需求描述
1.說明
- (1).iscsi在target端是工作在通訊端上的,監聽埠預設是3260,且使用的是tcp連線。因為要保證資料安全性,使用udp可能會導致丟包。
- (2).iscsi對用戶端有身份認證的需要,有兩種認證方式:基於IP認證,基於CHAP認證(雙方都進行驗證,即雙向認證)。
2.需求描述
找一台伺服器A作為iscsi的target,將其中的一塊磁碟或分割區/dev/sdb當作要共用的儲存裝置共用出去。再找兩台伺服器B和C當作iscsi initiator連線到target的共用儲存上。
大致拓撲圖如下:
請確保伺服器A上已經關閉了防火牆或者允許了3260埠。
下圖描述了使用iSCSI的大致過程,後文內容雖然因為介紹各種用法而顯得比較雜,但根據這張圖的流程,閱讀時很容易搞清楚相關內容。
2.2 安裝target
在伺服器A上:
yum -y install scsi-target-utils
檢視該工具包生成了哪些檔案。
rpm -ql scsi-target-utils
/etc/rc.d/init.d/tgtd #
/etc/sysconfig/tgtd
/etc/tgt/targets.conf #
/usr/sbin/tgt-admin #
/usr/sbin/tgt-setup-lun
/usr/sbin/tgtadm #
/usr/sbin/tgtd
/usr/sbin/tgtimg
/usr/share/doc/scsi-target-utils-1.0.24
/usr/share/doc/scsi-target-utils-1.0.24/README
/usr/share/doc/scsi-target-utils-1.0.24/README.iscsi
/usr/share/doc/scsi-target-utils-1.0.24/README.iser
/usr/share/doc/scsi-target-utils-1.0.24/README.lu_configuration
/usr/share/doc/scsi-target-utils-1.0.24/README.mmc
/usr/share/man/man5/targets.conf.5.gz
/usr/share/man/man8/tgt-admin.8.gz
/usr/share/man/man8/tgt-setup-lun.8.gz
/usr/share/man/man8/tgtadm.8.gz
其中/usr/sbin/tgtadm
和/usr/sbin/tgt-admin
的都是管理和設定target的工具,它們作用是一樣的,只不過tgtadm是命令列下的工具,而tgt-admin是根據組態檔/etc/tgt/targets.conf
呼叫tgtadm來實現。另外/etc/init.d/tgtd
是服務啟動指令碼。
這個時候已經可以啟動target服務了。
service tgtd start
netstat -tnlp | grep 3260
tcp 0 0 0.0.0.0:3260 0.0.0.0:* LISTEN 2074/tgtd
tcp 0 0 :::3260 :::* LISTEN 2074/tgtd
加入開機自啟動。
chkconfig tgtd on
2.2.1 tgtadm命令用法說明
tgtadm是一個高度模式化的命令,他們的模式很相近。有三個模式:target、logicalunit、account。指定模式時使用--mode選項。再使用--op來指定對應模式下的選項。另外,使用-lld指定driver,有兩種driver:iscsi和iser,基本都會使用iscsi。
tgtadm --help
--lld <driver> --mode target --op new --tid <id> --targetname <name>
add a new target with <id> and <name>. <id>
must not be zero.
--lld <driver> --mode target --op delete [--force] --tid <id>
delete the specific target with <id>.
With force option, the specific target is
deleted even if there is an activity.
--lld <driver> --mode target --op show
show all the targets.
--lld <driver> --mode target --op show --tid <id>
show the specific target's parameters.
--lld <driver> --mode target --op update --tid <id> --name <param> --value <value>
change the target parameters of the specific
target with <id>.
--lld <driver> --mode target --op bind --tid <id> --initiator-address <address>
--lld <driver> --mode target --op bind --tid <id> --initiator-name <name>
enable the target to accept the specific initiators.
--lld <driver> --mode target --op unbind --tid <id> --initiator-address <address>
--lld <driver> --mode target --op unbind --tid <id> --initiator-name <name>
disable the specific permitted initiators.
--lld <driver> --mode logicalunit --op new --tid <id> --lun <lun>
--backing-store <path> --bstype <type> --bsoflags <options>
add a new logical unit with <lun> to the specific
target with <id>. The logical unit is offered
to the initiators. <path> must be block device files
(including LVM and RAID devices) or regular files.
bstype option is optional.
bsoflags supported options are sync and direct
(sync:direct for both).
--lld <driver> --mode logicalunit --op delete --tid <id> --lun <lun>
delete the specific logical unit with <lun>
that the target with <id> has.
--lld <driver> --mode account --op new --user <name> --password <pass>
add a new account with <name> and <pass>.
--lld <driver> --mode account --op delete --user <name>
delete the specific account having <name>.
--lld <driver> --mode account --op bind --tid <id> --user <name> [--outgoing]
add the specific account having <name> to
the specific target with <id>.
<user> could be <IncomingUser> or <OutgoingUser>.
If you use --outgoing option, the account will be
added as an outgoing account.
--lld <driver> --mode account --op unbind --tid <id> --user <name>
delete the specific account having <name> from
specific target.
--control-port <port> use control port <port>
看上去很複雜。不過可以將上面的語法拋去driver部分,target、logicalunit和account這3種模式下的操作方式簡化後如下:
這樣就簡單的多了。
上表中的選項都是長格式的,但他們都有對應的短格式選項。
target和logicalunit兩個模式隨後就會有範例,而account是和CHAP認證有關的,將在後文和組態檔放在一塊解釋。
2.2.2 target的命名方式
iqn.YYYY-mm.<reversed domain name>[:identifier]
iqn
是iscsi qualified name的縮寫,就像fqdn一樣。YYYY-mm
描述的是此target是何年何月建立的,如2016-06。<reversed domain name>
是域名的反寫,起到了唯一性的作用,如longshuai.com寫為com.longshuai。identifier
是可選的,是為了知道此target相關資訊而設的描述性選項,如指明此target用到了哪些硬碟。
範例:
iqn.2016-06.com.longshuai:test.disk1
2.2.3 建立一個target
需要說明的是,下面的實驗全是使用命令列工具tgtadm來實現的。但是修改組態檔然後使用tgt-admin也是一樣可以的,且target數量多的時候,更建議使用設定為檔案載入的方式。最重要的一點是,使用命令列方式建立的target及lu等是臨時生效的,在target服務重新啟動後就失效了,再手動建立它們是一件相當麻煩的事情。
如下,分別使用了長格式選項和短格式選項分別建立和顯示target。注意:建立target時,tid不能是0,因為0是被系統保留的。
tgtadm --lld iscsi --mode target --op new --tid 1 --targetname iqn.2017-03.com.longshuai:test.disk1
tgtadm -L iscsi -m target -o show
以上是第一個target的資訊。從資訊中可以看到:
- 建立完第一個target後自動就建立了一個LUN為0的logicalunit(以後簡稱lu),這是固定給每個target都使用的LUN。
- 此lu的型別是controller。
- "backing store type"為null,即此lu沒有向下擴充套件邏輯裝置,因為它是lun控制器。也就是說這個LUN是保留作為lu控制器用的。
- "I_T nexus information"記錄的是initiator與此target的聯結關係,nexus的意思就是聯結、關聯,在後文介紹initiator的時候會展示此處資訊。
現在向此target新增一個lu,使用的是新插入的磁碟/dev/sdc(全新,未進行分割區)。當然,使用新建立的分割區或者已經格式化後的分割區做實驗也可以。
tgtadm -L iscsi -m logicalunit -o new -t 1 -l 1 -b /dev/sdc
然後再來檢視target的資訊。
tgtadm -L iscsi -m target -o show
從LUN 1資訊中可以看出,lu type已經是disk而非controller,且顯示了此lu的容量大小是42950M。另外還顯示了使用的邏輯裝置是/dev/sdc,且是可讀可寫的(rdwr)。
但到目前為止,該target都沒有定義共用給誰,這從target資訊的最後兩行Account/ACL information中可以看出。
現在將此target系結一個共用IP,即說明此IP可以連線該target。這是iSCSI的一種認證方式:IP認證。除此之外,還有基於account的CHAP認證,詳細內容見後文。IP認證的作用是允許Initiator發現該target,並允許做進一步的基account的CHAP認證。
tgtadm -L iscsi -m target -o bind -t 1 -I 192.168.100.0/24
tgtadm -L iscsi -m target -o show
再新增一個10G分割區/dev/sdb1為邏輯儲存單元,lun=2。
tgtadm -L iscsi -m logicalunit -o new -t 1 -l 2 -b /dev/sdb1
tgtadm -L iscsi -m target -o show
由於該lu是在target id=1下的,所以192.168.100.0這個網段的機器也能存取此裝置。也就是說,共用出去的是target級別而不是lu級別的。
然後在iscsi的"用戶端"initiator安裝iscsi-initiator-utils看看是否能看見這兩個裝置。如果想急著看結果,請跳到安裝initiator的章節中。
2.2.4 tgt-admin和組態檔targets.conf
tgt-admin是讀取組態檔的選項然後呼叫tgtadm來執行的工具。它的選項很多可以簡化tgtadm命令的書寫,畢竟tgtadm的選項太長太多餘了,除此之外也有一些其他的作用用於更細緻的配(tgtadm設定的太粗糙了)。用法如下:
tgt的組態檔為/etc/tgt/targets.conf
,該組態檔的格式很容易讀懂,能實現的target和lun的設定方式多種多樣。它的配製方法在後文會和iscsi initiator的組態檔/etc/iscsi/iscsid.conf放在一起介紹。
下面就使用tgt-admin為當前的target生成對應的組態檔來稍作分析。
首先列出當前target的資訊。
bash> tgt-admin -s
Target 1: iqn.2017-03.com.longshuai:test.disk1
System information:
Driver: iscsi
State: ready
I_T nexus information:
LUN information:
LUN: 0
Type: controller
SCSI ID: IET 00010000
SCSI SN: beaf10
Size: 0 MB, Block size: 1
Online: Yes
Removable media: No
Prevent removal: No
Readonly: No
Backing store type: null
Backing store path: None
Backing store flags:
LUN: 1
Type: disk
SCSI ID: IET 00010001
SCSI SN: beaf11
Size: 10742 MB, Block size: 512
Online: Yes
Removable media: No
Prevent removal: No
Readonly: No
Backing store type: rdwr
Backing store path: /dev/sdb1
Backing store flags:
LUN: 2
Type: disk
SCSI ID: IET 00010002
SCSI SN: beaf12
Size: 42950 MB, Block size: 512
Online: Yes
Removable media: No
Prevent removal: No
Readonly: No
Backing store type: rdwr
Backing store path: /dev/sdc
Backing store flags:
Account information:
ACL information:
192.168.100.0/24
使用--dump
選項輸出為組態檔的格式,並將其重定向到/tmp/tgt.conf中。
bash> tgt-admin --dump | tee /tmp/tgt.conf
default-driver iscsi
<target iqn.2017-03.com.longshuai:test.disk1>
backing-store /dev/sdb1
backing-store /dev/sdc
initiator-address 192.168.100.0/24
</target>
由此可以看出,全域性使用的driver是iscsi,名稱為iqn.2017-03.com.longshuai:test.disk1
的target有兩個backing-store,即邏輯裝置,分別是/dev/sdb1和/dev/sdc。但是要注意,這樣匯出的組態檔指定的LUN號碼可能會在tgt-admin讀取並執行的時候更換位置,但這並不會有任何影響。
現在將已有的target全部刪除,再去檢視資訊就已經沒有了。
tgt-admin --delete ALL
tgt-admin -s
再從剛才生成的組態檔中讀取並啟動。然後檢視資訊,發現已經有了target。
tgt-admin -e -c /tmp/tgt.conf
tgt-admin -s
關於tgt-admin其他選項也都很簡單,都是從字面意思就能看出來用法的。所以就不多說明了。
另外需要說明的是在tgt的組態檔/etc/tgt/targets.conf
中有一行:
#include /etc/tgt/temp/*.conf
將此行註釋後,以後可以匯出組態檔到/etc/tgt/temp目錄下並以.conf作為字尾,重新啟動tgtd服務即可重新載入,而不需要在手動載入了。不過有個問題,使用dump出來的組態檔會有default-driver指令行,而這一行在主組態檔中也有,且他們是不能出現多次的,否則將會報錯,所以需要將主組態檔中的default-driver指令注釋掉。
2.3 安裝initiator
安裝Initiator的機器成為iscsi的發起者,initiator本身的意思就是"發起者",在這裡即iscsi的"用戶端"程式的意思。
此處先在B伺服器(192.168.100.5)上安裝iscsi-initiator-utils。另一台C伺服器後面再做測試。
yum -y install iscsi-initiator-utils
2.3.1 相關檔案和目錄說明
下面是此安裝包生成的一些重要檔案和目錄(只列出了必要的部分)。
rpm –ql iscsi-initiator-utils
其中:
/etc/iscsi/iscsid.conf
:是iscsi發起者的組態檔。/etc/rc.d/init.d/{iscsi,iscsid}
:服務啟動指令碼,只需要啟動iscsi即可,因為它會自動呼叫iscsid指令碼。/sbin/iscsi-iname
:為initiator命名的工具。就像target有自己獨特的iqn名稱,initiator也有獨特的名稱標識自己。/sbin/iscsiadm
:initiator的管理工具,在initiator上的絕大部分的命令都是通過它來執行的。/var/lib/iscsi/ifaces
:指定使用哪個網絡卡介面和target通訊。/var/lib/iscssi/nodes
:該目錄中儲存了發現的target,分別是以target_name命名的目錄,在target_name目錄下又儲存了以"target_ip,port"(如192.168.100.151,3260)的組態檔,這個組態檔是本initiator向對應的target 發起連線時的引數,這些引數繼承於/etc/iscsi/iscsid.conf
。/var/lib/iscsi/send_targets
:該目錄中也儲存了一個或多個以"target_IP,port"命名的目錄,記錄的是discovery的歷史記錄,對於discovery成功的則在對應的目錄會有檔案,否則是空目錄。
其中IP,port
的記錄方式稱為protal,是入口、入門的意思。
需要注意的是,建議不要把iscsi和iscsid設定為開機自啟動,因為開機時如果它找不到target的時候會一直卡在那裡等待。可以將其放在rc.local檔案中來啟動。
chkconfig iscsi off
chkconfig iscsid off
echo "service iscsi start" >>/etc/rc.d/rc.local
2.3.2 iscsi-iname命令
和target一樣,initiator也需要一個獨特的名稱來標識自己讓target識別。initiator在連線target的時候,會讀取/etc/iscsi/initiatorname.iscsi中的內容作為自己的iname。
初始狀態的iname如下:
bash> cat /etc/iscsi/initiatorname.iscsi
InitiatorName=iqn.1994-05.com.RedHat:ceb390801983
其中字尾"ceb390801983"是一個隨機串。
也可以為iname生成一個別名,只需在此檔案中另起一行寫入以下內容:
InitiatorAlias=INAME_ALIAS
如:
InitiatorAlias=client.longshuai.com
若要自指定iname,可以手動修改該檔案。也可以使用iscsi-iname工具來生成iname並儲存到該檔案。
bash> iscsi-iname
iqn.1994-05.com.redhat:5a804fa64f8e
bash> iscsi-iname
iqn.1994-05.com.redhat:ca4eb16bbddd
可以看出iscsi-iname生成的iname字首都是一樣的,修改的只是字尾部分的隨機串。如果要指定字首,則使用-p選項。
bash> iscsi-iname -p iqn.2017-03.com.longshuai
iqn.2017-03.com.longshuai:adb6a5ec885c
所以,通過iscsi-iname向/etc/iscsi/initiatorname.iscsi中寫入一個iname。
echo Initiatorname=`iscsi-iname -p iqn.2017-03.com.longshuai` >/etc/iscsi/initiatorname.iscsi
然後重新啟動下iscsi服務。
service iscsi restart
2.3.3 iscsiadm命令
iscsiadm也是一個模式化的命令,使用-m指定mode。mode有:discovery、node、session、iface。一般就用前兩個mode。
discovery
:發現某伺服器是否有target輸出,以及輸出了哪些target。發現target後會生成target資料庫discoverydb。node
:管理跟某target的關聯關係。在discovery發現了target後,是否要跟target建立關係,是否要刪除已有的關係或者解除已有的關係等。刪除關聯關係不僅會解除關聯,還會刪除發現target後生成的discoverydb。session
:對談管理。iface
:介面管理。
2.3.4 發現target(discovery)
即使用discovery模式。
iscsiadm -m discovery [ -d debug_level ] [ -t type -p ip:port -I ifaceN [ -p ip:port ]
-d:輸出偵錯資訊,級別從0-8。出現錯誤的時候用來判斷錯誤來源是很有用處的,可以使用級別2。
-I:指定發現target時通訊介面。
-t type:有三種type(sendtargets,SLP,iSNS),一般只會用到sendtargets,可以簡寫為st。
-p IP:PORT:指定要發現target的IP和埠,不指定埠時使用預設的3260。現在可以進行discovery了。這裡發起兩次,第一次是正確的,第二次是錯誤的(該IP上沒有target或主機未啟動)。
bash> iscsiadm -m discovery -t st -p 192.168.100.151:3260
192.168.100.151:3260,1 iqn.2017-03.com.longshuai:test.disk1
bash> iscsiadm -m discovery -t st -p 192.168.100.152:3260
iscsiadm: cannot make connection to 192.168.100.152: No route to host
iscsiadm: cannot make connection to 192.168.100.152: No route to host
iscsiadm: cannot make connection to 192.168.100.152: No route to host
iscsiadm: cannot make connection to 192.168.100.152: No route to host
iscsiadm: cannot make connection to 192.168.100.152: No route to host
iscsiadm: cannot make connection to 192.168.100.152: No route to host
iscsiadm: connection login retries (reopen_max) 5 exceeded
iscsiadm: Could not perform SendTargets discovery: encountered connection failure如果出現以上錯誤,檢查下是不是防火牆阻擋了,是不是IP地址寫錯了。
在發現了target後,在/var/lib/iscsi中的nodes和send_targets目錄中就有了檔案。
tree /var/lib/iscsi/
可以看到,對於discovery失敗的在send_targets目錄中也會記錄,只不過是空目錄。在nodes目錄和正確discovery到的send_targets子目錄中都有幾個組態檔,都是些引數資訊。而且可以看到,send_targets中的目錄是nodes目錄的軟連結。
如果想重新發現已存在的target時,可以清空nodes目錄中對應的項,然後再discovery。
使用service iscsi status
可以檢視到相關資訊項。
2.3.5 關聯和解除關聯target(node)
關聯target的作用是initiator和target建立session,建立session後,initiator上就可以檢視、存取、操作target上的scsi裝置。
有兩種關聯方法,一是關聯所有,一是指定單個target進行關聯。
iscsiadm -m node [-d debug_level] [-L all,manual,automatic] [-U all,manual,automatic]
iscsiadm -m node [-d debug_level] [[-T targetname -p ip:port -I ifaceN] [-l | -u ]] [-o operation]
-d:指定debug級別,有0-8個級別。
-L和-U:分別是登入和登出target,可以指定ALL表示所有發現的target,或者manual指定。
-l和-u:分別是登入和登出某一個target。
-T:用於-l或-u時指定要登入和登出的targetname。
-o:對discoverydb做某些操作,可用的操作有new/delete/update/show,一般只會用到delete和show。例如,使用單個的關聯方式關聯target。其中target_name可以通過命令iscsiadm -m node檢視。
bash> iscsiadm -m node
192.168.100.151:3260,1 iqn.2017-03.com.longshuai:test.disk1
bash> iscsiadm -m node -T iqn.2017-03.com.longshuai:test.disk1 -p 192.168.100.151:3260 -l
Logging in to [iface: default, target: iqn.2017-03.com.longshuai:test.disk1, portal: 192.168.100.151,3260] (multiple)
Login to [iface: default, target: iqn.2017-03.com.longshuai:test.disk1, portal: 192.168.100.151,3260] successful.實際上,在執行discovery的時候很可能就已經自動執行了關聯,所以再次關聯很可能什麼訊息也看不到。如果是這樣的話,需要先退出session,再進行關聯。當然也可能是直接顯示successful,這樣就說明原來discovery的時候是沒有主動關聯的。
iscsiadm -m node -T iqn.2017-03.com.longshuai:test.disk1 -p 192.168.100.151:3260 -u此時fdisk -l看看是否已經多出了兩塊硬碟出來。
bash> fdisk -l
Disk /dev/sda: 21.5 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0005ff67
Device Boot Start End Blocks Id System
/dev/sda1 * 1 32 256000 83 Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2 32 2356 18666496 83 Linux
/dev/sda3 2356 2611 2048000 82 Linux swap / Solaris
Disk /dev/sdb: 10.7 GB, 10742183424 bytes
64 heads, 32 sectors/track, 10244 cylinders
Units = cylinders of 2048 * 512 = 1048576 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
Disk /dev/sdc: 42.9 GB, 42949672960 bytes
64 heads, 32 sectors/track, 40960 cylinders
Units = cylinders of 2048 * 512 = 1048576 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000現在就可以對這兩塊邏輯盤進行分割區格式化(建立檔案系統),並投入使用。
此時先看下target端的target資訊。
tgt-admin -s | less
其中I_T nexus表示initiator到target的關聯資訊,nexus的值是該initiator關聯到target的次數。多個initiator會顯示多個I_T nexus資訊。這裡可以看到只有一個I_T nexus,說明只有一個initiator進行了關聯。
2.3.6 iSCSI的資料不安全性(不同步性)
現在在initiator上將/dev/sdb進行格式化,並向其中寫入一個檔案。
parted /dev/sdb mklabel gpt
parted /dev/sdb mkpart /dev/sdb1 ext4 1 10G
mkfs.ext4 /dev/sdb1
parted /dev/sdb print
mount /dev/sdb1 /mnt/
echo "haha" > /mnt/test.txt然後設定伺服器C(192.168.100.6),讓其作為另一台initiator。
bash> yum -y install iscsi-initiator-utils
bash> iscsiadm -m discovery -t st -p 192.168.100.151:3260
bash> iscsiadm -m node -T iqn.2017-03.com.longshuai:test.disk1 -p 192.168.100.151:3260 -l
bash> fdisk -l
bash> mount /dev/sdb1 /mnt
bash> ls /mnt
lost+found test.txt不出所料,C伺服器也能掛載/dev/sdb1,且在B伺服器寫入的test.txt檔案也已經同步過來了。
再看看此時target的target資訊。
bash> tgt-admin -s
Target 1: iqn.2017-03.com.longshuai:test.disk1
System information:
Driver: iscsi
State: ready
I_T nexus information:
I_T nexus: 1
Initiator: iqn.2017-03.com.longshuai:b01d684ad13f
Connection: 0
IP Address: 192.168.100.5
I_T nexus: 2
Initiator: iqn.1994-05.com.redhat:42b7f829d2ec
Connection: 0
IP Address: 192.168.100.6現在在C伺服器上,向/dev/sdb1掛載的目錄/mnt下寫入一個檔案,看看是否會同步到B伺服器上。
echo "hehe" >/mnt/test1.txt在192.168.100.5上執行:
ls /mnt/
lost+found test.txt
echo "heihei" >/mnt/test3.txt顯然,test1.txt並沒有同步到B伺服器上。同理,此時B中再寫入檔案也不會同步到C上。
那麼在C上解除安裝/mnt,然後再次掛載會有什麼情況呢?
umount /mnt
mount /dev/sdb1 /mnt
ls /mnt
lost+found test3.txt test.txt沒看錯,test1.txt確實沒了。這就是使用iscsi出現的問題,多個主機同時使用邏輯儲存,資料會衝突並且不能及時同步而導致資料丟失。
所以,iscsi一定要配合叢集檔案系統或者分散式檔案系統來使用以防止上述問題。
2.3.7 initiator開機一直處於等待狀態
該問題在前文描述過。
出現這個問題是因為initiator端設定了iscsi或iscsid開機自啟動,正好又無法和target聯絡,如通訊出現故障、target處於關機狀態、target中的tgtd服務未啟動、target上的target_id和target_name等設定改變了。
總而言之,開機自啟動的時候無法正常關聯/var/lib/iscsi目錄下記錄的target就會出現此問題。
解決辦法也是建議的辦法是把iscsi和iscsid的開機自啟動關閉掉,然後把啟動他們的命令放到rc.local中。
如果已經遇到了無法正常開機的情況,那麼可以多等待些時間,或者修改target端讓target端能夠和initiator匹配上。如target端本來是關機狀態,將其開機即可。
第3章 target和initiator的組態檔
3.1 initiator的組態檔
一般而言,對於initiator的組態檔/etc/iscsi/iscsid.conf,裡面預設設定了重新啟動服務就自動對已發現過的target進行關聯,所以重新啟動iscsi服務的時候會自動進行關聯。
如果不使用CHAP,則基本可以無視這個組態檔。使用CHAP認證的時候設定下面CHAP相關的段落就夠了,其他的設定段落可以不用理會。關於CHAP認證,稍後就介紹。
# *************
# CHAP Settings
# *************
####以下是initiator authentication相關
# To enable CHAP authentication set node.session.auth.authmethod to CHAP. The default is None.
#node.session.auth.authmethod = CHAP
# To set a CHAP username and password for initiator authentication by the target(s):
#node.session.auth.username = username
#node.session.auth.password = password
####以下是target authentication相關
# To set a CHAP username and password for target(s) authentication by the initiator:
#node.session.auth.username_in = username_in
#node.session.auth.password_in = password_in
####以下是discovery認證相關,iscsi-initiator-utils似乎不支援這個認證,所以以下項不能開啟和設定
# To enable CHAP authentication for a discovery session to the target
# set discovery.sendtargets.auth.authmethod to CHAP. The default is None.
#discovery.sendtargets.auth.authmethod = CHAP
# To set a discovery session CHAP username and password for the initiator authentication by the target(s):
#discovery.sendtargets.auth.username = username
#discovery.sendtargets.auth.password = password
# To set a discovery session CHAP username and password for target(s) authentication by the initiator:
#discovery.sendtargets.auth.username_in = username_in
#discovery.sendtargets.auth.password_in = password_in所以,如果只要實現單向認證,則開啟以下三項即可。
node.session.auth.authmethod = CHAP
node.session.auth.username = username
node.session.auth.password = password如果要實現雙向認證,則需要開啟以下5項。
node.session.auth.authmethod = CHAP
node.session.auth.username = username
node.session.auth.password = password
node.session.auth.username_in = username_in
node.session.auth.password_in = password_in且需要注意的是,如果是單向認證,則後兩項必須不能開,開了就會進行雙向認證。
雖然iscsi-initiator-utils支援discovery認證,但是由於scsi-target-utils不支援discovery認證,所以在認證關聯target之前必須先進行discovery,也就是說在target端的存取控制列表ACL項中必須要定義允許initiator進行discovery。
3.2 target組態檔的設定方法
target端使用tgtadm命令設定的結果都是工作在核心中的,重新啟動tgt服務或重新啟動系統時,記憶體中的內容都會丟失。所以要永久讓設定生效需要寫入到組態檔中去。
target的組態檔預設是/etc/tgt/targets.conf,但是可以在/etc/tgt/temp/目錄(預設不存在)下建立多個以".conf"為字尾的組態檔,然後啟用主組態檔中的include指令即可。
以下給出兩個設定的例子,這個組態檔很通俗易懂。
#include /etc/tgt/temp/*.conf
default-driver iscsi
<target iqn.2017-03.com.longshuai:test.disk1>
backing-store /dev/sdb1
backing-store /dev/sdc
incominguser <incoming_username> <PASSWORD>
outgoinguser <outgoing_username> <PASSWORD>
initiator-address 192.168.100.0/24
</target>這樣的設定,backing-store的順序決定了lun號碼的順序,上面的設定中/dev/sdb1會是Lun1,/dev/sdc會是lun2。
若想要為每個邏輯裝置指定想要指定的lun號碼,需要將每個backing-store封裝在target中並獨立指定lun號碼。
#include /etc/tgt/temp/*.conf
default-driver iscsi
<target iqn.2017-03.com.longshuai:test.disk1>
<backing-store /dev/sdb1>
lun 5
</backing-store>
<backing-store /dev/sdc>
lun 6
</backing-store>
incominguser <incoming_username> <PASSWORD>
outgoinguser <outgoing_username> <PASSWORD>
initiator-address 192.168.100.0/24
</target>
3.3 重新啟動tgtd服務不載入組態檔的問題
如果在正常狀態下有initiator關聯了target裝置,此時重新啟動tgtd服務很可能會導致組態檔中的設定不生效,這是為了保護initiator仍然可以隨時關聯target而不丟失資料和狀態設立的機制。但不得不說,這個特性真的很讓人煩惱,設定不生效,難道非得再使用tgtadm來重新生成到核心嗎?
問題如下描述。
當前的target狀態如下:
bash> tgt-admin -s
Target 1: iqn.2017-03.com.longshuai:test1.disk1
System information:
Driver: iscsi
State: ready
I_T nexus information:
LUN information:
LUN: 0
Type: controller
SCSI ID: IET 00010000
SCSI SN: beaf10
……省略部分結果……
LUN: 1
Type: disk
SCSI ID: IET 00010001
SCSI SN: beaf11
……省略部分結果……
LUN: 2
Type: disk
SCSI ID: IET 00010002
SCSI SN: beaf12
Size: 42950 MB, Block size: 512
……省略部分結果……
Account information:
ACL information:
192.168.100.0/24組態檔中啟用的項如下。這和上面的狀態是一樣的。
<target iqn.2017-03.com.longshuai:test1.disk1>
backing-store /dev/sdb1
backing-store /dev/sdc
initiator-address 192.168.100.0/24
</target>此時在initiator上關聯此target,然後登出。這裡無論登不登出對target的影響都是一樣的。
iscsiadm -m discovery -t st -p 192.168.100.151:3260
iscsiadm -m node -T iqn.2017-03.com.longshuai:test1.disk1 -p 192.168.100.151:3260 -l
iscsiadm -m node -T iqn.2017-03.com.longshuai:test1.disk1 -p 192.168.100.151:3260 -u再重新啟動target上的tgtd服務,然後檢視狀態。
service tgtd restart
Stopping SCSI target daemon: [ OK ]
Starting SCSI target daemon: [ OK ]
tgt-admin -s
Target 1: iqn.2017-03.com.longshuai:test1.disk1
System information:
Driver: iscsi
State: ready
I_T nexus information:
LUN information:
LUN: 0
Type: controller
SCSI ID: IET 00010000
SCSI SN: beaf10
Size: 0 MB, Block size: 1
Online: Yes
Removable media: No
Prevent removal: No
Readonly: No
Backing store type: null
Backing store path: None
Backing store flags:
Account information:
ACL information:
192.168.100.0/24結果lun1和lun2沒了。無論再怎麼重新啟動結果都是一樣,哪怕是手動使用tgt-admin -e -c指定組態檔執行結果也一樣。
好在/etc/init.d/tgtd提供了不少的選項。
/etc/init.d/tgtd --help
Usage: /etc/init.d/tgtd {start|stop|status|restart|condrestart|try-restart|reload|force-stop|force-restart|force-reload}它們的意思無須多述。
經過測試,上述問題只有使用force-reload選項能解決,其他所有選項都無效,包括force-restart和reload。
service tgtd force-reload或者重新啟動系統也能解決,但是誰沒事會重新啟動系統呢?
第4章 account模式和CHAP認證
4.1 CHAP認證
基於IP的認證比較粗糙,不過多數時候已經夠用了。但對於安全性要求高的環境來說,使用CHAP認證更好一些。
CHAP(Challenge-Handshake Authentication Protocol),稱為挑戰式握手認證協定,它是雙向認證,當然也支援單向認證。
對於iscsi而言,在CHAP認證的機制上有兩種方式:initiator authentication
和target authentication
。
- initiator authentication認證
在initiator嘗試連線到一個target的時候,initator需要提供一個使用者名稱和密碼給target被target進行認證。也就是說initiator需要被target認證,它向target端提供的賬號和密碼是target端指定的。
這個賬號和密碼對於target來說是流入的賬號和密碼,用incoming表示。所以後面稱呼這個賬號和密碼為incoming賬號和incoming密碼。再次說明,incoming賬號是initiator端提供給target端,被target端認證的賬號。
- target authentication認證
在initiator嘗試連線到一個target的時候,target有時也需要被initiator認證,以確保該target是合法而非偽裝的target,這就要求target提供一個使用者名稱和密碼給initiator被initiator進行認證。
target向initiator提供的賬號和密碼對於target而言是流出的,所以稱之為outgoing。所以outgoing使用的賬號和密碼在後文稱為outgoing賬號和outgoing密碼。而對於initiator而言是incoming的,所以在initiator組態檔中稱為in。也就是說outgoing賬號是target端提供給initiator端,被initiator認證的賬號,但儘管如此,這個賬號和密碼還是在target端建立和系結的。
綜上,不管是什麼認證,賬號和密碼都是target端建立和系結。
以上兩種認證方式是有層次順序的。一般來說,有認證需求的時候都是伺服器驗證用戶端是否有許可權,iscsi也一樣。
initiator authentication可以單獨存在,它可以在沒有target authentication的情況下應用,這時候的CHAP認證就是單向認證(target認證initiator的合法性)。
但target authentication只有在initiator authentication的基礎上才能進行。也就是說target認證和initiator認證必須同時存在才可以。即initiator和target需要相互認證實現雙向CHAP認證。
4.2 tgtadm命令的account模式用法
以下是tgtadm --help關於account的結果,但是用法給的並不全面。
--lld <driver> --mode account --op new --user <name> --password <pass>
--lld <driver> --mode account --op delete --user <name>
--lld <driver> --mode account --op bind --tid <id> --user <name> [--outgoing]
--lld <driver> --mode account --op unbind --tid <id> --user <name>以下是個人發現的較為全面的用法,為了偷懶,所以使用短選項格式來表示。其中
# 新建一個使用者
-L <driver> -m account -o new --u <name> --p <pass>
# 刪除一個使用者
-L <driver> -m account -o delete --u <name>
# 檢視使用者列表
-L <driver> -m account -o show
# 係結使用者到target上,outgoing的意義在後文會說明
-L <driver> -m account -o bind -t <tid> -u <name> [--outgoing]
# 從target上解綁使用者
-L <driver> -m account -o unbind -t <tid> -u <name> [--outgoing]
4.3 實現CHAP單向認證
首先確保target的ACL是允許initiator進行discovery的。
bash> tgt-admin -s | sed -n '/Account/,$p'
Account information:
ACL information:
192.168.100.0/24
在target端建立initiator authentication所需的賬號和密碼並繫結到target_ID上。這個賬號是用來對initiator進行單向認證的,所以對於target而言是incoming賬號。
tgtadm -L iscsi -m account -o new --user incoming_malong --password incoming_123456
tgtadm -L iscsi -m account -o bind -t 1 --user incoming_malong
檢視下系結情況。
tgt-admin -s | sed -n '/Account/,$p'
Account information:
incoming_malong
ACL information:
192.168.100.0/24
由於tgtg的工作在核心當中的,所以設定好後無需重新啟動服務,這些賬號相關的就可以生效。
在initiator端修改組態檔/etc/iscsi/iscsid.conf,設定以下幾項,這裡故意沒啟用密碼認證部分,是為了看到認證失敗的結果。。(這裡使用的是伺服器B,即192.168.100.5這台機器,伺服器C即192.168.100.6在後面系結多個賬號的時候拿來做測試用)
vim /etc/iscsi/iscsid.conf
node.session.auth.authmethod = CHAP
node.session.auth.username = incoming_malong
#node.session.auth.password = incoming_123456
在initiator發現,然後關聯。
bash> iscsiadm -m discovery -t st -p 192.168.100.151:3260
192.168.100.151:3260,1 iqn.2017-03.com.longshuai:test.disk1
bash> iscsiadm -m node -T iqn.2017-03.com.longshuai:test.disk1 -p 192.168.100.151:3260 -l
Logging in to [iface: default, target: iqn.2017-03.com.longshuai:test.disk1, portal: 192.168.100.151,3260] (multiple)
iscsiadm: Could not login to [iface: default, target: iqn.2017-03.com.longshuai:test.disk1, portal: 192.168.100.151,3260].
iscsiadm: initiator reported error (24 - iSCSI login failed due to authorization failure)
iscsiadm: Could not log into all portals
因為認證所需的密碼沒設定,所以認證失敗了。設定為正確的賬號和密碼再進行發現、關聯認證。
bash> vim /etc/iscsi/iscsid.conf
node.session.auth.authmethod = CHAP
node.session.auth.username = incoming_malong
node.session.auth.password = incoming_123456
bash> iscsiadm -m discovery -t st -p 192.168.100.151:3260
192.168.100.151:3260,1 iqn.2017-03.com.longshuai:test.disk1
bash> iscsiadm -m node -T iqn.2017-03.com.longshuai:test.disk1 -p 192.168.100.151:3260 -l
Logging in to [iface: default, target: iqn.2017-03.com.longshuai:test.disk1, portal: 192.168.100.151,3260] (multiple)
Login to [iface: default, target: iqn.2017-03.com.longshuai:test.disk1, portal: 192.168.100.151,3260] successful.
4.4 實現CHAP雙向認證
要雙向認證,那麼target端需要建立一個outgoing賬號和密碼,並繫結到target上。注意下面的--outgoing
選項,表示是從target流出的賬號,即表示該target要被initiator認證。
tgtadm -L iscsi -m account -o new --user outgoing_malong --password outgoing_123456
tgtadm -L iscsi -m account -o bind -t 1 --user outgoing_malong --outgoing
檢視下target上的賬號資訊。在資訊中,outgoing的賬號後面使用括號對此進行了標識。
tgt-admin -s | sed -n '/Account/,$p'
Account information:
incoming_malong
outgoing_malong (outgoing)
ACL information:
192.168.100.0/24
然後在initiator端設定CHAP雙向認證。同樣,此處先設定一個錯誤的情況以作比較。
vim /etc/iscsi/iscsid.conf
node.session.auth.authmethod = CHAP
node.session.auth.username = incoming_malong
node.session.auth.password = incoming_123456
node.session.auth.username_in = outgoing_malong
#node.session.auth.password_in = outgoing_123456
重新進行發現和關聯。不過首先要登出已經登入的target。
iscsiadm -m node -Tiqn.2017-03.com.longshuai:test.disk1 -p 192.168.100.151:3260 -u
iscsiadm -m discovery -t st -p 192.168.100.151:3260
192.168.100.151:3260,1 iqn.2017-03.com.longshuai:test.disk1
iscsiadm -m node -Tiqn.2017-03.com.longshuai:test.disk1 -p 192.168.100.151:3260 -l
Logging in to [iface: default, target: iqn.2017-03.com.longshuai:test.disk1, portal: 192.168.100.151,3260] (multiple)
iscsiadm: Could not login to [iface: default, target: iqn.2017-03.com.longshuai:test.disk1, portal: 192.168.100.151,3260].
iscsiadm: initiator reported error (19 - encountered non-retryable iSCSI login failure)
iscsiadm: Could not log into all portals
它提示遇到不可重試的iscsi登入錯誤,因為target無法被initiator認證,initiator認為這個target是非法的target。
設定為正確的密碼然後再進行發現、關聯。
vim /etc/iscsi/iscsid.conf
node.session.auth.authmethod = CHAP
node.session.auth.username = incoming_malong
node.session.auth.password = incoming_123456
node.session.auth.username_in = outgoing_malong
node.session.auth.password_in = outgoing_123456
iscsiadm -m discovery -t st -p 192.168.100.151:3260
iscsiadm -m node -Tiqn.2017-03.com.longshuai:test.disk1 -p 192.168.100.151:3260 -l
4.5 係結多個outgoing賬號
tgtadm -L iscsi -m account -o new --user outgoing_user1 --password outgoing_passwd1
tgtadm -L iscsi -m account -o bind -t 1 --user outgoing_user1 --outgoing
tgtadm: this target already has an outgoing account
係結的時候提示已經有一個outgoing賬號,說明一個target的outgoing賬號只能有一個。也就是說,某一個target被認證的時候是1對多的關係。
但是incoming賬號並非如此。
4.6 係結多個incoming賬號
tgtadm -L iscsi -m account -o new --user incoming_user1 --password incoming_passwd1
tgtadm -L iscsi -m account -o new --user incoming_user2 --password incoming_passwd2
tgtadm -L iscsi -m account -o bind -t 1 --user incoming_user1
tgtadm -L iscsi -m account -o bind -t 1 --user incoming_user2
tgt-admin -s | sed -n '/Account/,$p'
Account information:
incoming_malong
incoming_user1
incoming_user2
outgoing_malong (outgoing)
ACL information:
192.168.100.0/24用伺服器C即192.168.100.6來登入一個看看。
vim /etc/iscsi/iscsid.conf
node.session.auth.authmethod = CHAP
node.session.auth.username = incoming_user1
node.session.auth.password = incoming_passwd1
node.session.auth.username_in = outgoing_malong
node.session.auth.password_in = outgoing_12345發現並關聯。
iscsiadm -m node -U all
iscsiadm -m discovery -t st -p 192.168.100.151:3260
iscsiadm -m node -T iqn.2017-03.com.longshuai:test.disk1 -p 192.168.100.151:3260 -l所以,incoming賬號可以有多個。
4.7 解綁和刪除使用者
先檢視下有目前有哪些使用者。
tgtadm -L iscsi -m account -o show
Account list:
outgoing_user1
incoming_user2
incoming_user1
outgoing_malong
incoming_malong再檢視下哪些使用者是已經系結到target上的。
tgt-admin -s | sed -n '/Account/,$p'
Account information:
incoming_malong
incoming_user1
incoming_user2
outgoing_malong (outgoing)
ACL information:
192.168.100.0/24對incoming_user1和incoming_user2進行解綁。
tgtadm -L iscsi -m account -o unbind -t 1 -u incoming_user1
tgtadm -L iscsi -m account -o unbind -t 1 -u incoming_user2對outgoing賬戶解綁。
tgtadm -L iscsi -m account -o unbind -t 1 -u outgoing_malong --outgoing刪除多餘的賬戶。
tgtadm -L iscsi -m account -o delete -u incoming_user1
tgtadm -L iscsi -m account -o delete -u incoming_user2
tgtadm -L iscsi -m account -o delete -u outgoing_malong
tgtadm -L iscsi -m account -o delete -u outgoing_user1
第5章 快速設定iscsi兩端
這裡是對前文的一個總結,用於解釋要使用iscsi時對target端和initiator大致需要做哪些事情。
#############################
# target端所需要做的事情
#############################
tgtadm -L iscsi -m target -o new -t 1 -T iqn.2017-03.com.longshuai:test1.disk1
tgtadm -L iscsi -m logicalunit -o new -t 1 -l 1 -b /dev/sdb1
tgtadm -L iscsi -m logicalunit -o new -t 1 -l 2 -b /dev/sdc
tgtadm -L iscsi -m target -o bind -t 1 -I 192.168.100.0/24
#如果要CHAP認證,則繼續新增相關賬戶和密碼並繫結到target上
tgtadm -L iscsi -m account -o new -u USERNAME -p PASSWORD
tgtadm -L iscsi -m account -o bind -t 1 -u USERNAME [--outgoing]
#最後將設定放入到組態檔中
sed -i -r 's/#include(.*)/include1/' /etc/tgt/targets.conf
mkdir /etc/tgt/temp
tgt-admin --dump | sed '/default/d' >/etc/tgt/temp/tgt1.conf
#不用重新啟動服務。
#如特殊情況,出現重新啟動tgtd伺服器但是組態檔不生效的情況,適應force-reload選項
#service tgtd force-reload
#############################
# initiator端所需要做的事情
#############################
#第一件事是決定是否要自定義initiator的名稱,如果需要自定義,則修改/etc/iscsi/initiatorname.iscsi檔案
#首先discovery目標主機上有哪些可用的target
iscsiadm -m discovery -t st -p 192.168.100.151:3260
# 然後登陸target
iscsiadm -m node -T iqn.2017-03.com.longshuai:test1.disk1 -p 192.168.100.151:3260 -l
#如果需要CHAP認證,則啟用/etc/iscsi/iscsid.conf中的相關CHAP認證指令
#前三項實現單向認證,target端認證initiator是否合法
#同時啟用這5項實現雙向認證,target端和initiator都會認證對方是否合法
node.session.auth.authmethod = CHAP
node.session.auth.username = incoming_malong
node.session.auth.password = incoming_123456
node.session.auth.username_in = outgoing_malong
node.session.auth.password_in = outgoing_123456
第6章 windows上設定initiator
在"執行"中輸入iscsicpl.exe
,開啟iscsi發起程式。
但要注意,Windows中格式化的NTFS檔案系統在Linux中預設是不支援的,所以iscsi的共用儲存不能跨Windows和Linux系統使用,除非安裝支援外掛。
本文永久更新連結地址:https://www.linuxidc.com/Linux/2018-05/152535.htm
相關文章