Metonymical Deflection

ゆるく日々のコト・たまにITインフラ

CentOS7 + SPDKでiSCSI target構築

CentOS7上でSPDKをビルドして、iSCSI targetを構築しました。
なお、CentOS7はDL360上で稼働させた場合と、Windows版VMWareWorkstation12上で稼働させた場合の両方で構築することができました。

1.環境

1-1.DL360
筐体                             : ProLiant DL360p Gen8
System ROM                       : P71 01/22/2018
CPU                           : Intel(R) Xeon(R) CPU E5-2660 0 @ 2.20GHz 
OS                               : CentOS7.5(1804)
Kernel                           : 3.10.0-862.el7.x86_64
Installed Environment Groups     : Minimal Install
SPDK                         : v18.07-pre
DPDK                             : v18.02.0
1-2.VMWare
筐体                             : 自作PC
CPU                           : Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz
VMWare              : VMware(R) Workstation 12 Pro 12.5.9 build-7535481  
OS                               : CentOS7.5(1804)
Kernel                           : 3.10.0-862.el7.x86_64
Installed Environment Groups     : Minimal Install
SPDK                         : v18.07-pre
DPDK                             : v18.02.0

WinおよびVMWare環境は以下の画像で確認してもらった方が良いかもしれません。
Win環境
f:id:metonymical:20180529200243j:plain
VMWare環境
f:id:metonymical:20180527224812j:plain
HugePageを使うためメモリは多めで。
SPDKはDPDKのPMDを使うためCPUのコア数も多めで。
さらに、
 Intel VT-x/EPT またはAMD-V-RVIを仮想化
 CPUパフォーマンスカウンタを仮想化
にもチェックを入れました。
50GBのOS用とは別に200GBのiSCSI Target用のHDDを追加しています。

1-3.全体の流れ

事前準備
SPDKのビルド
SPDKのiscsi.conf設定

2.事前準備

2-1.セキュリティ設定の無効化

firewalldとSELinuxを無効化します。

systemctl disable firewalld

vi /etc/selinux/config
で開いて
SELINUX=disabled
にして保存。
2-2.grubの設定

grubにHugePageの設定追加

vi /etc/sysconfig/grub

GRUB_CMDLINE_LINUX=の行末に追加
default_hugepagesz=1G hugepagesz=1G hugepages=4

保存後、grubに反映
grub2-mkconfig -o /etc/grub2.cfg
2-3.numactl-develのインストール

dpdkがnumactl-develを必要とするようなので念のためインストール。

yum -y install numactl-devel

reboot

再起動後にHugePageを確認。
# cat /proc/meminfo | grep ^Huge
HugePages_Total:       4
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:    1048576 kB

3.SPDKのビルド

spdkはdpdkと違い至れり尽くせりでpkgdep.shを実行することにより、spdkのビルドに必要なパッケージなどを自動でインストールし依存関係を解消してくれます。

3-1.gitインストールからspdkのビルドまで

少々乱暴ですが、以下を流し込んでしまって問題ありません。

yum -y install git && \
cd /usr/src && \
git clone https://github.com/spdk/spdk && \
cd spdk && \
git submodule update --init && \
scripts/pkgdep.sh && \
./configure && \
make

gitインストール
/usr/srcにcd
spdkのソースをgitから取得
/usr/src/spdkにcd*1
アップデート
必要なパッケージのインストール
makeファイル生成
ビルド

ちなみに、make前に

./configure --help

とすると、追加オプションを表示できます。
例えば、

./configure --with-rdma

とすることで、RDMAにも対応してくれるようです。

3-2.unittest.shの実行

ビルドが完了したら、最後に各モジュールのテストを実施してみてください。

./test/unit/unittest.sh

 出力結果省略

=====================
All unit tests passed
=====================
WARN: lcov not installed or SPDK built without coverage!
WARN: neither valgrind nor ASAN is enabled!

多数の出力結果が表示されますが、最後に「All unit tests passed」と表示されればOKです。
Warringが2件表示されてますが、気にせず先に進んでください。

4.spdkのiscsi.confファイル設定

4-1.設定ファイルの作成
# cd /usr/src/spdk/app/iscsi_tgt
# vi iscsi.conf

[global]
 ReactorMask 0x1
 LogFacility "local7"

[iSCSI]
 NodeBase "iqn.2016-06.io.spdk"
 AuthFile /usr/local/etc/spdk/auth.conf
 MinConnectionsPerCore 1
 MinConnectionIdleInterval 5000
 Timeout 30
 DiscoveryAuthMethod Auto
 DefaultTime2Wait 2
 DefaultTime2Retain 60
 ImmediateData Yes
 ErrorRecoveryLevel 0

[Rpc]                  #AIO(Asynchronous I/O)が生成されなかったためRPCを有効化しています。
 Enable Yes
 Listen 127.0.0.1

[AIO]
 AIO /dev/sdb AIO0 512          #追加した200GBのHDDを指定しています。   

[PortalGroup1]
 Portal DA1 192.168.11.208:3260     #自身のIPアドレス or 0.0.0.0:3260でも大丈夫です。

[InitiatorGroup1]
 InitiatorName ANY
 Netmask 192.168.11.0/24         #アクセス許可するNWアドレスを指定します。

[TargetNode1]
 TargetName disk1
 TargetAlias "Data Disk1"
 Mapping PortalGroup1 InitiatorGroup1
 AuthMethod Auto
 AuthGroup AuthGroup1
 UseDigest Auto
 LUN0 AIO0                #AIO0をLUN0としてTargetNodeを起動します。
 QueueDepth 128
4-2.Targetプログラムの実行

ファイルの保存が完了したら、先ほどcdした /usr/src/spdk/app/iscsi_tgt のパス上で以下を実行。

./iscsi_tgt -c iscsi.conf

以下、出力結果。
# ./iscsi_tgt -c iscsi.conf
Starting SPDK v18.07-pre / DPDK 18.02.0 initialization...
[ DPDK EAL parameters: iscsi -c 0x1 --file-prefix=spdk_pid22562 ]
EAL: Detected 4 lcore(s)
EAL: Multi-process socket /var/run/.spdk_pid22562_unix
EAL: Probing VFIO support...
app.c: 521:spdk_app_start: *NOTICE*: Total cores available: 1
reactor.c: 669:spdk_reactors_init: *NOTICE*: Occupied cpu socket mask is 0x1
reactor.c: 453:_spdk_reactor_run: *NOTICE*: Reactor started on core 0 on socket 0

iscsi_tgtのデフォルト動作ではフォアグラウンドで稼働してしまうため、上記出力でプロンプトが停止したように見えますが、iSCSI targetは正常に起動できています。
ちなみに、上記はVMWareの場合で、DL360の場合は EAL: NUMA socket 0~ といった表示が複数行出力されますが、iSCSI targetは正常に起動できています。*2
バックグラウンドで動作させたい場合には、-bを付けてください。

./iscsi_tgt -b -c iscsi.conf
4-3.Initiatorからのアクセス

Initiatorのインストール

yum -y install iscsi-initiator-utils

Discovery実施

# iscsiadm -m discovery -t sendtargets -p 192.168.11.208
192.168.11.208:3260,1 iqn.2016-06.io.spdk:disk1

Discovery時のTarget側出力*3

conn.c: 324:spdk_iscsi_conn_construct: *NOTICE*: Launching connection on acceptor thread
iscsi.c:2090:spdk_iscsi_op_login_notify_session_info: *NOTICE*: Login(discovery) from iqn.1994-05.com.redhat:a2f790913987 (192.168.11.209) on (192.168.11.208:3260,1), ISID=23d000000, TSIH=1, CID=0, HeaderDigest=off, DataDigest=off
conn.c: 741:spdk_iscsi_conn_read_data: *ERROR*: spdk_sock_recv() failed, errno 104: Connection reset by peer
conn.c: 456:spdk_iscsi_remove_conn: *NOTICE*: Terminating connections(tsih 1): 0

ログイン実施

# iscsiadm -m node --login
Logging in to [iface: default, target: iqn.2016-06.io.spdk:disk1, portal: 192.168.11.208,3260] (multiple)
Login to [iface: default, target: iqn.2016-06.io.spdk:disk1, portal: 192.168.11.208,3260] successful.

ログイン時のTarget側出力

conn.c: 324:spdk_iscsi_conn_construct: *NOTICE*: Launching connection on acceptor thread
iscsi.c:2078:spdk_iscsi_op_login_notify_session_info: *NOTICE*: Login from iqn.1994-05.com.redhat:a2f790913987 (192.168.11.209) on iqn.2016-06.io.spdk:disk1 tgt_node1 (192.168.11.208:3260,1), ISID=23d000003, TSIH=2, CID=0, HeaderDigest=off, DataDigest=off

Session確認

# iscsiadm -m session
tcp: [1] 192.168.11.208:3260,1 iqn.2016-06.io.spdk:disk1 (non-flash)

bdevとして認識されていることを確認

# lsblk
NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda               8:0    0   50G  0 disk
tqsda1            8:1    0    1G  0 part /boot
mqsda2            8:2    0   49G  0 part
  tqcentos-root 253:0    0   47G  0 lvm  /
  mqcentos-swap 253:1    0    2G  0 lvm  [SWAP]
sdb               8:16   0  200G  0 disk
sr0              11:0    1 1024M  0 rom

ログアウト

# iscsiadm -m node --logout
Logging out of session [sid: 1, target: iqn.2016-06.io.spdk:disk1, portal: 192.168.11.208,3260]
Logout of [sid: 1, target: iqn.2016-06.io.spdk:disk1, portal: 192.168.11.208,3260] successful.

ログアウト時のTarget側出力

iscsi.c:2601:spdk_iscsi_op_logout: *NOTICE*: Logout from iqn.1994-05.com.redhat:a2f790913987 (192.168.11.209) on iqn.2016-06.io.spdk:disk1 tgt_node1 (192.168.11.208:3260,1), ISID=23d000003, TSIH=2, CID=0, HeaderDigest=off, DataDigest=off
conn.c: 456:spdk_iscsi_remove_conn: *NOTICE*: Terminating connections(tsih 2): 0

あとは、通常のiSCSI Targetと同様に動作しますので、Initiator側でmkfsするなり、fioで速度測定するなりご自由にどうぞ。

以上です。

5.最後に

以下のサイトを参考にさせて頂きました。
SPDK: Getting Started
https://www.starwindsoftware.com/blog/intel-spdk-nvme-of-target-performance-tuning-part-2-preparing-testing-environment
CentOS7下编译安装SPDK iSCSI Target - 程序园

SPDKに関する日本語サイトが皆無に等しいのは覚悟の上だったのですが、英語サイトでも出力結果などの詳細解説を記載したサイトが無かったため、ちょっとしんどかったです。3番目の中国サイトがとても助かりました。ありがとうございます。

DPDKに引き続き、取り急ぎSPDKを動作させるところまでは何とかできました。これをベースにNVMe-oFなどにも挑戦したいなと思っています。RoCEv2などにも興味があるのですが、こちらは現在情報収集中です。私は元々ネットワークエンジニアなので、近い将来、主記憶装置も補助記憶装置もすべてがネットワーク上で抽象化orプール化されていくことをイメージしながら、その(大容量)トラフィックをどのように捌いて制御しようか?なんてことを考えつつ、最適なネットワーク設計を模索し続けています。

*1:このパスがspdkの基点になります。今回紹介した内容以外にも開発用の色々なツールが含まれていますので、興味があればディレクトリを漁ってみるのもいいかもしれません。

*2:このとき、Minimal Installだと、netstatが叩けなかったため、ss -naptで確認したところ、TCP3260のポートが開いていないように見える事象を確認しました。しかし、正常起動している可能性が高いので、試しにinitiator側からDiscoveryしてみてください。私はこの事象で1週間悩み続けました、幻を見ていたのかもしれませんが。。。

*3:エラーが出ていますが気にせず先に進めてください