NVMe over TCP
マシン2台で直結のテスト環境作ったので忘れないうちにメモしておく。
カーネル5.0からNVMe TCPがサポートされた。
Ubuntu 18.04.03やFedora 31ではモジュール化されている。一応モジュールがあるか確認し、ロードする。モジュールになっていないディストリビューションの場合は構成を確認し、必要に応じてカーネルを再コンパイルする。
まずはターゲット側マシン。
# find /lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/ -name nvme* /lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/ /lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/host/nvme-core.ko.xz /lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/host/nvme-fabrics.ko.xz /lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/host/nvme-fc.ko.xz /lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/host/nvme-tcp.ko.xz /lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/host/nvme.ko.xz /lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/host/nvme-rdma.ko.xz /lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/target/nvme-fcloop.ko.xz /lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/target/nvme-loop.ko.xz /lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/target/nvmet-fc.ko.xz /lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/target/nvmet-tcp.ko.xz /lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/target/nvmet.ko.xz /lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/target/nvmet-rdma.ko.xz # # modprobe nvmet # modprobe nvmet-tcp # # lsmod | grep nvme nvmet_tcp 28672 1 nvmet 102400 7 nvmet_tcp nvme 49152 0 nvme_core 102400 1 nvme #
nvme用のターゲットツールをインストールする。やることの考え方はtargetcliと同じで、サブシステムでストレージの設定を行い、ポートでネットワークの設定を行い、両者を結びつける。
まずはサブシステムを今回はtcp-test1という名前で作成し、ネームスペースは単純に1として作成。 そのネームスペース1にバッキングデバイスとして今回は実物のNVMe SSDではなくnullデバイスを指定する。接続を許すホストとして全てOKにしてしまい、最後に有効化する。
# dnf install nvmetcli # # mkdir /sys/kernel/config/nvmet/subsystems/tcp-test1 # mkdir -p /sys/kernel/config/nvmet/subsystems/tcp-test1/namespaces/1 # echo /dev/nullb0 > /sys/kernel/config/nvmet/subsystems/tcp-test1/namespaces/1/device_path # echo 1 > /sys/kernel/config/nvmet/subsystems/tcp-test1/attr_allow_any_host # echo 1 > /sys/kernel/config/nvmet/subsystems/tcp-test1/namespaces/1/enable #
ポートはまず1番ポートを作成し、接続方式としてIPv4とTCPを指定し、使用するIPアドレスとポートを設定する。ファイアウォールが稼働中であればポートの追加を忘れずに。
# mkdir /sys/kernel/config/nvmet/ports/1 # echo ipv4 > /sys/kernel/config/nvmet/ports/1/addr_adrfam # echo tcp > /sys/kernel/config/nvmet/ports/1/addr_trtype # echo 4420 > /sys/kernel/config/nvmet/ports/1/addr_trsvcid # echo 192.168.1.1 > /sys/kernel/config/nvmet/ports/1/addr_traddr # # firewall-cmd --zone=FedoraServer --add-port=4420/tcp --permanent # firewall-cmd --reload
ターゲット側の最後に今作成したサブシステムとポート間でリンクを張る。dmesgでNVMe over TCPが無事設定できたことが確認できる。
# ln -s /sys/kernel/config/nvmet/subsystems/tcp-test1/ /sys/kernel/config/nvmet/ports/1/subsystems/tcp-test1 # # dmesg | grep nvmet_tcp [ 3071.444329] nvmet_tcp: enabling port 1 (192.168.1.1:4420)
イニシエータ側マシンでの作業は、NVMe over TCPのクライアント用ドライバをロードして、ディスカバリし、接続という流れ。最終的にはターゲット側の250GBのnullb0がイニシエータ側マシンではnvme1n1として接続できている。
# firewall-cmd --zone=FedoraServer --add-port=4420/tcp --permanent # firewall-cmd --reload # # modprobe nvme-tcp # lsmod | grep nvme nvme_tcp 36864 0 nvme_fabrics 28672 1 nvme_tcp nvme 49152 0 nvme_core 102400 3 nvme_tcp,nvme,nvme_fabrics # # nvme discover -t tcp -a 192.168.1.1 -s 4420 Discovery Log Number of Records 1, Generation counter 2 =====Discovery Log Entry 0====== trtype: tcp adrfam: ipv4 subtype: nvme subsystem treq: not specified, sq flow control disable supported portid: 1 trsvcid: 4420 subnqn: tcp-test1 traddr: 192.168.1.1 sectype: none # # nvme connect -t tcp -n tcp-test1 -a 192.168.1.1 -s 4420 # # lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 447.1G 0 disk ├─sda1 8:1 0 600M 0 part /boot/efi ├─sda2 8:2 0 1G 0 part /boot └─sda3 8:3 0 445.6G 0 part ├─fc31-root 253:0 0 15G 0 lvm / └─fc31-swap 253:1 0 31.4G 0 lvm [SWAP] sdb 8:16 0 1.5T 0 disk sdc 8:32 0 1.5T 0 disk sdd 8:48 1 14.6G 0 disk └─sdd1 8:49 1 14.6G 0 part sr0 11:0 1 2G 0 rom nvme0n1 259:0 0 477G 0 disk ├─nvme0n1p1 259:1 0 512M 0 part └─nvme0n1p2 259:2 0 476.4G 0 part nvme1n1 259:4 0 250G 0 disk