仮想化の魔法を支える「ライブマイグレーション」の深淵:共有ストレージ vs 無共有型
「ライブマイグレーション」という言葉を聞いて、皆さんは何を想像しますか?VMを止めることなく、まるで神の手が移動させるかのようにホストを跨ぐあの挙動。裏側で一体何が起きているのか、その仕組みを理解せずに運用するのは、正直言って「時限爆弾」を抱えて走っているようなものです。
今日は、SREとして数多の障害現場を潜り抜けてきた経験から、この「仮想マシンの移動」を支える二つの流儀――共有ストレージ型と無共有型について、パケットの呼吸を感じるレベルで掘り下げていきましょう。
—
1. 共有ストレージ型:王道のマイグレーション
多くの企業が採用しているのは、NFSやiSCSI、ファイバチャネル(FC)を用いた共有ストレージ型です。
なぜこれが「王道」なのか
この方式の肝は「データは動かさない」ことにあります。仮想マシンのディスクイメージは共有ストレージ上にあり、移動先ホストと移動元ホストの両方がそのボリュームをマウントしています。
マイグレーション時に移動するのは以下の3つだけ。
1. メモリ上の状態(RAMの内容)
2. CPUレジスタの状態
3. デバイスのステート
パケットの挙動としては、移動元ホストがメモリのダーティページを繰り返し転送し、最後に停止した瞬間に残りのデータを同期させ、移動先でVMが再開されるというフローです。
実務的な落とし穴
共有ストレージ型は高速ですが、ネットワークの「遅延」と「帯域」がボトルネックになります。特に10Gbps未満のネットワークで巨大なメモリを積んだVMをマイグレーションしようとすると、転送が収束せず、いつまで経ってもマイグレーションが終わらない「コンバージェンス失敗」に陥ります。
—
2. 無共有型(Shared-nothing):ネットワークの限界に挑む
一方で、共有ストレージを持たない構成や、データセンターを跨ぐような環境で必要になるのが「無共有型マイグレーション(Storage Migration)」です。
NBD(Network Block Device)による泥臭い同期
共有ストレージがない場合、ディスクイメージそのものをネットワーク経由でコピーしなければなりません。ここで登場するのが NBD です。
1. フェーズ1(初期同期): 全ディスクブロックをバックグラウンドでコピー。
2. フェーズ2(反復転送): コピー中に書き込まれた差分ブロックを追跡し、転送。
3. フェーズ3(最終同期): VMを一時停止し、残りの数MBを送り込んでスイッチオーバー。
このプロセスは、言わば「巨大なファイルをネットワーク経由でコピーしながら、その最中にファイルを書き換え続ける」という離れ業です。
—
3. 実践:ライブマイグレーションを監視する
実務において、マイグレーションが詰まった時に「どこで何が起きているか」を確認する方法を知っておくことは重要です。例えば、QEMU/KVM環境であれば、virsh コマンドで状態を追いかけます。
# マイグレーションの進行状況を確認するコマンド
# 転送量(remaining)が0に近づいているかを見守るのがSREの日常
virsh domjobinfo <ドメイン名>
# 実行例の出力イメージ
# Job type: Unbounded
# Time elapsed: 12000 ms
# Data processed: 1024 MB
# Data remaining: 512 MB <-- ここが減り続けているかを確認
また、もしPythonで自動化ツールを組むなら、libvirt APIを叩いて統計情報を定期的に取得するスクリプトを書いておくと便利です。
import libvirt
def monitor_migration(dom):
# ドメインのジョブ情報を取得
stats = dom.jobInfo()
# 転送残量(remaining)が一定以下になったら注意を払う
print(f"残り転送量: {stats['memRemaining']} bytes")
# 接続先の設定
conn = libvirt.open('qemu:///system')
dom = conn.lookupByName('web-api-server-01')
# 監視ループの断片
if dom.isActive():
monitor_migration(dom)
—
4. 現場で役立つチューニングTips
最後に、現場でトラブルに直面した時に効く設定パラメーターを教えます。
migrate_downtime:
マイグレーションの最終段階でVMを停止する時間(ミリ秒)です。デフォルトでは短いですが、DBサーバーなどディスクI/Oが激しいVMでは、ここを少し長めに取らないと収束しません。
migrate_set_speed:
ネットワーク帯域を使い切らないよう制限をかけます。500mbps 程度に絞ることで、本番トラフィックへの影響を抑えるのが賢明なSREの作法です。
# virshでマイグレーション速度を制限する例
virsh migrate-setmaxdowntime <ドメイン名> 100 # 100msまで許容
virsh migrate-setspeed <ドメイン名> 500 # 500Mbpsに制限
最後に
ライブマイグレーションは、単なる「便利な機能」ではありません。それは、物理層の制約を仮想層の抽象化でいかに隠蔽するかという、ネットワークエンジニアの「美学」の塊です。
もし皆さんがマイグレーションの失敗に遭遇したら、まずは ping でのRTT(往復遅延)を確認し、次にディスクI/Oのレイテンシを疑ってください。パケットは嘘をつきません。今のネットワーク帯域とVMの書き込み速度のバランスが取れているか、常に計算することが、安定したインフラ運用への第一歩です。
それでは、次回の記事では「ライブマイグレーション中のTCP再送制御」について、さらに深掘りしていきましょう。現場からは以上です。
コメント