为了将业务组件完全容器化,验证在docker容器中执行iscsi挂载、卸载操作时,物理机上能否挂载、卸载对应的设备,以及当操作容器退出时是否会导致iscsi连接不可用。

iSCSI容器化方案

通常情况下开源的 open-iscsi 包括以下两个组件:

  • iscsiadm: iSCSI的客户端工具
  • iscsid: iSCSI守护进程

上述两个工具配合Linux内核中的iscsi模块,用户可以进行iSCSI LUN的挂载卸载等操作。

iscsiadm和iscsid通过指定的Unix domain socket进行通讯,Centos7中默认情况下着这些socket连接保存在**/etc/systemd/system/sockets.target.wants/**目录下。

iscsid和iscsi内核通过netlink机制进行通信,这是一种特殊的socket。

在容器中运行iSCSI组件时,有以下方案:

1.完全容器化

iscsid 和 iscsiadm 完全安装在容器中,通过 SYS_MODULE 开关让容器加载系统内核,并将容器运行在系统网络命名空间。 这种场景下需要完全卸载物理上的iscsid相关组件防止,iscsi内核和iscsid服务通信时发生冲突。

部分操作系统是自带 iscsi-initiator-tools 或者 open-iscsi 的,这种情况要先卸载这些应用。

2.iscsiadm容器化

在物理机上安装open-iscsi服务,iscsid进程运行在物理机上,而管理命令行iscsiadm使用容器自带的发行版,容器运行在系统网络命名空间。

iscsid和iscsiadm可能出现版本兼容性的问题。

3.挂载iscsiadm

将物理机上的iscsiadm挂载到容器内,其余配置"iscsiadm容器化"的方案一致。这样能够保证iscsid和iscsiadm不会出现兼容性问题。

可以在以下POD中执行iscsiadm挂载、卸载等操作,并且即使容器消亡也不会影响iscsi的连接。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: iscsi-utils
spec:
  selector:
    matchLabels:
      app: iscsi-utils
  template:
    metadata:
      labels:
        app: iscsi-utils
    spec:
      containers:
      - name: iscsi
        image: centos:centos7.9.2009
        command:
        - sleep
        - inf
        imagePullPolicy: IfNotPresent
        securityContext:
          allowPrivilegeEscalation: true
          capabilities:
            add:
            - SYS_ADMIN
          privileged: true
        volumeMounts:
        - mountPath: /etc/localtime
          name: timezone
        - mountPath: /dev
          name: host-dev
        - mountPath: /sys
          name: host-sys
        - mountPath: /run/mount
          name: host-mount
        - mountPath: /lib/modules
          name: lib-modules
          readOnly: true
        - mountPath: /etc/iscsi
          name: iscsi-config
          readOnly: true
        - mountPath: /usr/sbin/iscsiadm
          name: iscsi-bin
          readOnly: true
      dnsPolicy: ClusterFirstWithHostNet
      hostNetwork: true
      hostPID: true
      volumes:
      - hostPath:
          path: /dev
          type: ""
        name: host-dev
      - hostPath:
          path: /sys
          type: ""
        name: host-sys
      - hostPath:
          path: /run/mount
          type: ""
        name: host-mount
      - hostPath:
          path: /lib/modules
          type: ""
        name: lib-modules
      - hostPath:
          path: /etc/localtime
          type: ""
        name: timezone
      - hostPath:
          path: /etc/iscsi
          type: "DirectoryOrCreate"
        name: iscsi-config
      - hostPath:
          path: /usr/sbin/iscsiadm
          type: "File"
        name: iscsi-bin

附录:iSCSI Server

Linux系统中可以使用targetcli工具创建iSCSI服务端target,用户可以参考一下命令安装targetcli

1
yum -y install  targetcli

targetcli 基于目录树管理,安装好之后用户执行 targetcli 即可进入对应的目录系统。

ps:默认情况下 targetcli 只允许单个用户登录

上述截图中执行ls,可以看到target的目录结构:

  • backstores:该目录中block、fileio、pscsi、ramdisk均表示不同类型后端存储(lun)

    • block:配置块设备目录,可以是物理磁盘、分区、逻辑卷、多路径设备等
    • fileio:配置文件目录,一般是稀疏文件
    • ramdisk:配置内存存储目录
    • pscsi:配置物理scsi设备目录
  • iscsi:iscsi配置目录

创建基于稀疏文件的backstores(可以理解为创建lun):

1
2
truncate -s 1g /opt/disk1 
targetcli /backstores/fileio create name=lun1 file_or_dev=/opt/disk1

创建iscsi target,注意服务端initiator名称格式为:iqn.yyyy-mm.naming-authority:unique-name,其中naming-authority通常是公司的 Internet 域名的逆转格式,unique-name可以是任意唯一标识

1
2
3
4
5
6
7
8
9
# 创建iSCSI target
targetcli /iscsi create iqn.2021-12.cn.yoaz.iscsi:target-0-1-0
# 关联后端存储
targetcli /iscsi/iqn.2021-12.cn.yoaz.iscsi:target-0-1-0/tpg1/luns create /backstores/fileio/lun1
# 设置访问权限,只允许指定iqn标识initiator连接
targetcli /iscsi/iqn.2021-12.cn.yoaz.iscsi:target-0-1-0/tpg1/acls create iqn.1994-05.com.redhat:f9a39634a761

# 保存配置到 /etc/target/saveconfig.json,开机时可以通过 targetcli / restoreconfig 重新加载
targetcli / saveconfig

创建完成后目录结构如下:

img.png

附录:iSCSI 常用命令

1
2
3
4
5
6
7
8
# 发现
iscsiadm --mode discovery --type sendtargets --portal 172.17.151.86
# 挂载
iscsiadm --mode node -T iqn.2021-12.cn.yoaz.iscsi:target-0-1-0 -p 172.17.151.86 --login 
# 卸载
iscsiadm --mode node -T iqn.2021-12.cn.yoaz.iscsi:target-0-1-0 -p 172.17.151.86 --logout
# 清除记录
iscsiadm --mode node -o delete -T iqn.2021-12.cn.yoaz.iscsi:target-0-1-0

参考

https://www.cnblogs.com/pipci/p/11620234.html

https://www.docker.com/blog/road-to-containing-iscsi/

http://linux.51yip.com/search/iscsiadm