RDMA を使った共有ストレージは、Proxmox VE のクラスタで SAN を置き換える現実的な選択肢になりつつある。ただし、その設定手順は一般のネットワーク設定とは前提がかなり違う。この記事は、公式ドキュメントと Linux カーネルのドキュメントだけを頼りに、Proxmox へ RDMA を持ち込む手順を整理したものだ。この手順は実機で検証していない。 したがってここに書く数値やコマンドは、カーネル・ドライバ・ファームウェアの組み合わせによってはそのまま動かない可能性がある。それでも、手順の順序と分岐点を先に知っておく価値はあると考えている。
Proxmox に RDMA を持ち込む前に決めること
RDMA の設定に入る前に、決めておくべきことが3つある。HCA(Host Channel Adapter)をどう用意するか、どのプロトコルでストレージを繋ぐか、そして何を速くしたいのかである。
第一に、ハードウェアだ。RDMA は汎用の NIC では動かない。InfiniBand の HCA、または RoCE 対応の NIC が必要になる。中古の InfiniBand HCA(Mellanox の ConnectX 系など)は比較的安価に入手できるが、対応するケーブル(DAC / AOC)とスイッチを揃える必要がある。2ノードを直結する構成ならスイッチを省けるが、3ノード以上ではスイッチが要る。
第二に、プロトコルの選択である。RDMA は「転送の仕組み」であり、その上で何を動かすかは別の話だ。iSER、SRP、NVMe-oF、IPoIB といった選択肢があり、それぞれ対応状況が違う。Proxmox のバージョンによって使える選択肢が変わる点は、先に押さえておきたい。
第三に、目的の確認である。RDMA を入れる理由は、たいてい「レイテンシを下げたい」か「CPU 使用率を下げたい」のどちらかだ。前者なら小さなブロックのランダム I/O が効いてくるし、後者なら大きい転送で差が出る。目的を定めずに導入すると、効果が見えずに終わりやすい。
InfiniBand の基本構成 — HCA・サブネットマネージャ・IPoIB
InfiniBand の構成要素は、イーサネットとは名前からして違う。ここを押さえないと、後の手順が何をしているのか分からなくなる。
最小構成は、各ノードに HCA を挿し、ケーブルで接続する形だ。HCA はカーネルからは ib0 のようなインターフェースとして見える。この時点では IP アドレスは振られていない。InfiniBand はまず「ファブリック」として立ち上がり、その上に IP を載せるかどうかを後から選ぶ。
ファブリックにはサブネットマネージャ(SM)が必要である。SM は、どのノードがどのアドレスを持つかを管理する役割を担う。スイッチ内蔵の SM を使う構成もあれば、いずれかのノードで opensm を動かす構成もある。SM が動いていないと、ノード同士は物理的には繋がっていても通信できない。ここが最初のつまずきどころだ。
この上で IP 通信をしたい場合に使うのが IPoIB(IP over InfiniBand)である。IPoIB は InfiniBand 上で IP を運ぶ仕組みで、ib0 に IP アドレスを振れば、通常の TCP/IP アプリケーションからそのまま使える。手軽だが、RDMA の利点であるカーネルバイパスは効かない。IPoIB は「RDMA を使わずに InfiniBand を使う」方法だと理解しておくとよい。
IPoIB の設定手順 — カーネルモジュールと IP 割り当て
IPoIB の設定は、大きく3段階に分かれる。ドライバのロード、インターフェースの確認、IP の割り当てである。
まずドライバである。Mellanox 系の HCA なら mlx4_core や mlx5_core、IPoIB には ib_ipoib といったカーネルモジュールが要る。ディストリビューションによっては標準で入っているが、Proxmox VE のカーネル(Debian ベース)で利用できるかは、カーネルバージョンとファームウェアの組み合わせに依存する。modprobe でロードし、lsmod で確認する。
次にインターフェースの確認だ。ibstat や ibv_devices で HCA が認識されているかを見る。認識されていれば、ip link で ib0 が見えるはずだ。ここで見えなければ、ドライバかファームウェアの問題である。物理層の LED が点いているかも確認したい。
最後に IP の割り当てである。/etc/network/interfaces に ib0 の設定を書く。Proxmox VE は Debian のネットワーク設定をそのまま使うので、auto ib0 と iface ib0 inet static を追記し、アドレスとサブネットを指定する。MTU は IPoIB のモードによって変わる点に注意したい。datagram モードと connected モードで扱える MTU が違い、ここを揃えないとスループットが伸びない。
設定後は ifreload -a などで反映し、ping と ibstat の両方で確認する。IP が通っても RDMA のレートが出ていない、という状態が起こりうる。IP 層の疎通と RDMA 層の疎通は別物である。
iSER で iSCSI を RDMA 化する考え方
iSER は、iSCSI の転送を RDMA に置き換えたプロトコルである。iSCSI のターゲットとイニシエータの概念はそのままに、データ転送だけを RDMA に載せる。既存の iSCSI 運用があるなら、構造を変えずに性能を上げられる可能性がある。
ただし、Proxmox での対応状況には注意が要る。Proxmox VE はバージョンによって iSER のサポート状況が変わり、あるバージョンで対応していたものが後のバージョンで外れた、という経緯がある。公式ドキュメントやリリースノートで、自分のバージョンが iSER に対応しているかを必ず確認したい。ここは机上の整理だけでは判断できない部分である。
iSER を動かす前提として、RDMA のカーネルモジュール、iSER のカーネルモジュール(ib_isert)、そしてターゲット側の設定が必要になる。ターゲットには LIO(Linux-IO)が使われることが多く、targetcli でバックストアを定義する。イニシエータ側では iscsiadm の設定に RDMA 用のトランスポートを指定する。
机上で組み立てると、ここで「対応しているはずのモジュールがロードできない」という壁に当たりやすい。ドライバとカーネルモジュールは、カーネルバージョンに強く依存する。手順をなぞる前に、modinfo でモジュールの存在を確認する習慣をつけたい。
NVMe-oF という選択肢 — ブロックをそのままネットワークへ
iSER と並んで検討したいのが NVMe-oF(NVMe over Fabrics)である。NVMe-oF は、ローカルの NVMe デバイスを扱うためのコマンド体系を、そのままネットワーク越しに拡張した仕様だ。RDMA はその代表的なトランスポートのひとつで、ほかに TCP も選べる。
NVMe-oF の利点は、プロトコルスタックが薄いことにある。iSCSI のような SCSI 層を挟まず、NVMe のキューをそのまま遠隔に置く発想である。キューが深く、並列度を上げやすい。RDMA と組み合わせたときのレイテンシは、iSCSI 系より有利になりやすい。
一方で、ターゲット側の実装が課題になる。カーネル側の nvme-rdma モジュールとユーザー空間の nvme-cli を使う構成のほか、SPDK のようなユーザー空間実装でターゲットを立てる構成もある。後者は性能を追いやすいが、専用の設計と運用知識が要る。
Proxmox のゲストにブロックデバイスとして渡すなら、クラスタ全体で共有できるストレージとして定義する必要がある。Proxmox のストレージ定義はプラグイン方式で、iSCSI や Ceph は標準で用意されている。NVMe-oF を自前で組む場合は、この定義をどう扱うかを先に決めておきたい。
Proxmox が対応する RDMA 機能とバージョンの制約
Proxmox VE は、RDMA 関連の機能をすべて自前で提供しているわけではない。多くは Debian カーネルとユーザー空間のツールに依存している。したがって、対応状況は「Proxmox のバージョン × カーネル × ドライバ」の組み合わせで決まる。
たとえば、NVMe-oF を使う場合はカーネル側の nvme-rdma モジュールと、ユーザー空間の nvme-cli が要る。iSER は前述のとおりサポートが揺れやすい。SRP はさらに限定的である。
つまり、RDMA を組むという作業は、Proxmox の設定というより、Linux のストレージスタックを組む作業に近い。Proxmox 側でやることは、ネットワークインターフェースの定義と、ストレージのマウント設定くらいである。この構造を理解しておくと、トラブルの切り分けがしやすい。
また、クラスタ機能との関係も見ておきたい。Proxmox のクラスタは Corosync でノード間通信を行うが、これは RDMA を前提にしていない。RDMA を活かせるのは、あくまでゲストのストレージ I/O の経路である。クラスタ通信を速くしたいのか、ゲストのストレージを速くしたいのかで、設定する場所が違う。
ゲストにストレージを渡すときの設計
RDMA で組んだストレージは、最終的にゲスト(仮想マシン)へ渡す必要がある。ここで設計を誤ると、せっかくの低レイテンシが効かない。
共有ブロックストレージを複数ノードから同時に使う場合、ファイルシステムの選択が問題になる。複数ノードからの同時マウントを前提とするなら、クラスタファイルシステムか、あるいは共有 LUN を各ゲストに専有させる構成を選ぶ。同じ LUN を複数のゲストが同時に読み書きする構成は、データを壊す。
また、ライブマイグレーションを前提にするなら、ストレージが全ノードから見えている必要がある。ローカルディスクに置いたゲストは、マイグレーションできないか、ディスク転送を伴う。共有ストレージを入れる動機の多くは、この可用性の要求にある。
ゲストのディスクキャッシュ設定(cache=writeback や cache=none など)も、性能と安全性のトレードオフになる。RDMA でレイテンシを下げた分、キャッシュ設定の影響が相対的に見えやすくなる。ここは実機で測らないと判断できない領域だ。
共有ストレージの選択 — レイテンシとコストのトレードオフ
RDMA を前提に置いたとき、共有ストレージの選択肢はいくつかある。ここで整理しておきたいのは、それぞれが何を犠牲にしているかである。
InfiniBand + iSER は、既存の iSCSI 運用を活かしやすい。ただし対応バージョンの制約がある。NVMe-oF は、ブロックデバイスをネットワーク越しに扱う前提で設計されており、RDMA との相性がよい。ただしターゲット側の実装を別途用意する必要がある。Ceph は分散ストレージであり、内部で RDMA を使う構成もあるが、設定の複雑さは別次元になる。
コストの観点では、中古の InfiniBand 機材は魅力的に見える。しかし、ケーブル、スイッチ、そして何より「動かすための知識」がコストである。ここを軽く見積もると、導入後に時間を失う。
私が実機で組むとしたら、まず2ノード直結で IPoIB から入り、疎通と基本性能を確認してから iSER や NVMe-oF に進む順序を選ぶ。最初から RDMA のフル性能を狙うと、問題の切り分けができなくなる。
机上の手順を実機で確認するときのチェックリスト
机上の整理を実機に移すとき、確認すべき項目を残しておく。これは実機が手元にない段階でも、準備として使える。
- HCA が認識されているか(
lspci/ibstat) - 必要なカーネルモジュールが存在し、ロードできるか(
modinfo/modprobe) - サブネットマネージャが動いているか(
opensmの状態、スイッチ内蔵 SM の設定) ib0に IP が割り当てられ、疎通するか(ip addr/ping)- IPoIB の MTU がモードに合っているか
- ストレージ側のトランスポート(iSER / NVMe-oF など)が自分の Proxmox バージョンで使えるか
- ゲストへの渡し方(共有か専有か)とクラスタファイルシステムの要否
- クラスタ通信(Corosync)とストレージ経路が混ざっていないか
これらは、実機が届いた初日に順に潰していくための一覧である。机上の段階で用意しておけば、当日の迷いが減る。
まとめ — 手順より先に「何を速くしたいか」を決める
Proxmox へ RDMA を持ち込む手順を、公式資料に沿って整理した。この記事の内容は実機で検証していないため、数値やコマンドをそのまま信用せず、自分の環境のカーネルとドライバで確認してほしい。
順序としては、HCA の認識、カーネルモジュール、サブネットマネージャ、IPoIB の疎通、そしてストレージトランスポートの選択という流れになる。どの段階でも、IP 層の疎通と RDMA 層の疎通は別物だという点が効いてくる。
そして最も大事なのは、何を速くしたいのかを先に決めることである。クラスタ通信なのか、ゲストのストレージ I/O なのか、バックアップの転送なのか。目的が定まっていれば、必要なプロトコルと構成は自然に絞られる。目的が曖昧なまま機材から入ると、性能が出ないまま複雑さだけが残る。