1、管理Kernel NVMe/TCP Target
Cinder在R版开始通过volume模块LVM驱动中支持管理Kernel NVMe-oF Target,最初仅支持NVMe/RDMA,在Y版开始支持NVMe/TCP。
要实现对LVM驱动管理的卷的访问,实际分为两个部分。LVM驱动实现目标存储节点的逻辑卷管理,但本身不直接提供访问能力,而是依赖于可选的Target驱动为逻辑卷提供存储访问协议。
在配置文件中通过volume_driver字段指定使用LVM Driver:
volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver
通过target_protocol和target_helper字段指定存储访问协议和Target驱动,如需使用NVMe/TCP,则指定如下:
target_protocol = nvmet_tcp
target_helper = nvmet
在对应Target驱动的实现中,通过json结构体进行参数定义并调用nvme save/restore命令进行配置实现,从而提供NVMe/TCP存储传输协议访问设备。
手动配置Kernel NVMe/TCP Target流程可参考如下:
在内核中加载NVMe/TCP Target相关模块:
# modprobe nvmet
# modprobe nvmet_tcp
此时,目录/sys/kernel/config/nvmet生成,可被访问。
创建NVMeoF子系统:
# cd /sys/kernel/config/nvmet/subsystems
# mkdir nqn.2014-08.org.nvmexpress.cnode1
设置允许所有主机访问:
# cd nqn.2014-08.org.nvmexpress.cnode1
# echo 1 > attr_allow_any_host
创建命名空间,关联块设备,并启用:
# mkdir namespaces/1
# cd namespaces/1
# echo /dev/nvme0n1p1 > device_path
# echo 1 > enable
创建NVMeoF的TCP Trasnsport层:
# cd /sys/kernel/config/nvmet/ports/
# mkdir 1
设置监听地址和端口:
# cd 1
# echo tcp > addr_trtype
# echo ipv4 > addr_adrfam
# echo 192.168.0.3 > addr_traddr
# echo 4520 > addr_trsvcid
关联NVMeoF子系统:
# cd subsystems
# ln -s ../../../subsystems/nqn.2014-08.org.nvmexpress.cnode1 tcpsubsys
此时通过netstat命令即可看到端口4520已被监听。
2、管理SPDK NVMe/TCP Target
Cinder在S版开始新增volume模块SPDK驱动支持管理SPDK NVMe-oF Target,直至最新的发布版本,仅支持NVMe/RDMA。
与LVM驱动类似,SPDK驱动本身实现目标存储节点的SPDK逻辑卷管理,但本身不直接提供访问能力,而是依赖于Target驱动为SPDK逻辑卷提供存储访问协议。
在配置文件中指定如下:
volume_driver = cinder.volume.drivers.spdk.SPDKDriver
target_protocol = nvmet_rdma
target_helper = spdk-nvmeof
SPDK驱动与LVM驱动最大的不同点是逻辑卷的管理方式。SPDK驱动使用SPDK的逻辑卷管理器,通过与SPDK RPC Server交互实现逻辑卷管理,一个cinder卷对应一个SPDK逻辑卷。
存储传输协议的提供同样通过与SPDK RPC Server交互实现。
此Target驱动未正式支持NVMe/TCP,但参照nvmet,所需改动较少,理论上易实现。
手动配置SPDK NVMe/TCP Target流程可参考如下:
启动SPDK RPC Server,由于需要创建nvme/tcp target,可通过启用nvmf_tgt来同时启动RPC Server:
# cd spdk-21.07
# ./build/bin/nvmf_tgt -m 0xf0000
使用SPDK接管NVMe设备:
# PCI_ALLOWED="0000:86:00.0" HUGEMEM=65536 ./scripts/setup.sh
创建SPDK NVMe块设备(块设备名称命名为NVMe1):
# ./scripts/rpc.py bdev_nvme_attach_controller -b NVMe1 -t PCIe -a 0000:86:00.0
此时可考虑在此块设备上建SPDK逻辑卷容器(命名为Lvs1,供多个虚机使用)和逻辑卷(命名为Lvol1和Lvol2,容量单位为mb):(非必须)
# ./scripts/rpc.py bdev_lvol_create_lvstore NVMe1n1 Lvs1
# ./scripts/rpc.py bdev_lvol_create Lvol1 512000 -l Lvs1
创建NVMeoF的TCP Trasnsport层:
# ./scripts/rpc.py nvmf_create_transport -t tcp
创建NVMeoF子系统(可创建多个):
# ./scripts/rpc.py nvmf_create_subsystem -a nqn.2016-06.io.spdk:cnode1
在NVMeoF子系统中增加命名空间(关联SPDK设备):
# ./scripts/rpc.py nvmf_subsystem_add_ns nqn.2016-06.io.spdk:cnode1 Lvs1/Lvol1
为NVMeoF子系统创建监听端口(一般考虑指定IP和端口,-a参数标示允许任意host接入):
# ./scripts/rpc.py nvmf_subsystem_add_listener nqn.2016-06.io.spdk:cnode1 -t tcp -a 192.168.0.3 -s 4420
此时通过netstat命令即可看到端口4420已被监听。