介紹
將遠端的存儲通過iscsi協(xié)議為容器提供塊存儲,是一種通用的容器存儲解決方案,下面將通過kubernetes中的in-tree方式來演示該例子,并分析其中的細節(jié)。
iSCSI協(xié)議是C/S架構,client是iSCSI initiator,server端為iSCSI target。iSCSI協(xié)議的主要功能是利用TCP/IP網絡,在主機系統(tǒng)(可稱為initiator)和目標存儲設備(稱為target)之間進行大量的數(shù)據(jù)封裝和可靠傳輸過程。主要分成兩個組成部分,分別為iSCSI服務器端和iSCSI客戶端
iSCSI服務器端 (iSCSI Target)
iSCSI服務器端為iSCSI target,這是I/O操作的執(zhí)行者。主要是為了導出一個或多個塊設備供啟動者(initiator)使用,可以通過硬件和軟件的方式來實現(xiàn)。在Linux中可以使用scsi-target-utils軟件包來模擬實現(xiàn)。在使用iSCSI時,會在 iSCSI 儲存設備上去建立 LUN(Logical Unit Number)來提供給具備 iSCSI Initiator 功能的主機來存取 數(shù)據(jù)的。LUN 好比是個“邏輯單位磁碟”,物理上通常是由數(shù)個實體磁碟( RAID 或 LVM 技術的技術實現(xiàn))所組成。LUN ID由iSCSI目標設備(Target)分配。iSCSI 啟動端(Initiator)設備當前支持在每個目標設備(Target)中導出最多256個LUN。即最大支持16個target。
iSCSI target設備名稱采用如下格式來命名:iqn..[:],需要事先進行配置,保證唯一性。
iSCSI客戶端 (iSCSI Initiator)
iSCSI客戶端為iSCSI initiator,這是I/O操作的發(fā)起者。是I/O操作的發(fā)起者,需要通過發(fā)現(xiàn)過程請求遠端快設備。在Linux系統(tǒng)中可以通過軟件來模擬,需要安裝iSCSI設備驅動。如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: IET00010000
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: IET00010001
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,并且設置對應的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調度到某個node上,之后由kubelet中的volumemanager完成對于volume attach&mount操作,核心代碼位于kubernetes/pkg/volume/iscsi目錄下,在volume掛載的過程中,會首先調用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,返回的結構為
{
"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的時候會涉及到,內容如下所示:
{
"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之后的連接
總結
In-tree下的iscsi方式為容器提供iscsi的存儲類似于靜態(tài)供應,需要事先系統(tǒng)管理員創(chuàng)建好后端的iscsi存儲,之后容器提供指定對應的配置來使用。對于已經存在支持iscsi協(xié)議掛載的后端存儲,并且不具備動態(tài)功能csi插件的場景下具有一定的使用場景。
(免責聲明:本網站內容主要來自原創(chuàng)、合作伙伴供稿和第三方自媒體作者投稿,凡在本網站出現(xiàn)的信息,均僅供參考。本網站將盡力確保所提供信息的準確性及可靠性,但不保證有關資料的準確性及可靠性,讀者在使用前請進一步核實,并對任何自主決定的行為負責。本網站對有關資料所引致的錯誤、不確或遺漏,概不負任何法律責任。
任何單位或個人認為本網站中的網頁或鏈接內容可能涉嫌侵犯其知識產權或存在不實內容時,應及時向本網站提出書面權利通知或不實情況說明,并提供身份證明、權屬證明及詳細侵權或不實情況證明。本網站在收到上述法律文件后,將會依法盡快聯(lián)系相關文章源頭核實,溝通刪除相關內容或斷開相關鏈接。 )