iSCSIは「ネットワーク上のローカルディスク」という幻想をどう実現しているのか?―現場で役立つLUNマッピングと通信の裏側
こんにちは。インフラのトラブルシューティングで深夜のデータセンターを徘徊していた頃を思い出すと、今でもiSCSIのセッションが切れた時の冷や汗が蘇ります。
今日は、クラウドネイティブ全盛の今だからこそ、あえて「iSCSI」というプロトコルの泥臭い挙動に焦点を当てます。KubernetesのPV(Persistent Volume)や、レガシーなDB移行で今なお現役のこの技術。TCP/IPという「信頼できないネットワーク」の上で、なぜブロックストレージがローカルディスクのように振る舞えるのか。その裏側のパケットとプロトコル設計の勘所を紐解いていきましょう。
—
1. iSCSIが「ブロック」を運ぶための魔法:TCP 3260番の正体
iSCSI(Internet Small Computer System Interface)の本質は、SCSIコマンドをTCP/IPパケットでカプセル化することです。HTTP APIのようなアプリケーション層のデータ転送とは異なり、iSCSIはOSに対して「これは物理的に刺さっているディスクだ」と錯覚させる必要があります。
ここで重要になるのが TCP 3260 ポートです。
通信フローの深層
1. Discovery (検出): イニシエータ(クライアント)がターゲット(ストレージ)に対し、SendTargetsコマンドを投げます。
2. Login Phase: 認証(CHAPなど)を経て、セッションを確立します。ここで重要なのが ISID (Initiator Session ID) と TSID (Target Session ID) です。
3. Full Feature Phase: ここからが本番です。SCSIのRead/WriteコマンドがTCPペイロードとして流れます。
ここで注意すべきは、iSCSIは「順序保証」と「再送制御」をTCPに丸投げしている点です。もしネットワークのパケットロスが激しければ、アプリケーション側(ファイルシステム)には一切の通知なく、ただI/Oがスタック(ハング)します。これが「iSCSIはネットワークの質に極めて敏感」と言われる所以です。
—
2. LUNマッピングの現実:ただのIDじゃない
ストレージ側で「LUN(Logical Unit Number)」を定義し、それを特定のイニシエータに「マッピング」する作業。これは単なる紐付けではなく、ターゲット側で ACL(Access Control List) を適用する行為です。
- IQN (iSCSI Qualified Name):
iqn.2023-10.com.example:storage.target01のような文字列。これがイニシエータの「指紋」になります。 - LUN: ストレージが提供する仮想的なディスクのID。
現場でよくあるミスが「IQNの打ち間違い」と「マルチパス設定の不備」です。特にマルチパス(MPIO)を考慮しないと、ネットワークインタフェースが落ちた瞬間にOSがファイルシステムを強制アンマウントし、データ破損を招きます。
—
3. 実践:Linux環境でのiSCSI接続とデバッグ
まずは、接続の確認から始めましょう。iscsiadm コマンドは、この世界の「標準」です。
# ターゲット上のストレージを探索する(ディスカバリー)
sudo iscsiadm -m discovery -t sendtargets -p 192.168.1.100:3260
# ターゲットにログイン(セッション確立)
sudo iscsiadm -m node -T iqn.2023-10.com.example:target01 -p 192.168.1.100:3260 --login
# 現在確立されているセッションを確認する
sudo iscsiadm -m session -P 1
もし接続がうまくいかない場合、私は必ず以下の手順でデバッグします。
1. ポートの疎通確認: telnet 192.168.1.100 3260 が通るか?(ファイアウォールでブロックされていないか)
2. 認証情報の確認: /etc/iscsi/iscsid.conf の node.session.auth.authmethod が CHAP になっているか?
3. ログの監視: dmesg | grep -i iscsi でカーネルレベルのエラー(Connection reset by peerなど)が出ていないか?
—
4. Pythonでターゲットの生存を監視する(Tips)
本番運用では、監視エージェントが「ストレージが見えているか」を判断する必要があります。socket ライブラリを使って、低レイヤーのTCP疎通確認を行うコード例です。
import socket
def check_iscsi_target(ip, port=3260):
"""
iSCSIポートが応答するかを確認する簡易チェッカー
"""
try:
# タイムアウトを3秒に設定
with socket.create_connection((ip, port), timeout=3) as sock:
print(f"Success: {ip}:{port} is reachable.")
return True
except (socket.timeout, ConnectionRefusedError):
print(f"Error: Could not connect to {ip}:{port}")
return False
# 運用監視のループなどで利用
if __name__ == "__main__":
check_iscsi_target("192.168.1.100")
—
5. SREとしての「教訓」
最後に、一つだけ覚えておいてください。iSCSIにおける最大の敵は、「TCPの再送によるレイテンシ増大」です。
クラウド環境で iSCSI を扱う場合、MTUサイズ(ジャンボフレームの検討)や、ストレージ専用のVLAN分離は必須です。Web APIのレスポンスが妙に遅いと感じたら、その裏側にあるデータベースのデータディレクトリ(iSCSIマウント)のI/O待ちを疑うべきです。
「速いネットワーク」は当たり前ではありません。パケットが 3260 番ポートを通る際、ストレージとイニシエータの間でどれだけのハンドシェイクが繰り返されているか、その「重み」を意識できるエンジニアこそが、真に信頼されるインフラ屋だと私は思います。
それでは、次回のトラブル対応もご安全に。
コメント