介紹
將遠端的存儲通過iscsi協(xié)議為容器提供塊存儲,是一種通用的容器存儲解決方案,下面將通過kubernetes中的in-tree方式來演示該例子,并分析其中的細節(jié)。
iSCSI協(xié)議是C/S架構(gòu),client是iSCSI initiator,server端為iSCSI target。iSCSI協(xié)議的主要功能是利用TCP/IP網(wǎng)絡(luò),在主機系統(tǒng)(可稱為initiator)和目標存儲設(shè)備(稱為target)之間進行大量的數(shù)據(jù)封裝和可靠傳輸過程。主要分成兩個組成部分,分別為iSCSI服務器端和iSCSI客戶端
iSCSI服務器端 (iSCSI Target)
iSCSI服務器端為iSCSI target,這是I/O操作的執(zhí)行者。主要是為了導出一個或多個塊設(shè)備供啟動者(initiator)使用,可以通過硬件和軟件的方式來實現(xiàn)。在Linux中可以使用scsi-target-utils軟件包來模擬實現(xiàn)。在使用iSCSI時,會在 iSCSI 儲存設(shè)備上去建立 LUN(Logical Unit Number)來提供給具備 iSCSI Initiator 功能的主機來存取 數(shù)據(jù)的。LUN 好比是個“邏輯單位磁碟”,物理上通常是由數(shù)個實體磁碟( RAID 或 LVM 技術(shù)的技術(shù)實現(xiàn))所組成。LUN ID由iSCSI目標設(shè)備(Target)分配。iSCSI 啟動端(Initiator)設(shè)備當前支持在每個目標設(shè)備(Target)中導出最多256個LUN。即最大支持16個target。
iSCSI target設(shè)備名稱采用如下格式來命名:iqn..[:],需要事先進行配置,保證唯一性。
iSCSI客戶端 (iSCSI Initiator)
iSCSI客戶端為iSCSI initiator,這是I/O操作的發(fā)起者。是I/O操作的發(fā)起者,需要通過發(fā)現(xiàn)過程請求遠端快設(shè)備。在Linux系統(tǒng)中可以通過軟件來模擬,需要安裝iSCSI設(shè)備驅(qū)動。如iscsi-initiator-utils。
實驗
可以通過iSCSI將遠程的磁盤分區(qū)映射到本地之后就可以像使用本地磁盤一樣,將該遠程盤進行格式化以及掛載操作,給容器使用。
我們通過 scsi-target-utils來實現(xiàn)iSCSI target,將主機上的/dev/sdb磁盤分區(qū)作為Lun,如下圖所示
[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é)點上需要事先安裝iscsi-initiator-utils,并且設(shè)置對應的initiatorname,如果開啟了acl認證,需要將node節(jié)點的initiatorname添加到acl里面。
之后創(chuàng)建一個pod,其中指定一個存在的iscsi lun對接信息如下
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
之后可以看到遠程的卷被成功的掛載到node上,被容器所使用
Volume.iscsi說明
pod的spec中可以在volumes.iscsi中指定對接信息包括如下
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)度到某個node上,之后由kubelet中的volumemanager完成對于volume attach&mount操作,核心代碼位于kubernetes/pkg/volume/iscsi目錄下,在volume掛載的過程中,會首先調(diào)用WaitForAttach()完成掛載流程,SetUpDevice()掛載到某個容器所對應的目錄。iscsiAttacher.WaitForAttach()流程如圖所示:
Step1: 通過iscsiadm -m iface -l b. InitIface -o show獲取對應的iscsiTransport,如果不額外指定的話b. InitIface為default,iscsiTransport為tcp.
Step2: 如果pod的定義中指定iscsi.initiatorName ,則需要cloneIface(), 指定iscsi.initiatorName需要與node的不一致,這樣當開啟ACL initiatorName控制的時候,pod可以運行在不同的節(jié)點上。
Step3: 基于iqn號獲取lock,主要解決的場景為相同target下不同volume同時掛載或者login與logout操作并發(fā)進行,這個鎖引入的目的主要是為了后面volume在Detach的時候,需要根據(jù)isSessionBusy來判斷是否需要logout,斷開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,
}
通過這個map的引入后面用于判斷是否需要login,還是直接通過scanOneLun()來發(fā)現(xiàn)接入的Lun,避免沒有必要的login操作。scanOneLun之后會發(fā)現(xiàn)掛載到node上的device。
Step5: 根據(jù)volomeMode的類型是直接的PersistentVolumeBlock還是PersistentVolumeFileSystem模式,二者的區(qū)別在于是否需要對device進行格式化,創(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的時候會涉及到,內(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遠端掛載、格式化以及掛載到globalPDPath目錄下,SetUpDevice流程較為簡單主要是將globalPDPath mount –bind到容器對應的目錄,之后對目錄進行SetVolumeOwnership()操作。
卸載階段
pod銷毀的時候,會由kubelet完成volume的umount&detach操作,核心代碼位于kubernetes/pkg/volume/iscsi目錄下,主要完成umount node上的掛載信息,之后根據(jù)globalPDPath目錄下iscsi.json元數(shù)據(jù)信息來完成TearDownDevice斷開device,之后清理掉globalPDPath。
Step1: 根據(jù)mntPath掛載點信息獲得device盤符,之后Unmount()掉掛載點信息
Step2:loadISCSI中根據(jù)mntPath獲得該iscsi掛載信息的元數(shù)據(jù)信息,其中包括iqn iface volName initiatorName等信息
Step3: deleteDevices()中通過對device進行echo 1> delete操作,刪除掉盤符
Step4: 基于iqn獲取targetLocks.LockKey,之后判斷該target在node上是否存在其他的盤掛載,如果沒有存在,則進行iscsi logout操作,斷開node與target之后的連接
總結(jié)
In-tree下的iscsi方式為容器提供iscsi的存儲類似于靜態(tài)供應,需要事先系統(tǒng)管理員創(chuàng)建好后端的iscsi存儲,之后容器提供指定對應的配置來使用。對于已經(jīng)存在支持iscsi協(xié)議掛載的后端存儲,并且不具備動態(tài)功能csi插件的場景下具有一定的使用場景。
轉(zhuǎn)自:中國網(wǎng)
【版權(quán)及免責聲明】凡本網(wǎng)所屬版權(quán)作品,轉(zhuǎn)載時須獲得授權(quán)并注明來源“中國產(chǎn)業(yè)經(jīng)濟信息網(wǎng)”,違者本網(wǎng)將保留追究其相關(guān)法律責任的權(quán)力。凡轉(zhuǎn)載文章及企業(yè)宣傳資訊,僅代表作者個人觀點,不代表本網(wǎng)觀點和立場。版權(quán)事宜請聯(lián)系:010-65363056。
延伸閱讀