智匯華云 | 通過(guò)iscsi為容器提供存儲(chǔ)


時(shí)間:2022-02-08






介紹

將遠(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。

延伸閱讀

熱點(diǎn)視頻

突破6萬(wàn)億美元 2021年我國(guó)外貿(mào)進(jìn)出口規(guī)模再創(chuàng)歷史新高 突破6萬(wàn)億美元 2021年我國(guó)外貿(mào)進(jìn)出口規(guī)模再創(chuàng)歷史新高

熱點(diǎn)新聞

熱點(diǎn)輿情

?

微信公眾號(hào)

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