
介紹
將遠(yuǎn)端的存儲(chǔ)通過(guò)iscsi協(xié)議為容器提供塊存儲(chǔ),是一種通用的容器存儲(chǔ)解決方案,下面將通過(guò)kubernetes中的in-tree方式來(lái)演示該例子,并分析其中的細(xì)節(jié)。

iSCSI協(xié)議是C/S架構(gòu),client是iSCSI initiator,server端為iSCSI target。iSCSI協(xié)議的主要功能是利用TCP/IP網(wǎng)絡(luò),在主機(jī)系統(tǒng)(可稱為initiator)和目標(biāo)存儲(chǔ)設(shè)備(稱為target)之間進(jìn)行大量的數(shù)據(jù)封裝和可靠傳輸過(guò)程。主要分成兩個(gè)組成部分,分別為iSCSI服務(wù)器端和iSCSI客戶端
iSCSI服務(wù)器端 (iSCSI Target)
iSCSI服務(wù)器端為iSCSI target,這是I/O操作的執(zhí)行者。主要是為了導(dǎo)出一個(gè)或多個(gè)塊設(shè)備供啟動(dòng)者(initiator)使用,可以通過(guò)硬件和軟件的方式來(lái)實(shí)現(xiàn)。在Linux中可以使用scsi-target-utils軟件包來(lái)模擬實(shí)現(xiàn)。在使用iSCSI時(shí),會(huì)在 iSCSI 儲(chǔ)存設(shè)備上去建立 LUN(Logical Unit Number)來(lái)提供給具備 iSCSI Initiator 功能的主機(jī)來(lái)存取 數(shù)據(jù)的。LUN 好比是個(gè)“邏輯單位磁碟”,物理上通常是由數(shù)個(gè)實(shí)體磁碟( RAID 或 LVM 技術(shù)的技術(shù)實(shí)現(xiàn))所組成。LUN ID由iSCSI目標(biāo)設(shè)備(Target)分配。iSCSI 啟動(dòng)端(Initiator)設(shè)備當(dāng)前支持在每個(gè)目標(biāo)設(shè)備(Target)中導(dǎo)出最多256個(gè)LUN。即最大支持16個(gè)target。
iSCSI target設(shè)備名稱采用如下格式來(lái)命名:iqn..[:],需要事先進(jìn)行配置,保證唯一性。
iSCSI客戶端 (iSCSI Initiator)
iSCSI客戶端為iSCSI initiator,這是I/O操作的發(fā)起者。是I/O操作的發(fā)起者,需要通過(guò)發(fā)現(xiàn)過(guò)程請(qǐng)求遠(yuǎn)端快設(shè)備。在Linux系統(tǒng)中可以通過(guò)軟件來(lái)模擬,需要安裝iSCSI設(shè)備驅(qū)動(dòng)。如iscsi-initiator-utils。
實(shí)驗(yàn)
可以通過(guò)iSCSI將遠(yuǎn)程的磁盤(pán)分區(qū)映射到本地之后就可以像使用本地磁盤(pán)一樣,將該遠(yuǎn)程盤(pán)進(jìn)行格式化以及掛載操作,給容器使用。
我們通過(guò) scsi-target-utils來(lái)實(shí)現(xiàn)iSCSI target,將主機(jī)上的/dev/sdb磁盤(pán)分區(qū)作為L(zhǎng)un,如下圖所示
[root@iscsi-server yum.repos.d]# tgtadm -L iscsi -o show -m target
Target 1: iqn.2021-11.com.huayun.san:123456
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
SWP: No
Thin-provisioning: No
Backing store type: null
Backing store path: None
Backing store flags:
LUN: 1
Type: disk
SCSI ID: IET 00010001
SCSI SN: beaf11
Size: 10737 MB, Block size: 512
Online: Yes
Removable media: No
Prevent removal: No
Readonly: No
SWP: No
Thin-provisioning: No
Backing store type: rdwr
Backing store path: /dev/vdb
Backing store flags:
Account information:
ACL information:
之后在kubernetes的node節(jié)點(diǎn)上需要事先安裝iscsi-initiator-utils,并且設(shè)置對(duì)應(yīng)的initiatorname,如果開(kāi)啟了acl認(rèn)證,需要將node節(jié)點(diǎn)的initiatorname添加到acl里面。
之后創(chuàng)建一個(gè)pod,其中指定一個(gè)存在的iscsi lun對(duì)接信息如下
apiVersion: v1
kind: Pod
metadata:
name: iscsipd
spec:
containers:
- name: iscsipd-rw
image: kubernetes/pause
volumeMounts:
- mountPath: "/mnt/iscsipd"
name: iscsipd-rw
volumes:
- name: iscsipd-rw
iscsi:
targetPortal: 10.0.2.15:3260
portals: ['10.0.2.16:3260', '10.0.2.17:3260']
iqn: iqn.2001-04.com.example:storage.kube.sys1.xyz
lun: 0
fsType: ext4
readOnly: true
之后可以看到遠(yuǎn)程的卷被成功的掛載到node上,被容器所使用


Volume.iscsi說(shuō)明
pod的spec中可以在volumes.iscsi中指定對(duì)接信息包括如下
iscsi.iqn | required,string | Target iSCSI Qualified Name. |
iscsi.lun | required,int32 | iSCSI Target Lun number. |
iscsi.targetPortal | required,string | iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260). |
iscsi.chapAuthDiscovery | bolean | whether support iSCSI Discovery CHAP authentication |
iscsi.chapAuthSession | boolean | whether support iSCSI Session CHAP authentication |
iscsi.fsType | string | Filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. |
iscsi.initiatorName | string | Custom iSCSI Initiator Name. If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface:will be created for the connection. |
iscsi.iscsiInterface | string | iSCSI Interface Name that uses an iSCSI transport. Defaults to 'default' (tcp). |
iscsi.portals | []string | iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260). |
iscsi.readOnly | boolean | ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. |
iscsi.secretRef | LocalObjectReference | CHAP Secret for iSCSI target and initiator authentication |
源碼分析
掛載階段
pod調(diào)度到某個(gè)node上,之后由kubelet中的volumemanager完成對(duì)于volume attach&mount操作,核心代碼位于kubernetes/pkg/volume/iscsi目錄下,在volume掛載的過(guò)程中,會(huì)首先調(diào)用WaitForAttach()完成掛載流程,SetUpDevice()掛載到某個(gè)容器所對(duì)應(yīng)的目錄。iscsiAttacher.WaitForAttach()流程如圖所示:

Step1: 通過(guò)iscsiadm -m iface -l b. InitIface -o show獲取對(duì)應(yīng)的iscsiTransport,如果不額外指定的話b. InitIface為default,iscsiTransport為tcp.
Step2: 如果pod的定義中指定iscsi.initiatorName ,則需要cloneIface(), 指定iscsi.initiatorName需要與node的不一致,這樣當(dāng)開(kāi)啟ACL initiatorName控制的時(shí)候,pod可以運(yùn)行在不同的節(jié)點(diǎn)上。
Step3: 基于iqn號(hào)獲取lock,主要解決的場(chǎng)景為相同target下不同volume同時(shí)掛載或者login與logout操作并發(fā)進(jìn)行,這個(gè)鎖引入的目的主要是為了后面volume在Detach的時(shí)候,需要根據(jù)isSessionBusy來(lái)判斷是否需要logout,斷開(kāi)node與target的所有鏈接。
Step4: GetISCSIPortalHostMapForTarget主要根據(jù)target iqn獲取到login到該target上的scsi hosts number, 返回的結(jié)構(gòu)為
{
"192.168.30.7:3260": 2,
"192.168.30.8:3260": 3,
}
通過(guò)這個(gè)map的引入后面用于判斷是否需要login,還是直接通過(guò)scanOneLun()來(lái)發(fā)現(xiàn)接入的Lun,避免沒(méi)有必要的login操作。scanOneLun之后會(huì)發(fā)現(xiàn)掛載到node上的device。
Step5: 根據(jù)volomeMode的類(lèi)型是直接的PersistentVolumeBlock還是PersistentVolumeFileSystem模式,二者的區(qū)別在于是否需要對(duì)device進(jìn)行格式化,創(chuàng)建文件系統(tǒng),之后創(chuàng)建globalPDPath目錄,目錄位置采用如下格式
/var/lib/kubelet/plugins/kubernetes.io/iscsi/ /{ifaceName}/{portal-some_iqn-lun-lun_id},之后持久化的iscsi disk元數(shù)據(jù)到globalPDPath目錄下iscsi.json,元數(shù)據(jù)主要用于DetachVolume的時(shí)候會(huì)涉及到,內(nèi)容如下所示:
{
"VolName":"iscsipd-rw",
"Portals":[
"178.104.162.58:3260",
],
"Iqn":"iqn.2021-11.com.huayun.san:123456",
"Lun":"1",
"InitIface":"default",
"Iface":"default",
"InitiatorName":"",
"MetricsProvider":null
}
在WaitForAttach 階段完成了device遠(yuǎn)端掛載、格式化以及掛載到globalPDPath目錄下,SetUpDevice流程較為簡(jiǎn)單主要是將globalPDPath mount –bind到容器對(duì)應(yīng)的目錄,之后對(duì)目錄進(jìn)行SetVolumeOwnership()操作。

卸載階段
pod銷(xiāo)毀的時(shí)候,會(huì)由kubelet完成volume的umount&detach操作,核心代碼位于kubernetes/pkg/volume/iscsi目錄下,主要完成umount node上的掛載信息,之后根據(jù)globalPDPath目錄下iscsi.json元數(shù)據(jù)信息來(lái)完成TearDownDevice斷開(kāi)device,之后清理掉globalPDPath。

Step1: 根據(jù)mntPath掛載點(diǎn)信息獲得device盤(pán)符,之后Unmount()掉掛載點(diǎn)信息
Step2:loadISCSI中根據(jù)mntPath獲得該iscsi掛載信息的元數(shù)據(jù)信息,其中包括iqn iface volName initiatorName等信息
Step3: deleteDevices()中通過(guò)對(duì)device進(jìn)行echo 1> delete操作,刪除掉盤(pán)符
Step4: 基于iqn獲取targetLocks.LockKey,之后判斷該target在node上是否存在其他的盤(pán)掛載,如果沒(méi)有存在,則進(jìn)行iscsi logout操作,斷開(kāi)node與target之后的連接
總結(jié)
In-tree下的iscsi方式為容器提供iscsi的存儲(chǔ)類(lèi)似于靜態(tài)供應(yīng),需要事先系統(tǒng)管理員創(chuàng)建好后端的iscsi存儲(chǔ),之后容器提供指定對(duì)應(yīng)的配置來(lái)使用。對(duì)于已經(jīng)存在支持iscsi協(xié)議掛載的后端存儲(chǔ),并且不具備動(dòng)態(tài)功能csi插件的場(chǎng)景下具有一定的使用場(chǎng)景。
轉(zhuǎn)自:中國(guó)網(wǎng)
【版權(quán)及免責(zé)聲明】凡本網(wǎng)所屬版權(quán)作品,轉(zhuǎn)載時(shí)須獲得授權(quán)并注明來(lái)源“中國(guó)產(chǎn)業(yè)經(jīng)濟(jì)信息網(wǎng)”,違者本網(wǎng)將保留追究其相關(guān)法律責(zé)任的權(quán)力。凡轉(zhuǎn)載文章及企業(yè)宣傳資訊,僅代表作者個(gè)人觀點(diǎn),不代表本網(wǎng)觀點(diǎn)和立場(chǎng)。版權(quán)事宜請(qǐng)聯(lián)系:010-65363056。
延伸閱讀

版權(quán)所有:中國(guó)產(chǎn)業(yè)經(jīng)濟(jì)信息網(wǎng)京ICP備11041399號(hào)-2京公網(wǎng)安備11010502035964