ゼロダウンタイムの魔法:ライブマイグレーションの裏側にある「メモリ同期」の執念
「VMを落とさずに物理ホストを移動させる」。クラウドネイティブな世界にどっぷり浸かっていると、ライブマイグレーションは当たり前の機能に思えるかもしれない。だが、裏側で何が起きているかを知れば、その「執念深さ」に戦慄するはずだ。
今日は、ハイパーバイザーの深淵、ライブマイグレーションのメモリ転送シーケンスについて深掘りしよう。これは単なる技術解説ではない。パケットロスを許さない、エンジニアたちの泥臭い戦いの記録だ。
—
1. ライブマイグレーションの正体:メモリの「追いかけっこ」
ライブマイグレーションの基本戦略は、「全メモリをコピーしつつ、コピー中に書き換えられた差分を追いかけ続ける」というものだ。これには大きく分けて3つのフェーズがある。
1. Iterative Pre-copy(反復事前コピー): まだVMが動いている状態でメモリをコピーする。
2. Stop-and-Copy(最終転送): VMを数ミリ秒だけ停止し、最後に残った「Dirty Pages(書き換えられたメモリ領域)」を転送する。
3. Resume(再開): 移行先でVMの実行を再開し、元のホストのメモリを解放する。
ネットワークエンジニアとして注目すべきは、この「Dirty Pages」の転送速度だ。もしアプリケーションが激しくメモリを書き換えるタイプ(例えば大規模なインメモリキャッシュや高負荷のDB)だと、追いかけっこが終わらず、ライブマイグレーションがいつまでも完了しない「スタベーション」を引き起こす。
—
2. 通信シーケンスのリアル:Dirty Pageの追跡
ハイパーバイザー(KVM/QEMUなど)は、メモリの変更を検知するために dirty bitmap という仕組みを使う。
- ステップ1: ソースホストが全メモリをコピー開始。
- ステップ2: コピー中もVMは動き続ける。書き換えられたページは
dirty bitmapにマークされる。 - ステップ3: ソースホストは
dirty bitmapを見に行き、変更があったページだけを再度転送する。 - ステップ4: 「残りの転送時間がネットワーク帯域で収まる」と判断されるまで、これを繰り返す。
ここで重要になるのが downtime(ダウンタイム許容値)の設定だ。
QEMUでの設定例(コマンドライン引数)
実際にライブマイグレーションをトリガーする際、QEMU Monitorや管理ツール(libvirtなど)で以下のような設定が飛ぶ。
# ライブマイグレーションの制限設定(QEMUモニター経由のイメージ)
# 転送帯域を1Gbpsに制限し、ダウンタイム許容を300msに設定
migrate_set_speed 1000000000
migrate_set_downtime 0.3
migrate_set_speed: 移行専用のネットワーク帯域を占有しすぎないよう調整する。migrate_set_downtime: これが小さすぎると、Dirty Pageが減らずにマイグレーションがタイムアウトする。
—
3. 実務で遭遇する「ライブマイグレーション失敗」の勘所
現場でよくあるのは、「負荷が高い時に限ってライブマイグレーションが失敗する」というケースだ。これをデバッグするためのPythonスクリプトの断片を紹介しよう。QMP(QEMU Machine Protocol)を通じて現在のマイグレーション状態を監視するロジックだ。
import json
# QMPソケット経由でマイグレーション状態を取得する想定
def check_migration_status(qmp_socket):
# 'query-migrate' コマンドを発行
status = qmp_socket.execute("query-migrate")
# 転送済みデータ量とDirty Pageの残量を確認
ram = status.get("ram", {})
remaining = ram.get("remaining", 0)
dirty_rate = ram.get("dirty-pages-rate", 0)
print(f"残りデータ量: {remaining} bytes")
print(f"Dirty Page発生率: {dirty_rate} pages/sec")
if remaining > 1024 * 1024 * 100: # 100MB以上残っていたら警告
print("警告: 転送が追いついていません。ネットワーク負荷を確認してください")
ネットワークエンジニアへのTips
もし本番環境でライブマイグレーションが失敗し続けるなら、以下の3点を確認してほしい。
1. MTUの不一致: マイグレーションのパケットは巨大になりがちだ。ジャンボフレームが有効か、途中のスイッチで破棄されていないか。
2. 専用NICの分離: 管理用トラフィックとデータプレーンを同じNICで流すと、マイグレーション中に帯域枯渇が起きる。必ずマイグレーション専用の物理NIC/VLANを用意すること。
3. Dirty Rateの監視: アプリケーションの書き込み負荷が高すぎる場合、ライブマイグレーションはそもそも「不可能な作戦」になる。その場合は「一時的にアプリの負荷を落とす」か「オフラインマイグレーションを選択する」という勇気が必要だ。
—
最後に:完璧な技術はない
ライブマイグレーションは、物理的な限界と論理的な一貫性の間を縫うギリギリの操作だ。どんなに優れたハイパーバイザーでも、ネットワーク帯域がなければただの遅いコピーに過ぎない。
今日伝えたかったのは、コマンドを叩くことではなく、「裏でパケットがどのように流れ、どのタイミングでVMが停止するのか」というシーケンスをイメージする力だ。それができれば、インフラ運用はもっと面白くなるし、トラブルシューティングも恐ろしくなくなるはずだ。
次は、マイグレーション中のTCPセッションがなぜ切れないのか、Gratuitous ARPとスイッチのMAC学習のタイミングについて深く掘り下げてみよう。現場からは以上だ。
コメント