ライブマイグレーションの深淵:Pre-copyとPost-copyを理解し、ダウンタイムを「ゼロ」に近づける技術
こんにちは。クラウドの深淵をのぞき込み、パケットの呼吸を感じるSREの現場からお伝えします。
「仮想マシンのライブマイグレーション」。一見すると、魔法のように稼働中のOSを物理ホスト間で移動させるこの技術ですが、その裏側では、メモリ上の膨大なデータがネットワークを介して凄まじい勢いで転送されています。
特に大規模なWebサービスを運用していると、ホストのメンテナンスやリソースの負荷平準化のために、このマイグレーションを避けては通れません。今回は、ライブマイグレーションの心臓部である「メモリ転送方式(Pre-copyとPost-copy)」について、理論と実務の境界線を掘り下げていきましょう。
—
1. ライブマイグレーションの基本戦術:Pre-copy方式
「Pre-copy」は、現在のライブマイグレーションにおけるデファクトスタンダードです。その名の通り、仮想マシン(VM)を停止させる「前」に、メモリデータをコピーし続ける手法です。
動作のフロー
1. 反復転送(Iterative Copy): VMを稼働させたまま、全メモリページをコピーします。この間もVMは書き込みを行うため、コピーが終わる頃にはまた「差分」が発生しています。
2. 収束(Convergence): 差分が小さくなるまで繰り返し転送します。
3. サスペンドと最終転送: 最後にVMを極短時間(数十ミリ秒)停止させ、残った差分とCPUの状態を転送して、移行先で再開します。
この方式の最大の利点は、「失敗しても元に戻せる」という安全性です。移行中にネットワークが切れても、移行元が生きている限りサービスは継続できます。
—
2. 攻めの戦術:Post-copy方式
Pre-copyは、メモリの更新頻度が激しい(Dirty Pageの発生が多い)DBサーバーなどでは、いつまで経っても終了しない「無限ループ」に陥ることがあります。これを打破するのが「Post-copy」です。
動作のフロー
1. サスペンド: VMを移行元で即座に停止させます。
2. CPU状態の転送: CPUレジスタなどの最小限の情報を移行先へ送ります。
3. 再開: 移行先でVMを即座に起動します。
4. オンデマンド取得: VMがアクセスしたメモリ領域がまだ移行先にない場合、その都度ネットワーク経由で移行元から引っ張ってきます。
メリットは「確実に終わること」ですが、最大の弱点は「移行中にネットワークが切れるとVMがクラッシュする」という脆弱性です。
—
3. 実務で役立つ設定とデバッグの勘所
KVM/QEMU環境でマイグレーションを制御する場合、virshコマンドやXML設定ファイルが頼りになります。
QEMUでのマイグレーションパラメーター設定例
ライブマイグレーションのパフォーマンスを左右するのは、migrate_set_speedとmigrate_set_downtimeのバランスです。
# 1. 移行中のネットワーク帯域制限を解除(最大速度を指定)
# ネットワークカードの限界まで使い切る設定
virsh qemu-monitor-command <ドメイン名> --hmp "migrate_set_speed 10Gbps"
# 2. 許容するダウンタイムを50ミリ秒に設定
# これを絞りすぎるとPre-copyが収束しません
virsh qemu-monitor-command <ドメイン名> --hmp "migrate_set_downtime 0.05"
Pythonで移行状況を監視する(簡易スクリプト)
現場で「いつ終わるんだ?」と焦ることはよくあります。libvirt APIを使って、転送進捗をリアルタイムで追跡するコード例です。
import libvirt
import time
def monitor_migration(dom):
while True:
# 移行状態を取得
stats = dom.jobInfo()
# type 1 はマイグレーション中
if stats.type == 1:
print(f"転送済み: {stats.dataRemaining} bytes / 残り: {stats.memTotal} bytes")
else:
print("マイグレーション完了または中断")
break
time.sleep(1)
# 接続とドメイン取得
conn = libvirt.open('qemu:///system')
dom = conn.lookupByName('web-server-01')
monitor_migration(dom)
—
4. 現場のシニアエンジニアからの一言
ライブマイグレーションにおいて、最も注意すべきは「ネットワークの帯域」と「メモリのDirty Rate」の競合です。
- Dirty Rateが高い場合: アプリケーション側でキャッシュを大量に書き換えるような処理があると、Pre-copyは一生終わりません。この場合、
migrate-auto-convergeを有効にし、あえてCPU実行速度を落としてメモリ更新を抑制するオプションを検討してください。 - Post-copyを使うべき時: 「移行失敗」よりも「長時間停止することによるタイムアウト(APIの504エラー等)」の方が深刻な場合、Post-copyへの切り替えが有効です。
ネットワークエンジニアとしてのアドバイスですが、マイグレーション専用の物理NICを切り出しておくか、VLANで帯域を分離しておくことは、大規模環境では必須の「お作法」です。管理トラフィックがユーザーのトラフィックを圧迫しないよう、設計段階でケアしておきましょう。
技術は教科書通りには動きません。パケットのゆらぎや、OSのメモリ管理アルゴリズムがマイグレーションにどう影響するか。その「泥臭い挙動」を理解した時、あなたは本当の意味でクラウドを制御できるようになります。
それでは、また次回の深掘り記事でお会いしましょう。運用が平和であることを祈ります。
コメント