ストレージ実務 — RAID・スナップショット・iSCSI・fio
LUN はネットワークを越えてきたディスクだ — iSCSI とマルチパス
一言でいうと
iSCSIは、SCSIコマンドをTCPに載せて、ブロックデバイスをネットワーク越しに渡します。サーバーにはローカルディスクのように/dev/sdXとして見えますが、その下にはネットワークがあります。そのため、マウントの順序(_netdev)、アクセス制御(ACL・CHAP)、パスの冗長化(マルチパス)という、ローカルディスクにはなかった3つの課題が生じます。
なぜ必要なのか
NFSはファイルを共有します。サーバーがファイルシステムを持ち、クライアントは「このファイルを読んでください」と頼みます。ところが、データベースやハイパーバイザーは、ファイルではなくブロックデバイスを求めます。自分でファイルシステムを作り、キャッシュと書き込みの順序を自分で管理したいのです。ディスクをサーバーごとに挿すと、容量がサーバーに閉じ込められます。そこで、ディスクを1か所(ストレージ装置)に集め、その一部を切り出して、サーバーにブロックのまま貸し出す構造がSANで、その運搬をイーサネットとTCPで行うのがiSCSIです。
どう動くのか
RFC 7143が定義する用語は、いくつかだけです。
| 用語 | 意味 |
|---|---|
| イニシエーター(initiator) | ディスクを使う側。サーバー |
| ターゲット(target) | ディスクを提供する側。ストレージ |
| IQN | 双方の名前。iqn.<연-월>.<뒤집은 도메인>:<고유 이름>の形式(プレースホルダーは年月、逆順のドメイン、固有の名前です) |
| ポータル(portal) | ターゲットがリッスンするIPとポート。既定は3260/tcp |
| LUN | ターゲットの中で切り出した論理ディスク1つ |
Linuxのイニシエーターはopen-iscsiで、コマンドはiscsiadm1つです。流れは3段階です。ディスカバリー(discovery)は、iscsiadm -m discovery -t sendtargets -p <포털>(プレースホルダーはポータルです)が、ポータルにどのターゲットがあるかを問い合わせ、答えをローカルのノードレコードとして保存します。ログインは、iscsiadm -m node -T <IQN> -p <포털> --login(プレースホルダーはIQNとポータルです)がセッションを確立し、その瞬間にカーネルに新しいSCSIディスクが現れます。使用は、そのディスクがlsblkのTRAN列にiscsiと見え、名前が起動ごとに変わる可能性があるため、/dev/disk/by-path/ip-<포털>-iscsi-<IQN>-lun-<번호>(プレースホルダーはポータル、IQN、LUN番号です)のような固定のパスや、ファイルシステムのUUIDで指します。ノードレコードのnode.startupをautomaticにしておくと、サービスが起動したときに自動的にログインします。
Linuxカーネルには、ターゲット側も入っています。LIOと呼び、targetcliで設定します。バックストア(ファイルやブロックデバイス) → iSCSIターゲット(IQN) → TPGの下のLUN・ACL・ポータルの順にツリーを埋め、saveconfigで設定をファイルに残します。ACLは「このIQNのイニシエーターだけが、このLUNを見られる」というルールです。IQNは誰でも自分のものだと主張できる名前なので、実際の運用ではCHAPでシークレットの確認を加え、ストレージのトラフィックを別のVLANや専用ネットワークに置きます。
マウントの順序。ローカルディスクは起動の序盤にありますが、iSCSIディスクは、ネットワークが立ち上がってログインが終わって初めて現れます。systemd.mount(5)は、この場合、fstabのオプションに_netdevを付けるよう説明しています。ファイルシステムの種類だけでは、ネットワークデバイスかどうかが分からないからです。このオプションがないと、systemdがネットワークより先にマウントを試み、デバイスがなくて待ち続け、起動が遅くなったり止まったりします。
マルチパス。SANは、たいていパスを2つ以上置きます。サーバーのNIC 2枚が、別々のスイッチを経由して、ストレージのコントローラー2つに届きます。すると、同じLUNがサーバーに/dev/sdbと/dev/sdcの2つに見えます。2つのデバイスに別々にファイルシステムをマウントすると、同じディスクに2か所から書き込むことになり、データが壊れます。dm-multipathは、2つのデバイスが同じLUN(同じWWID)であることを見分けて、1つの/dev/mapper/mpathXにまとめます。1つのパスが切れると、別のパスにI/Oを渡し(failover)、設定によっては2つのパスを一緒に使うこともあります。multipath -llが、パスごとにactive・failedの状態を見せてくれます。
現場での姿
「再起動したらサーバーがemergencyシェルで止まった」のよくある原因が、_netdevのないiSCSIのfstabの行です。デバイスがまだないので、マウントを待ってタイムアウトになり、そのマウントに依存するサービスまで次々と止まります。新しいLUNを取り付ける作業計画書には、fstabの行と一緒に、「再起動後の自動ログイン・マウントの確認」が入ります。
マルチパスなしで、パスが2つあるLUNを使うのも、よくある事故です。lsblkに同じサイズのディスクが2つ見えたら、まずマルチパスを疑います。ストレージチームが「LUNを1つお渡ししました」と言ったのに、ディスクが2つ見えるなら、ほぼ確実です。そして、マルチパスデバイスは、/dev/sdXではなく、/dev/mapper/の下の名前で使います。
増設の依頼もよく来ます。ストレージ側でLUNを大きくしても、サーバーは知りません。SCSIデバイスを再読み込み(rescan)させ、マルチパスならマップのサイズを更新し、その上のPV・LV・ファイルシステムを順に拡張します。前のモジュールで見た「層ごとに別々に拡張する」が、さらに1層深くなったものです。
このモジュールのあとで
このモジュールは、読み物とクイズで終え、手を動かすのは、次のモジュールで性能測定と一緒に行います。同じVMの中にLIOターゲットを立ち上げてLUNを提供し、そのLUNにログインして_netdevでマウントしたあと、その上でfioでI/Oを測ります。マルチパスは、パスが1つしかないラボ環境では真似しかできないので、概念として扱います。