ページ

2016年3月7日月曜日

SRP ストレージを作る (SRP Target)

PC に Infiniband HCA を搭載して、CentOS 7 で (ミニ)SANストレージを構築してみたいと思います。
HCA は、QDR 40Gb/s をサポートしている Mellanox ConnectX-2 VPI (Single Port) を使用します。

Infiniband といっても、Infiniband スイッチは入手できなかったので、下記のようにストレージへの接続元と直結することにします。
KVM ホストのストレージプールとして使用










Infiniband は上位レイヤでネットワークやストレージ関連の様々なプロトコルを使用できますが、今回は SRP (SCSI RDMA Protocol) を使用します。
ストレージ側が SRP Target、アクセス元のKVMホストが SRP Initiator となります。

以下、SRP Target の構築です。

Infiniband セットアップ

では、まず Infiniband のドライバやユーティリティ等をインストールです。これにはいくつか選択肢があります。
  1. rpm パッケージ
  2. OFED (Open Fabrics Enterprise Distribution)
  3. Mellanox OFED (Mellanox 版の OFED)
HCA が Mellanox 製なので Mellanox OFED を使いたいところです。しかし、この後の SRP Target の構築を LIO (Linux IO Target) で行うため、Mellanox OFED は使用できません。
LIO では kernel モジュールの設定や参照を ConfigFS (sysfs のようなメモリ上の仮想ファイルシステム。ユーザスペースから kernel モジュールの設定や参照が可能。) で行うのですが、Mellanox OFED の SRP Target モジュール (ib_srpt.ko) が ConfigFS に対応していないためです。
よって、SRP Target 側は rpm パッケージからインストールします。
(ただ、rpm には Mellanox OFED に入っている hca_self_test.ofed のようなツールはありません)

CentOS 7 のインストール時に Infiniband HCA が検出されると、anaconda により rdma がインストールされますが、その他にも必要なパッケージをインストールします。
$ sudo yum install libibverbs libibverbs-utils
$ sudo yum install opensm
$ sudo yum install libmlx4 libmlx5 libmthca
$ sudo yum install libocrdma
$ sudo yum install librdmacm librdmacm-utils ibacm
$ sudo yum install infiniband-diags ibutils
$ sudo yum install perftest qperf
$ sudo yum install dapl dapl-utils
$ sudo yum install libibcommon libibcm
Infiniband ファブリックには Subnet Manager が 1つは存在している必要があります。
今回は HCA を直結するので、ストレージ側で Subnet Manager を稼働させることにします。
1 Port の HCA 1個だけ搭載している場合は、特に設定を行わずデフォルトのままでも Subnet Manager は動作しますので、このまま opensm サービスを起動します。
$ sudo systemctl start opensm
$ sudo systemctl enable opensm
SRP Target モジュールは、デフォルトで rdma サービス起動時にロードされるようになっています。
$ more /etc/rdma/rdma.conf
# Load IPoIB
IPOIB_LOAD=yes
# Load SRP (SCSI Remote Protocol initiator support) module
SRP_LOAD=yes
# Load SRPT (SCSI Remote Protocol target support) module
SRPT_LOAD=yes
# Load iSER (iSCSI over RDMA initiator support) module
ISER_LOAD=yes
# Load iSERT (iSCSI over RDMA target support) module
ISERT_LOAD=yes

ib_srpt.ko モジュールがロードされていることを確認します。
$ lsmod | grep srp
ib_srpt                52289  0
target_core_mod       303808  11 target_core_iblock,target_core_pscsi,iscsi_target_mod,ib_srpt,target_core_file,ib_isert
ib_srp                 42448  0
scsi_transport_srp     20725  1 ib_srp
scsi_tgt               20027  1 scsi_transport_srp
ib_cm                  42689  5 rdma_cm,ib_srp,ib_ucm,ib_srpt,ib_ipoib
ib_sa                  33950  6 rdma_cm,ib_cm,mlx4_ib,ib_srp,rdma_ucm,ib_ipoib
ib_mad                 47486  5 ib_cm,ib_sa,mlx4_ib,ib_srpt,ib_umad
ib_core                88311  16 rdma_cm,ib_cm,ib_sa,iw_cm,xprtrdma,mlx4_ib,ib_mad,ib_srp,ib_ucm,ib_iser,ib_srpt,ib_umad,ib_uverbs,rdma_ucm,ib_ipoib,ib_isert
これで Infiniband のセットアップは完了です。

SRP Target 構築

続いて、LIO (Linux-IO) を使用して SRP Target を構築します。
LIO は kernel モジュール (target_core_mod.ko、iscsi_target_mod.ko 等) として Linux に標準で組み込まれている SCSI Target です。
Python ベースの targetcli (LIO Shell) を使って管理します。

LIO の設定には ConfigFS が使用されます。
ConfigFS を使うには、/sys/kernel/config が ConfigFS としてマウントされている必要がありますが、CentOS 7 では OS インストール時に Inifiniband HCA が検出されると、デフォルトで自動マウントされるようになります。
LIO モジュールのディレクトリ /sys/kernel/config/target/ が作成されており参照できると思います。
$ cat /sys/kernel/config/target/version
Target Engine Core ConfigFS Infrastructure v4.1.0-rc2-ml on Linux/x86_64 on 3.10.0-229.14.1.el7.x86_64
targetcli をインストールします。
$ sudo yum install targetcli
targetcli はシェルのような CUI のツールで、iSCSI や FC などのネットワークファブリックのセクションと、物理、論理ブロックデバイス等のセクション (Backstores) に分かれています。
$ sudo targetcli          //初回起動時は以下の Warning が出る
Warning: Could not load preferences file /root/.targetcli/prefs.bin.
targetcli shell version 2.1.fb37
Copyright 2011-2013 by Datera, Inc and others.
For help on commands, type 'help'.

/>
/> ls
o- / .............................................................................................. [...]
  o- backstores ................................................................................... [...]
  | o- block ....................................................................... [Storage Objects: 0]
  | o- fileio ...................................................................... [Storage Objects: 0]
  | o- pscsi ....................................................................... [Storage Objects: 0]
  | o- ramdisk ..................................................................... [Storage Objects: 0]
  o- iscsi ................................................................................. [Targets: 0]
  o- loopback .............................................................................. [Targets: 0]
  o- srpt .................................................................................. [Targets: 0]
/>
targetcli を終了すると、自動で設定情報が /etc/target/saveconfig.json に保存されます。
(グローバルパラメータの auto_save_on_exit がデフォルトで有効になっているため)
/> exit
Global pref auto_save_on_exit=true
Last 10 configs saved in /etc/target/backup.
Configuration saved to /etc/target/saveconfig.json
ただし、 ファイルに保存しても OS を再起動すると設定はクリアされてしまいます。
target サービスを有効化しておくと、OS 起動時にファイル保存した設定がリストアされるようになります。
$ sudo systemctl start -t service target
$ sudo systemctl enable -t service target
targetcli では、まず Backstore を定義します。
この Backstore の領域(ボリューム)を LUN に割り当て、SRP Initiator からアクセスする形になります。

Backstore には以下の Storage Object があります。
  • BLOCK    ... ブロックデバイス
  • FILEIO    ... ファイルシステム上のファイル
  • PSCSI    ... SCSIパススルー
  • RAMDISK    ... メモリをブロックデバイスとして使う
BLOCK はブロックデバイスをそのまま割り当てます。Write through なので、突発的な電源断などでシステムが落ちた場合でも、データロスのリスクが低いです。
FILEIO はファイルをディスクイメージのように使用します。(ブロックデバイスを指定することも可能)
Write back に設定すればパフォーマンスが大幅に向上しますが、突発的なダウン等のおけるデータロスのリスクが高くなります。
今回は、SSD * 3台で構成した RAID5 Array (Fake RAID) を BLOCK に指定することにします。
/> backstores/block create BSBLK01 /dev/md/array0_0
Created block storage object BSBLK01 using /dev/md/array0_0.

/> ls backstores/block/
o- block ........................................................................... [Storage Objects: 1]
  o- BSBLK01 ....................................... [/dev/md/array0_0 (476.9GiB) write-thru deactivated]
次に、SRP Target の設定です。
kernel モジュールの ib_srpt.ko がロードされていれば、targetcli のツリーに srpt が表示されているはずです。
また、targetcli で srpt の設定を行うと、ConfigFS の /sys/kernel/config/target/srpt/ 配下に書き込まれます。
/> srpt/ info
Fabric module name: srpt
ConfigFS path: /sys/kernel/config/target/srpt
Allowed WWN types: ib
Allowed WWNs list: ib.fe800000000000000002c903000f826d
Fabric module features: acls
Corresponding kernel module: ib_srpt
/>
SRP Target のインスタンスを作成します。
/> cd srpt
/srpt> create fe800000000000000002c903000f826d
Created target ib.fe800000000000000002c903000f826d.

/srpt> ls
o- srpt .................................................................................... [Targets: 1]
  o- ib.fe800000000000000002c903000f826d .................................................. [no-gen-acls]
    o- acls ................................................................................... [ACLs: 0]
    o- luns ................................................................................... [LUNs: 0]
create のパラメータの WWN には、HCA の Port GUID を指定します。
Port GUID は、/sys/class/infiniband/(HCAのデバイス名)/ports/(ポート番号)/gids/0 で確認できます。
今回の 1 port の HCA の場合は以下を参照します。
$ cat /sys/class/infiniband/mlx4_0/ports/1/gids/0
fe80:0000:0000:0000:0002:c903:000f:826d
Backstore で定義した領域を LUN に割り当てます。
/srpt> ib.fe800000000000000002c903000f826d/luns create /backstores/block/BSBLK01
Created LUN 0.

/srpt> ls
o- srpt .................................................................................... [Targets: 1]
  o- ib.fe800000000000000002c903000f826d .................................................. [no-gen-acls]
    o- acls ................................................................................... [ACLs: 0]
    o- luns ................................................................................... [LUNs: 1]
      o- lun0 ........................................................ [block/BSBLK01 (/dev/md/array0_0)]
最後に、SRP Target インスタンスの ACL を設定します。
SRP Initiator から接続するには、ACL に WWPN として SRP Initiator の PortID が登録されていなければなりません。(iSCSI の場合は省略可能)
SRP Initiator は SRP Target に接続する時、認証要求 SRP_LOGIN_REQ で Initiator 側の PortID を送信します。
この PortID は、接続時に syslog に書かれるメッセージから確認することもできますが、SRP Initiator が Mellanox OFED の srp_daemon を使っている場合、
"SRP Target 側 Port GUID を Byte 単位で逆に並べた値 (8byte)" + "SRP Initiator の Port GUID (8byte)"
で構成されます。

今回のシステムでは、
  • 接続先 SRP Target の Port GUID ... 0x0002c903000f826d
  • 接続元 SRP Initiator の Port GUID ... 0x0002c903000f81e1
となっています (SRP Initiator については次回書きます) ので、SRP_LOGIN_REQ で送信される PortID は、"6d820f0003c90200" + "0002c903000f81e1" になります。

ちなみに、実際に SRP Initiator が接続してきた時の syslog が以下です。
kernel: ib_srpt Received SRP_LOGIN_REQ with i_port_id 0x6d820f0003c90200:0x2c903000f81e1, t_port_id 0x2c903000f826c:0x2c903000f826c and it_iu_len 260 on port 1 (guid=0xfe80000000000000:0x2c903000f826d)
この PortID を ACL に登録します。
自動で LUN0 に適用されます。
/srpt> ib.fe800000000000000002c903000f826d/acls create 6d820f0003c902000002c903000f81e1
Created Node ACL for ib.6d820f0003c902000002c903000f81e1
Created mapped LUN 0.

/srpt> ls
o- srpt .................................................................................... [Targets: 1]
  o- ib.fe800000000000000002c903000f826d .................................................. [no-gen-acls]
    o- acls ................................................................................... [ACLs: 1]
    | o- ib.6d820f0003c902000002c903000f81e1 ........................................... [Mapped LUNs: 1]
    |   o- mapped_lun0 ........................................................ [lun0 block/BSBLK01 (rw)]
    o- luns ................................................................................... [LUNs: 1]
      o- lun0 ........................................................ [block/BSBLK01 (/dev/md/array0_0)]
以上で SRP Target の準備が完了しました。

次は SRP Initiator 側のセットアップを行います。

0 件のコメント:

コメントを投稿