複数ポート接続でのDM-Multipathを使ったiSCSI設定

#複数ポートを持ったiSCSIストレージへの接続の設定
通常iSCSIストレージには複数の接続用ポートがあるため冗長化と帯域を稼ぐことが同時に可能となる。

##DM-Multipathを利用する理由
bondingでも良さそうに思えるが、冗長化は実現出来たとしても負荷分散はできないため。

##下準備
###環境
  - ホスト（イニシエータ）側サーバにはiSCSIのために4ポート分NICが追加してある (2ポートGbE ×2枚)
  - iSCSIストレージ（ターゲット）はDELL MD3200i
    - 4ポートのiSCSI用GbEポートを持つコントローラが2枚取り付けてある
  - 解説中で利用している表示はCentOS 7のものだが、CentOS 6でも同じ設定で対応可能

###IPアドレス
iSCSI用のIPアドレスを設定する。このとき、各デバイスでポート毎に異なるサブネットになるようにする。

| デバイス  | IPアドレス | 
|:--|:--|
| ホスト | 192.168.201.1 - 192.168.204.1 |
| ストレージコントローラ0 | 192.168.201.101 - 192.168.204.101 |
| ストレージコントローラ1 | 192.168.201.102 - 192.168.204.102 |

ホスト側の各ポートのMACアドレスを確認しておく。

| ポートNo. | IPアドレス | MACアドレス |
|:--|:--|:--|
| 0 | 192.168.201.1 | xx:xx:xx:xx:xx:aa |
| 1 | 192.168.202.1 | xx:xx:xx:xx:xx:bb |
| 2 | 192.168.203.1 | xx:xx:xx:xx:xx:cc |
| 3 | 192.168.204.1 | xx:xx:xx:xx:xx:dd |

##iSCSIの設定
###iSCSIイニシエータ用パッケージの導入

```
# yum install -y iscsi-initiator-utils
```

###iSCSIイニシエータIQN
イニシエータIQNをメモするか好きな値に書き換える。書き換える場合は決められたフォーマットに従うようにする。
このイニシエータIQNからストレージの使いたいLUNにアクセス出来るよう設定しておく。

```
# vi /etc/iscsi/initiatorname.iscsi
```

###ifaceの設定

```
# iscsiadm -m iface -I iface0 -o new
New interface iface0 added
# iscsiadm -m iface -I iface1 -o new
New interface iface1 added
# iscsiadm -m iface -I iface2 -o new
New interface iface2 added
# iscsiadm -m iface -I iface3 -o new
New interface iface3 added

# iscsiadm -m iface -I iface0 -o update -n iface.hwaddress -v xx:xx:xx:xx:xx:aa
iface0 updated.
# iscsiadm -m iface -I iface1 -o update -n iface.hwaddress -v xx:xx:xx:xx:xx:bb
iface1 updated.
# iscsiadm -m iface -I iface2 -o update -n iface.hwaddress -v xx:xx:xx:xx:xx:cc
iface2 updated.
# iscsiadm -m iface -I iface3 -o update -n iface.hwaddress -v xx:xx:xx:xx:xx:dd
iface3 updated.

# iscsiadm -m iface
default tcp,<empty>,<empty>,<empty>,<empty>
iser iser,<empty>,<empty>,<empty>,<empty>
iface0 tcp,xx:xx:xx:xx:xx:aa,<empty>,<empty>,<empty>
iface1 tcp,xx:xx:xx:xx:xx:bb,<empty>,<empty>,<empty>
iface2 tcp,xx:xx:xx:xx:xx:cc,<empty>,<empty>,<empty>
iface3 tcp,xx:xx:xx:xx:xx:dd,<empty>,<empty>,<empty>
```

###iSCSIターゲットを認識させる
iscsiadmコマンドでiSCSIターゲットのディスカバリを**サブネット毎に**行う。複数の接続エラーが表示され、うんざりするほど時間がかかるが最終的に認識していれば問題ない。
ストレージコントローラ0側のIPアドレスに対して行えばコントローラ1側も自動的に認識してくれたが機種によるのかも？ストレージ装置が複数ある場合は同一サブネット内でも見つけてくれないので別途そのIPを指定する必要がある。

```
# iscsiadm -m discovery -t sendtargets -p 192.168.201.101
(略)
# iscsiadm -m discovery -t sendtargets -p 192.168.202.101
(略)
# iscsiadm -m discovery -t sendtargets -p 192.168.203.101
(略)
# iscsiadm -m discovery -t sendtargets -p 192.168.204.101
(略)
```
#### 追記
~~下記のように設定すれば余計な手間が省けるかもしれないので今後検証してみる。~~
下記のようにサブネット毎に接続されているifaceを明示することで一瞬でディスカバリが終了する。しかし以降の手順で楽になることはない。

```
# iscsiadm -m discovery -t sendtargets -p 192.168.201.101 -I iface0
# iscsiadm -m discovery -t sendtargets -p 192.168.202.101 -I iface1
# iscsiadm -m discovery -t sendtargets -p 192.168.203.101 -I iface2
# iscsiadm -m discovery -t sendtargets -p 192.168.204.101 -I iface3
```


###詳細な認識状況を確認
全てのifaceXが全てのストレージのポートと通信可能**ということ**になっている。

```
#  iscsiadm -m node -P 1
Target: iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        Portal: 192.168.201.201:3260,1
                Iface Name: iface0
                Iface Name: iface1
                Iface Name: iface2
                Iface Name: iface3
        Portal: 192.168.202.201:3260,1
                Iface Name: iface0
                Iface Name: iface1
                Iface Name: iface2
                Iface Name: iface3
        Portal: 192.168.203.201:3260,1
                Iface Name: iface0
                Iface Name: iface1
                Iface Name: iface2
                Iface Name: iface3
        Portal: 192.168.204.201:3260,1
                Iface Name: iface0
                Iface Name: iface1
                Iface Name: iface2
                Iface Name: iface3
        Portal: 192.168.201.202:3260,2
                Iface Name: iface0
                Iface Name: iface1
                Iface Name: iface2
                Iface Name: iface3
        Portal: 192.168.202.202:3260,2
                Iface Name: iface0
                Iface Name: iface1
                Iface Name: iface2
                Iface Name: iface3
        Portal: 192.168.203.202:3260,2
                Iface Name: iface0
                Iface Name: iface1
                Iface Name: iface2
                Iface Name: iface3
        Portal: 192.168.204.202:3260,2
                Iface Name: iface0
                Iface Name: iface1
                Iface Name: iface2
                Iface Name: iface3
```

###実際には通信不可能な組み合わせを削除
何か間違ってるんじゃないかと思うくらいとても面倒くさい作業…

```
# iscsiadm -m node -T iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -p 192.168.202.101 -I iface0 -o delete
# iscsiadm -m node -T iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -p 192.168.202.102 -I iface0 -o delete
# iscsiadm -m node -T iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -p 192.168.203.101 -I iface0 -o delete
# iscsiadm -m node -T iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -p 192.168.203.102 -I iface0 -o delete
# iscsiadm -m node -T iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -p 192.168.204.101 -I iface0 -o delete
# iscsiadm -m node -T iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -p 192.168.204.102 -I iface0 -o delete
# iscsiadm -m node -T iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -p 192.168.201.101 -I iface1 -o delete
# iscsiadm -m node -T iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -p 192.168.201.102 -I iface1 -o delete
# iscsiadm -m node -T iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -p 192.168.203.101 -I iface1 -o delete
# iscsiadm -m node -T iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -p 192.168.203.102 -I iface1 -o delete
# iscsiadm -m node -T iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -p 192.168.204.101 -I iface1 -o delete
# iscsiadm -m node -T iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -p 192.168.204.102 -I iface1 -o delete
# iscsiadm -m node -T iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -p 192.168.201.101 -I iface2 -o delete
# iscsiadm -m node -T iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -p 192.168.201.102 -I iface2 -o delete
# iscsiadm -m node -T iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -p 192.168.202.101 -I iface2 -o delete
# iscsiadm -m node -T iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -p 192.168.202.102 -I iface2 -o delete
# iscsiadm -m node -T iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -p 192.168.204.101 -I iface2 -o delete
# iscsiadm -m node -T iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -p 192.168.204.102 -I iface2 -o delete
# iscsiadm -m node -T iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -p 192.168.201.101 -I iface3 -o delete
# iscsiadm -m node -T iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -p 192.168.201.102 -I iface3 -o delete
# iscsiadm -m node -T iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -p 192.168.202.101 -I iface3 -o delete
# iscsiadm -m node -T iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -p 192.168.202.102 -I iface3 -o delete
# iscsiadm -m node -T iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -p 192.168.203.101 -I iface3 -o delete
# iscsiadm -m node -T iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -p 192.168.203.102 -I iface3 -o delete
```

###削除後の設定を確認
不要なエントリを削除して綺麗になった

```
#  iscsiadm -m node -P 1
Target: iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        Portal: 192.168.201.101:3260,1
                Iface Name: iface0
        Portal: 192.168.202.101:3260,1
                Iface Name: iface1
        Portal: 192.168.203.101:3260,1
                Iface Name: iface2
        Portal: 192.168.204.101:3260,1
                Iface Name: iface3
        Portal: 192.168.201.102:3260,2
                Iface Name: iface0
        Portal: 192.168.202.102:3260,2
                Iface Name: iface1
        Portal: 192.168.203.102:3260,2
                Iface Name: iface2
        Portal: 192.168.204.102:3260,2
                Iface Name: iface3
```

###全てのiSCSIターゲットにログイン
実際に接続されていないiSCSIターゲットのエントリを消していると数秒でログイン処理が完了するはず。変なエントリがあるとタイムアウトが発生する。

```
# iscsiadm -m node -l
Logging in to [iface: iface0, target: iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, portal: 192.168.201.201,3260] (multiple)
Logging in to [iface: iface1, target: iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, portal: 192.168.202.201,3260] (multiple)
Logging in to [iface: iface2, target: iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, portal: 192.168.203.201,3260] (multiple)
Logging in to [iface: iface3, target: iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, portal: 192.168.204.201,3260] (multiple)
Logging in to [iface: iface0, target: iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, portal: 192.168.201.102,3260] (multiple)
Logging in to [iface: iface1, target: iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, portal: 192.168.202.102,3260] (multiple)
Logging in to [iface: iface2, target: iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, portal: 192.168.203.102,3260] (multiple)
Logging in to [iface: iface3, target: iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, portal: 192.168.204.102,3260] (multiple)
Login to [iface: iface0, target: iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, portal: 192.168.201.101,3260] successful.
Login to [iface: iface1, target: iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, portal: 192.168.202.101,3260] successful.
Login to [iface: iface2, target: iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, portal: 192.168.203.101,3260] successful.
Login to [iface: iface3, target: iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, portal: 192.168.204.101,3260] successful.
Login to [iface: iface0, target: iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, portal: 192.168.201.102,3260] successful.
Login to [iface: iface1, target: iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, portal: 192.168.202.102,3260] successful.
Login to [iface: iface2, target: iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, portal: 192.168.203.102,3260] successful.
Login to [iface: iface3, target: iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, portal: 192.168.204.102,3260] successful.

# iscsiadm -m session
tcp: [1] 192.168.201.101:3260,1 iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(non-flash)
tcp: [2] 192.168.202.101:3260,1 iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(non-flash)
tcp: [3] 192.168.203.101:3260,1 iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(non-flash)
tcp: [4] 192.168.204.101:3260,1 iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(non-flash)
tcp: [5] 192.168.201.102:3260,2 iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(non-flash)
tcp: [6] 192.168.202.102:3260,2 iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(non-flash)
tcp: [7] 192.168.203.102:3260,2 iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(non-flash)
tcp: [8] 192.168.204.102:3260,2 iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(non-flash)
```

###iSCSIボリュームの認識状況を確認
ホスト側のイニシエータIQNのマッピングがストレージ側で適切に行われていないとiSCSIのセッションを確立出来てもブロックデバイスが見えない。``# iscsiadm -m session --rescan``しても表示されないため、その場合はストレージ側の設定を変更した後に一度iSCSIセッションを切断して再度ログインする。
複数のiSCSIストレージにログインしている時には既に利用している接続に影響を及ぼさないようにターゲット名を指定してログアウトすること。

```
# iscsiadm -m node -T iqn.1984-05.com.dell:powervault.md3200i.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx --logout
(略)

# iscsiadm -m node --login
(略)
```

iSCSIセッションを切断する前に既にマウントしているiSCSIボリュームがある場合はアンマウントする必要があるため、場合によってはかなりキツい。LUNを追加した場合は`# iscsiadm -m node -R`でログアウトすること無く追加したiSCSIボリュームを認識させられるが、容量変更や削除した場合はログアウトさせる必要がある（確認した限りそう思われる）。


上手く認識出来ていれば以下のようになる（sdb～sdi）。

```
# lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda      8:0    0   149G  0 disk
tqsda1   8:1    0   500M  0 part /boot
tqsda2   8:2    0 140.5G  0 part /
mqsda3   8:3    0     8G  0 part [SWAP]
sdb      8:16   0   100G  0 disk
sdc      8:32   0   100G  0 disk
sdd      8:48   0   100G  0 disk
sde      8:64   0   100G  0 disk
sdf      8:80   0   100G  0 disk
sdg      8:96   0   100G  0 disk
sdh      8:112  0   100G  0 disk
sdi      8:128  0   100G  0 disk
sr0     11:0    1  1024M  0 rom
```

##multipath設定
###DM-Multipathパッケージの導入

```
# yum install -y device-mapper-multipath
# modprobe dm-multipath
```

###設定ファイルの作成
multipath用設定ファイルを作成する。このファイルは自動では作成されないためテンプレをコピーして書き換えるか自分で適当に作成する必要がある。*間違えて /etc/multipath/ 配下に作成しないこと*
基本的にブラックリストに設定して利用したいwwidのみ例外登録するのが安全だと思う。

```bash:/etc/multipath.conf
blacklist {
    devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*"
    devnode "^hd[a-z]"
    devnode "sda"
    wwid *
 
    device {
        vendor "*"
        product "Universal Xport"
    }
}
blacklist_exceptions {
    wwid aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
}          
defaults {
    user_friendly_names yes
    path_grouping_policy multibus
}
devices {
    device {
        vendor "DELL"
        product "MD32xxi"
        rr_min_io 32
        path_checker rdac
        path_selector "round-robin 0"
        hardware_handler "1 rdac"
        failback immediate
        prio rdac
    }
}
```

###設定を反映させる
最期に`# multipath -v2`を実行したときに表示が出れば成功。上手くいかないときは`# multipath -v3`で詳細を確認すると良い。
設定ファイルを書き換えた場合は再度`# multipath`から順に実行する。

```
# multipath
# multipath -F
# multipath -v2
(略)
```

どのようにmultipathが構成されているか確認

```
# multipath -ll
mpatha (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) dm-0 DELL    ,MD32xxi
size=100G features='3 queue_if_no_path pg_init_retries 50' hwhandler='1 rdac' wp=rw
|-+- policy='round-robin 0' prio=14 status=active
| |- 14:0:0:0 sdd 8:48  active ready running
| |- 15:0:0:0 sdb 8:16  active ready running
| |- 16:0:0:0 sdc 8:32  active ready running
| `- 17:0:0:0 sde 8:64  active ready running
`-+- policy='round-robin 0' prio=9 status=enabled
  |- 18:0:0:0 sdi 8:128 active ready running
  |- 19:0:0:0 sdg 8:96  active ready running
  |- 20:0:0:0 sdh 8:112 active ready running
  `- 21:0:0:0 sdf 8:80  active ready running
```

*mpatha*という名前を変えたい場合は`/etc/multipath/bindings`を書き換えて上記の`# multipath`からの手順をやり直す。
その際にフレンドリ名とwwidの間に余計なスペースがあると失敗する。


###常駐設定
最初の`# multipath`の実行時に起動しているが一応起動と常駐のための操作を行う。

```
# systemctl start multipathd
# systemctl enable multipathd
```

##ベンチマーク
fioを使って下記のベンチマークを実行

```ini:seqread4.fio
[global]
filename=/dev/mapper/mpatha
group_reporting=1
direct=1
ioengine=libaio

[seqread4]
readwrite=read
blocksize=1m
size=1g
numjobs=4
loops=5
```

```
# fio seqread4.fio
(略)
seqread4: (groupid=0, jobs=4): err= 0: pid=30251: Mon Jun 19 13:23:32 2017
Run status group 0 (all jobs):
   READ: io=20480MB, aggrb=297717KB/s, minb=297717KB/s, maxb=297717KB/s, mint=70441msec, maxt=70441msec
```

300MB/s程度の速度が出ていることからDM-multipathにより負荷分散が出来ていることが確認できる。

##メモ
あくまで本内容は個人的な検証結果のメモです。
CentOS 6まではiSCSIのセッションが確立されている状態で`# /etc/init.d/network restart`するとiSCSIがログアウトされてしまうため悲惨な状態になっていたが、CentOS 7からは問題ないように対応されている模様。