大旗号
科技 娱乐 汽车 财经 数码 时尚 旅游 美文 美食 其它

智汇华云 | 通过iscsi为容器提供存储

互联网科技 2022-02-08

介绍

将远端的存储通过iscsi协议为容器提供块存储,是一种通用的容器存储解决方案,下面将通过kubernetes中的in-tree方式来演示该例子,并分析其中的细节。


iSCSI协议是C/S架构,client是iSCSI initiator,server端为iSCSI target。iSCSI协议的主要功能是利用TCP/IP网络,在主机系统(可称为initiator)和目标存储设备(称为target)之间进行大量的数据封装和可靠传输过程。主要分成两个组成部分,分别为iSCSI服务器端和iSCSI客户端


iSCSI服务器端 (iSCSI Target)

iSCSI服务器端为iSCSI target,这是I/O操作的执行者。主要是为了导出一个或多个块设备供启动者(initiator)使用,可以通过硬件和软件的方式来实现。在Linux中可以使用scsi-target-utils软件包来模拟实现。在使用iSCSI时,会在 iSCSI 储存设备上去建立 LUN(Logical Unit Number)来提供给具备 iSCSI Initiator 功能的主机来存取 数据的。LUN 好比是个“逻辑单位磁碟”,物理上通常是由数个实体磁碟( RAID 或 LVM 技术的技术实现)所组成。LUN ID由iSCSI目标设备(Target)分配。iSCSI 启动端(Initiator)设备当前支持在每个目标设备(Target)中导出最多256个LUN。即最大支持16个target。

iSCSI target设备名称采用如下格式来命名:iqn..[:],需要事先进行配置,保证唯一性。


iSCSI客户端 (iSCSI Initiator)

iSCSI客户端为iSCSI initiator,这是I/O操作的发起者。是I/O操作的发起者,需要通过发现过程请求远端快设备。在Linux系统中可以通过软件来模拟,需要安装iSCSI设备驱动。如iscsi-initiator-utils。


实验

可以通过iSCSI将远程的磁盘分区映射到本地之后就可以像使用本地磁盘一样,将该远程盘进行格式化以及挂载操作,给容器使用。

我们通过 scsi-target-utils来实现iSCSI target,将主机上的/dev/sdb磁盘分区作为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节点上需要事先安装iscsi-initiator-utils,并且设置对应的initiatorname,如果开启了acl认证,需要将node节点的initiatorname添加到acl里面。


之后创建一个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可以运行在不同的节点上。

Step3: 基于iqn号获取lock,主要解决的场景为相同target下不同volume同时挂载或者login与logout操作并发进行,这个锁引入的目的主要是为了后面volume在Detach的时候,需要根据isSessionBusy来判断是否需要logout,断开node与target的所有链接。

Step4: GetISCSIPortalHostMapForTarget主要根据target iqn获取到login到该target上的scsi hosts number, 返回的结构为

{

    "192.168.30.7:3260": 2,

    "192.168.30.8:3260": 3,

}

通过这个map的引入后面用于判断是否需要login,还是直接通过scanOneLun()来发现接入的Lun,避免没有必要的login操作。scanOneLun之后会发现挂载到node上的device。

Step5: 根据volomeMode的类型是直接的PersistentVolumeBlock还是PersistentVolumeFileSystem模式,二者的区别在于是否需要对device进行格式化,创建文件系统,之后创建globalPDPath目录,目录位置采用如下格式

/var/lib/kubelet/plugins/kubernetes.io/iscsi/ /{ifaceName}/{portal-some_iqn-lun-lun_id},之后持久化的iscsi disk元数据到globalPDPath目录下iscsi.json,元数据主要用于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上的挂载信息,之后根据globalPDPath目录下iscsi.json元数据信息来完成TearDownDevice断开device,之后清理掉globalPDPath。


Step1: 根据mntPath挂载点信息获得device盘符,之后Unmount()掉挂载点信息

Step2:loadISCSI中根据mntPath获得该iscsi挂载信息的元数据信息,其中包括iqn iface volName initiatorName等信息

Step3: deleteDevices()中通过对device进行echo 1> delete操作,删除掉盘符

Step4: 基于iqn获取targetLocks.LockKey,之后判断该target在node上是否存在其他的盘挂载,如果没有存在,则进行iscsi logout操作,断开node与target之后的连接


总结

In-tree下的iscsi方式为容器提供iscsi的存储类似于静态供应,需要事先系统管理员创建好后端的iscsi存储,之后容器提供指定对应的配置来使用。对于已经存在支持iscsi协议挂载的后端存储,并且不具备动态功能csi插件的场景下具有一定的使用场景。





京东春晚大手笔,有何深意?
出品| 大力财经文 | 魏力摘要: 京东再度登场春晚,1亿份一分钱实物奖品、百台汽车等背后的商业策略揭秘!一年又一年,春晚又要来了,每年春晚的赞助商归属都是一个重磅的商业话题,毕竟春晚的流量在那里摆着呢,最著名的莫过于当年的红包大战,让两大平台狠

2024-02-08

创业再启航,锤子科技001号朱萧木开拓“减龄咖啡”赛道市场
文 发布 | 大力财经在创业的道路上,朱萧木从未停止过探索与创新的脚步。朱萧木,这位锤子科技的 001 号员工,一路走来,见证了企业的兴衰起伏,也完成了从产品经理到创业者的华丽转身。如今,他怀揣着一颗永不服输的心,毅然踏上了新的创业之旅——减龄咖啡

2024-02-08

字节跳动公益平台“公益聚力计划”上线
为更好地联合社会多方力量参与社会公益,字节跳动公益平台于近日正式推出“公益聚力计划”(以下简称“计划”)。“计划”支持公益项目的策划与筛选、公益机构撮合,以及多种定制化的产品功能,如定制版公益证书、爱心回礼、爱心留言等,可多样化满足高粉创作

2024-02-08

时代里的SHEIN卖家:在出海的浪头里追赶,创新,爆发
对于2020年就在跨境电商SHEIN上抓住出海商机、做成第一个创业项目的陈乔而言,这几年国内鼓励企业出海的政策指引是他人生翻身的“财神爷”,而海外广袤的消费市场就是他的“福地”了。陈乔原是就职在世界500强外企公司的一位部门中层。金领做了十几年,陈乔觉

2024-02-05

大小姐驾到!高德地图联合《王者荣耀》推出孙尚香导航语音包
“大小姐驾到!统统闪开!”如果你是一个手游爱好者,多半会对这句话耳熟能详,来自于国内手游界顶流《王者荣耀》中的高人气角色——孙尚香,并成为一代玩家们的记忆。如今,随着高德地图与《王者荣耀》达成合作,这句话又有了后半句:“大小姐驾到!统统闪开

2024-02-04

司机家宴、游园会、火车票礼包,滴滴陪司机师傅一起过大年
图为:上海滴滴司机师傅参与“写福字”活动  2024年春运已经开始,有司机师傅踏上了返乡之路,也有不少司机师傅仍然奔波在接送乘客的路上。为向辛勤出车的司机师傅致敬,也为返乡的司机师傅提供便利,滴滴在春节期间推出了返乡火车票购票奖励、司机家宴、游

2024-02-02

美团启动架构调整:聚力核心本地商业,提升科技与境外业务优先级
2月2日,美团CEO王兴发布内部邮件宣布新的组织架构调整。邮件显示,美团对核心本地商业相关多项业务进行了整合,并进一步提升了科技与国际化相关业务的优先级。在核心本地商业上,美团对过去相对独立的事业群进行了整合。主要调整包括:对到家事业群、到店事

2024-02-02

从异乡门到故乡门,百度地图车道级导航全程护航
2024春运已然开启,根据相关部门预测,今年春运自驾出行将备受青睐,预计80%的人次将选择自驾车出行。面对春运期间的大流量车流与极端雨雪天气的双重挑战,百度地图加速升级,将城市车道级导航覆盖范围从100城迅速扩至200城,让春节自驾之旅实现从异乡门到故

2024-02-02