概述
對於ZFS我是一直在強烈推薦的,因為實在太好用了。但是直到現在,它還是只能運行於Oracle的Solaris和FreeBSD兩個系統上,為了將它分享給別的系統只能通過NAS或SAN的方式。
NAS的方式很簡單,我一直在用Samba實現,當然NFS也是可以的,SAN的話之前還沒試過。使用上當然是SAN更好一些,而且現在網速也夠快。雖然對於儲存來說,NAS和SAN都是外部儲存,但對於客戶機來說,它知道NAS是網路裝置,而SAN則會被視同本地裝置,這是二者的主要區別。之所以會這樣,是因為NAS走的是網路層的協議,SAN走的是更底層的塊裝置協議。
傳統上SAN都是比較高大上的,因為都是走光纖通道(FC),直到後來有了iSCSI這個大救星——使用iSCSI的SAN又被稱為IP-SAN。而且有了iSCSI以後,NAS和SAN的區別已經不那麼明顯了,因為現在有一些NAS裝置也提供iSCSI支援。
不過要注意一點:正因為NAS是走網路通訊協定,所以對客戶機來說,是以通用的網路檔案系統方式訪問,不需要關注服務端是用什麼具體的檔案系統,這也就意味著在不同系統中可以共用NAS中的檔案。比如我現在就是在服務端用ZFS格式存放檔案,通過SAMBA共用給Linux、Mac和Windows,在四個完全不同的系統中訪問共用檔案都沒有問題。但是SAN是走底層塊裝置協議,所以是客戶機獨用的,Linux用的target不能與Windows共用(格式化後的檔案系統不同),同樣在服務端也無法直接看到相應target裡的具體內容(可以通過服務端的本地Initiator串連後mount為指定檔案系統操作,但也僅限於服務端本身支援的檔案系統格式)。
之前版本的FreeBSD雖然也支援iSCSI,但是是一個使用者級的應用,個人感覺不好,所以沒試過。在最新的FreeBSD 10中,iSCSI被整合到系統中去了,這真是個喜大普奔的好訊息,最近試了一下感覺還不錯。
關於iSCSI的基本原理大致是這樣:iSCSI本身是一個協議,是一個在IP網路上的虛擬SCSI實現。用戶端能過iSCSI Initiator類比一個本地的塊裝置(可以理解為一個虛擬SCSI硬碟),然後由iSCSI Initiator把收到的SCSI指令通過IP網路傳遞到服務端,服務端的再將相應的指令轉為對實際硬碟的操作。
在服務端(即儲存端)有一些物理或邏輯硬碟,被組織成所謂的LUN(邏輯單元編號),可以理解為一種邏輯卷,比如一塊硬碟,一個分區,一組RAID,或是一個ZFS。當這個儲存端把這些LUN通過iSCSI對外提供儲存服務的時候,我們叫它iSCSI target。同時,在儲存端上可以通過多種途徑對外提供服務,比如通過不同的IP,不同的網卡,不同的身份認證方式等,每一種途徑叫做一個portal group。portal group和target可以自由組合,以滿足用戶端的各種儲存需求。
在用戶端,則是通過前面所說的iSCSI Initiator實現,它在本地表現為一個虛擬硬碟(在/dev下有裝置名稱,但沒有實際的物理裝置),對它的所有操作都會被通過iSCSI傳遞到對應的iSCSI target上去。
iSCSI target
首先在服務端建立一個ZFS供target之用:
zfs create -s -V 4G -b 4k tank/testtarget
注意需要-V參數才能在/dev/zvol下建立相應的塊裝置供iSCSI之用。-V表示建立ZFS卷,-s表示不在建立時分配空間,不加此參數則會建立一個實際佔用指定容量的卷。-b指定塊大小(即傳統意義上的扇區大小,一般用4096或512)。
然後在 /etc/rc.conf 裡加入以下一行啟用ctld(iSCSI服務):
ctld_enable="YES"
接著是配置ctld,建立 /etc/ctl.conf 檔案,內容為:
portal-group san { discovery-auth-group no-authentication listen 192.168.x.x}target iqn.2014-05.com.example:target0 { auth-group no-authentication portal-group san lun 0 { path /dev/zvol/tank/testtarget blocksize 4096 size 4G }}
這是最簡單的配置,只有一個target和一個portal group。沒有使用使用者認證。作為測試已經足夠了。
然後就可以啟動這個target了:
chmod 600 /etc/ctl.confservice ctld start
注意那個chmod的步驟是必須的,否則服務無法啟動,因為一個全域可讀的設定檔是不安全的。
啟動完可以看一下日誌,以確定沒有出錯。
tail /var/log/messages
iSCSI initiator
一般不拿FreeBSD做用戶端,只是有時會需要在服務端測試一下target的配置,所以可能還是會用到FreeBSD下的Initiator的,所以記錄了一下配置方法附後供參考。本節以實際的案頭環境配置為例。
我的案頭是Linux Mint 16,以下供參考。不過不同的Linux發行版應該都差不多。Mac貌似需要商業軟體支援,沒法介紹。微軟有為Windows免費提供相關的Initiator軟體(高版本Windows已內建),配置方法附後。
首先需要安裝軟體:
sudo apt-get install open-iscsi open-iscsi-utils
然後啟動服務:
sudo service open-iscsi start
然後搜尋一下target :
sudo iscsiadm -m discovery -t sendtargets -p 192.168.x.x
在結果中可以看到之前配置好的target。
登入串連target:
sudo iscsiadm -m node -T iqn.2014-05.com.example:target0 -p 192.168.x.x -l
現在開啟系統喜好設定-磁碟(或你的發行版上的相關工具,或者你習慣用命令列也行),即可看到一個新增的磁碟(在我的電腦上,它的裝置名稱叫/dev/sdc),磁碟名叫做FREEBSD CTLDISK,處於未格式化狀態。用EXT4格式化,再mount即可像本地碟一樣直接使用了。
至此一個基本的基於ZFS的iSCSI服務就算搭建完成。
更複雜的應用
前面說的target配置是全開放的,整個網段內所有用戶端都可以自由串連,為了安全起見,需要加入使用者認證。
最簡單的方法就是在target配置裡加入使用者名稱密碼:
target iqn.2014-05.com.example:target0 { portal-group san chap user password1234 lun 0 { path /dev/zvol/tank/testtarget blocksize 4096 size 4G }}
注意,其中密碼預設需要不少於12位。但是如果有多個使用者需要使用的話,這樣就不方便了,這時就需要使用auth-group:
auth-group ag0 { chap user1 password1234 chap user2 password1234}target iqn.2014-05.com.example:target0 { auth-group ag0 portal-group san lun 0 { path /dev/zvol/tank/testtarget blocksize 4096 size 4G }}
現在在initiator端同樣需要指定使用者名稱密碼才能串連了。但是使用者名稱密碼並不是在命令列裡輸入,而是需要配置給open-iscsi服務。修改/etc/iscsi/iscsid.conf,加入:
node.startup = automaticnode.session.auth.authmethod = CHAPnode.session.auth.username = usernode.session.auth.password = password1234
其中node.startup設定為automatic是為了讓initiator自動連接。這項並不是必須的,它的預設值是manual,即需要手動串連target,設定為automatic即可在系統重啟後自動連接target,而不需要再手工運行iscsiadm去串連。
node.session.auth的username和password就是前面配置的target的使用者名稱和密碼。同理,如果配置了portal group的使用者認證,也可以在這裡配置discovery的使用者名稱和密碼。
然後重啟open-iscsi服務:
sudo service open-iscsi restart
現在再執行:
sudo iscsiadm -m node -T iqn.2014-05.com.example:target0 -p 192.168.x.x -l
即可登入串連target。串連後即可mount使用。
如果像前面那樣把node.startup配置為automatic,則啟動後會自動連接,只需要直接mount或如下配置成自動mount:
先取得UUID:
sudo blkid /dev/sdc
或者用/dev/disk/py-path/方式的路徑,然後把它配置到fstab裡(以by-path路徑為例,以UUID方式參見fstab中的預設配置):
/dev/disk/by-path/ip-192.168.x.x:3260-iscsi-iqn.2014-05.com.example:target0-lun-0 /mnt/iscsi ext4 _netdev,errors=remount-ro 0 1
注意,選項裡必須有_netdev一項否則在啟動時會等待很長時間後mount失敗。
試試ZFS
可以注意到,前面有一個步驟是用戶端需要對target進行格式化,我是格式化為EXT4格式的,那麼服務端的ZFS還有效嗎?可以來試試。
首先在mount好的路徑裡建立一些檔案,然後到服務端做個快照:
zfs snapshot tank/testtarget@test1
然後再回到用戶端,把相關的檔案刪除或修改,然後umount並斷開(否則不能對服務端ZFS作修改操作):
sudo umount /dev/sdcsudo iscsiadm -m node -T iqn.2014-05.com.example:target0 -p 192.168.x.x -u
然後在服務端把iSCSI服務給停了:
service ctld stop
現在可以試試復原快照——當然也可以做一個複製,然後把target指向複製,這裡以簡單的復原操作為例:
zfs rollbak tank/testtarget@test1
再重啟服務:
service ctld start
用戶端重新串連:
sudo iscsiadm -m node -T iqn.2014-05.com.example:target0 -lsudo mount /dev/sdc /mnt/iscsi
現在再看之前修改過或刪除掉的檔案又恢複原狀了。可見ZFS卷同樣可以實現ZFS的功能,並不會因為它被格式化為EXT4而失效。
附:FreeBSD下的Initiator配置
首先啟動 iscsid 服 務。因為通常情況下只是測試一下,可以直接用iscsid命令啟動服務,因為用service命令啟動的話還需要配置rc.conf,而且即使是直接啟動也可以用service命令停止它。
然後用串連target:
iscsictl -A -p 192.168.x.x -t iqn.2014-05.com.example:target0
然後用不帶參數的iscsictl看一下串連狀態和裝置名稱。注意:如果狀態顯示為Waiting for iscsid(8),則說明iscsid服務未啟動。
沒問題的話就:
mount -t fstype /dev/da0 /mnt/iscsi
其中fstype為檔案系統名,da0為串連後的裝置名稱。
附:Windows的Initiator配置
因為Mac不能用,鬱悶之餘看了一下Windows的配置,發現還是挺簡單的,連重啟都不用。
首先在微軟官網下載:Microsoft iSCSI initiator
然後安裝之。注意,需要開啟MS DTC服務。
安裝後運行之,在[Discovery]頁的[Target Portals]一欄裡點[Add],輸入Portal的IP地址或DNS名稱,比如:192.168.x.x。
確定後在[Targets]頁裡即可看到服務端配置的targets,選擇之,然後點[Log On],其狀態會從Inactive變成Connected。注意這時有個選項叫“Automatically restore this connection when the system boots”,選中之可以在系統啟動時自動連接。
現在開啟系統管理中的磁碟管理,就會彈出提示說系統中多了一塊硬碟,選擇之並格式化為你想要的檔案系統格式,比如FAT32或NTFS,之後就可以像普通硬碟一樣使用它了。