本文永久链接: https://www.xtplayer.cn/rancher/rancher-k8s-use-iscsi-storage/

iSCSI 命名约定

iSCSI 使用一种特殊、唯一的名称来标识 iSCSI 节点(目标或启动器)。此名称类似于与光纤通道设备相关联的全球名称 (WWN),可作为一种通用的节点识别方式使用。iSCSI 名称通过两种不同方式格式化。最常见的是 IQN 格式。有关 iSCSI 命名要求和字符串配置文件的更多详细信息,请参见 IETF 网站上的 RFC 3721 和 RFC 3722。

iSCSI 限定名 (IQN) 格式

IQN 格式采用 iqn.yyyy-mm.naming-authority:unique name 的形式,其中:

  • yyyy-mm 是命名机构成立的年份和月份。

  • naming-authority 通常是命名机构的 Internet 域名的反向语法。例如,iscsi.vmware.com 命名机构的 iSCSI 限定名形式可能是 iqn.1998-01.com.vmware.iscsi。此名称表示 vmware.com 域名于 1998 年 1 月注册,iscsi 是一个由 vmware.com 维护的子域。

  • unique name 是希望使用的任何名称,如主机的名称。命名机构必须确保在冒号后面分配的任何名称都是唯一的,

    例如:

iqn.1998-01.com.vmware.iscsi:name1

iqn.1998-01.com.vmware.iscsi:name2

iqn.1998-01.com.vmware.iscsi:name999

企业唯一标识符 (EUI) 格式

EUI 格式采用 eui.16 hex digits 的形式。例如: eui.0123456789ABCDEF。

16 位十六进制数字是 IEEE EUI(扩展唯一标识符)格式的 64 位数的文本表示形式。前 24 位是 IEEE 向特定公司注册的公司 ID。后 40 位由持有该公司 ID 的实体分配,并且必须是唯一的。

更新 Kubernetes 集群(可选)

Rancher 安装的 Kubernetes 集群,利用 iSCSI 启动器工具在 iSCSI 卷上存储数据,该工具嵌入在 kubelet 的 rancher/hyperkubeDocker 镜像中。在某些情况下,安装在 kubelet 容器中的启动器和 iscsi 服务器版本可能不匹配,从而导致连接失败。

如果遇到此问题,可以将集群中每个节点上安装启动器工具,然后将启动器工具映射到 kubelet 容器来解决版本问题。

平台包裹名字安装命令
Ubuntu/Debianopen-iscsisudo apt install open-iscsi
RHELiscsi-initiator-utilsyum install iscsi-initiator-utils -y

在节点上安装启动器工具后,编辑集群 YAML,编辑 kubelet 配置挂载主机 SCSI 二进制文件和配置目录,如下面的示例所示。

在更新 Kubernetes YAML 之前,请确保在集群节点上安装了 open-iscsi(deb)或 iscsi-initiator-utils(yum)软件包。如果在 Kubernetes YAML 中创建绑定挂载 之前 未安装此软件包,Docker 将自动在每个节点上创建目录和文件。

services:
kubelet:
extra_binds:
- "/etc/iscsi:/etc/iscsi"
- "/sbin/iscsiadm:/sbin/iscsiadm"

创建 ISCSI 服务器

操作系统以为 centos7.6 为例

主机名配置IP 地址角色操作系统用户操作系统
iscsi-target-server2C4G1.1.1.47iSCSI Targetrootcentos
iscsi-target-agent-1.1.1.46iSCSI Initiatorrootcentos

注意:以上配置仅用于本次文档演示

iSCSI Target 服务器搭建

  1. 基础环境配置

    # 禁止 selinux
    setenforce 0 # 临时禁止,重启后恢复
    sudo sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config # 永久禁止,需要重启服务器
    # 关闭防火墙
    systemctl disable firewalld.service \
    && systemctl stop firewalld.service
    # 安装 ntp 时间同步服务器
    yum install ntp -y \
    && systemctl enable ntpd.service \
    && systemctl start ntpd.service
  2. 安装 iSCSI target 管理工具

    yum install targetcli.noarch -y \
    && systemctl enable target.service \
    && systemctl start target.service
  3. 创建一个用于存放磁盘文件的目录,比如 /iscsi_disks

    mkdir /iscsi_disks
  4. 进入 target 管理命令行

    targetcli
  5. 创建磁盘镜像

    iscsi 支持多种存储对象,可以通过 ls /backstores/ 查看,这里演示选择文件存储 fileio,如果用于生产建议选择块设备 block

    # 创建磁盘镜像
    cd /backstores/fileio
    create disk01 /iscsi_disks/disk01.img 10G
  6. 创建 target

    cd /iscsi
    create iqn.2019-05.com.example:servers1
  7. 创建 LUN

    cd /iscsi/iqn.2019-05.com.example:servers1/tpg1/luns
    create /backstores/fileio/disk01
  8. (可选)配置 ACL,限制哪些客户端能连接

    cd /iscsi/iqn.2019-05.com.example:servers1/tpg1/acls
    create iqn.2019-05.com.example:agent1
  9. 配置通信身份验证

    • 单向登录认证

      cd /iscsi/iqn.2019-05.com.example:servers1/tpg1/

      # 开启 tpg1 级别的登录认证
      set attribute authentication=1

      # 启用 read/write 模式
      set attribute demo_mode_write_protect=0
      set attribute generate_node_acls=1

      # 配置 tpg1 级别的登录认证
      set attribute authentication=1
      set auth userid=agent_login_user1 # 传入账号,也就是客户端访问服务端认证使用的账号
      set auth password=agent_login_passwd1 #传入账号对应的密码

      # 配置 acls 级别的登录认证
      cd /iscsi/iqn.2019-05.com.example:servers1/tpg1/acls/iqn.2019-05.com.example:agent1
      set auth userid=agent_login_user1 # 传入账号,也就是客户端访问服务端认证使用的账号
      set auth password=agent_login_passwd1 #传入账号对应的密码
    • 双向登录认证

      cd /iscsi/iqn.2019-05.com.example:servers1/tpg1/

      # 开启 tpg1 级别的登录认证
      set attribute authentication=1

      # 启用 read/write 模式
      set attribute demo_mode_write_protect=0
      set attribute generate_node_acls=1

      # 配置 tpg1 级别的登录认证
      set attribute authentication=1
      set auth userid=agent_login_user1 # 传入账号,客户端登录服务端用于校验的账号
      set auth password=agent_login_passwd1 # 传入账号对应的密码
      set auth mutual_userid=server_check_user1 # 传出账号,服务器用于验证客户端的账号
      set auth mutual_password=server_check_passwd1 # 传出账号对应的密码

      # 配置 acls 级别的登录认证
      cd /iscsi/iqn.2019-05.com.example:servers1/tpg1/acls/iqn.2019-05.com.example:agent1
      set auth userid=agent_login_user1 # 传入账号,客户端登录服务端用于校验的账号
      set auth password=agent_login_passwd1 # 传入账号对应的密码
      set auth mutual_userid=server_check_user1 # 传出账号,服务器用于验证客户端的账号
      set auth mutual_password=server_check_passwd1 # 传出账号对应的密码
    • 单向发现认证

      cd /iscsi
      set discovery_auth enable=1
      set discovery_auth userid=agent_discovery_user2 # 传入账号,客户端发现服务端用于校验的账号
      set discovery_auth password=agent_discovery_passwd2 # 传入账号对应的密码
    • 双向发现认证

      cd /iscsi
      set discovery_auth enable=1
      set discovery_auth userid=agent_discovery_user2 # 传入账号,客户端发现服务端用于校验的账号
      set discovery_auth password=agent_discovery_passwd2 # 传入账号对应的密码
      set discovery_auth mutual_userid=server_check_user2 # 传出账号,服务器用于验证客户端的账号
      set discovery_auth mutual_password=server_check_passwd2 # 传出账号对应的密码
  10. 执行 exit 退出编辑并自动保存

客户端校验

  1. 基础环境配置

    # 禁止 selinux
    setenforce 0 # 临时禁止,重启后恢复
    # 关闭防火墙
    systemctl disable firewalld.service \
    && systemctl stop firewalld.service
    # 安装 ntp 时间同步服务器
    yum install ntp -y \
    && systemctl enable ntpd.service \
    && systemctl start ntpd.service
  2. 安装 iscsi-initiator-utils 工具

    yum install iscsi-initiator-utils -y
  3. 配置客户端 iqn

    vi /etc/iscsi/initiatorname.iscsi
    # 修改为之前 ACL 中创建的客户端 iqn
    InitiatorName=iqn.2019-05.com.example:agent1
  4. 配置客户端认证参数

    # 编辑配置文件
    vi /etc/iscsi/iscsid.conf

    # *************
    # CHAP Settings
    # *************

    # 开启登录认证方法
    node.session.auth.authmethod = CHAP
    # 登录认证
    ## 对应服务端的传入账号,客户端用此账号校验服务器
    node.session.auth.username = agent_login_user1
    node.session.auth.password = agent_login_passwd1
    # 双向登录认证
    ## 对应服务端的传出账号,服务器用此账号校验客户端
    node.session.auth.username_in = server_check_user1
    node.session.auth.password_in = server_check_passwd1

    # 开启发现认证方法
    discovery.sendtargets.auth.authmethod = CHAP
    # 单向发现认证
    # 对应服务端的传入账号,客户端用此账号发现服务器
    discovery.sendtargets.auth.username = agent_discovery_user2
    discovery.sendtargets.auth.password = agent_discovery_passwd2
    # 双向发现认证
    # 对应服务端的传出账号,服务器用此账号校验客户端
    discovery.sendtargets.auth.username_in = server_check_user2
    discovery.sendtargets.auth.password_in = server_check_passwd2

    # ********
    # Timeouts
    # ********
  5. 发现测试

    iscsiadm -m discovery -t sendtargets -p 1.1.1.47
  6. 登录测试

    iscsiadm -m node -T iqn.2019-05.com.example:servers1 -p 1.1.1.47 -l

配置 K8S 持久卷(PV)

创建密文

  1. K8S 中需要以为密文方式传入客户端的认证账号,并且需要 base64 加密

    ---
    apiVersion: v1
    kind: Secret
    metadata:
    type: "kubernetes.io/iscsi-chap"
    data:
    discovery.sendtargets.auth.password: YWdlbnRfZGlzY292ZXJ5X3Bhc3N3ZDIK
    discovery.sendtargets.auth.username_in: c2VydmVyX2NoZWNrX3VzZXIyCg==
    discovery.sendtargets.auth.password_in: c2VydmVyX2NoZWNrX3Bhc3N3ZDIK
    node.session.auth.password: YWdlbnRfbG9naW5fcGFzc3dkMQo=
    node.session.auth.username_in: c2VydmVyX2NoZWNrX3VzZXIxCg==
    node.session.auth.password_in: c2VydmVyX2NoZWNrX3Bhc3N3ZDEK

    参考地址:https://github.com/kubernetes/examples/tree/master/volumes/iscsi

  2. 登录到 rancher ui,切换到任意项目(这里以 default 命名空间为例)\工作负载页面下,点击右上角的导入 YAML 按钮。

  3. 复制粘贴 yaml 内容,其他参数默认,最后点击 导入

创建 PV

  1. 登录 rancher ui,切换到指定集群\存储\持久卷,点击右上角的添加卷(pv);

创建测试应用

  1. 切换到项目视图下,点击创建工作负载;

  2. 配置应用的基本参数,

  3. 配置容器卷,选择添加新的持久卷

  4. 配置完成后点击启动。

  5. 应用运行正常后,通过 web shell 查看磁盘挂载情况

  6. 检查测试

    • 查看 target 生成的镜像文件大小
    • 进入容器/demo 路径下,通过 dd 命令写入一个文件
    dd if=/dev/zero of=/demo/demo count=2 bs=1024M