午前2時の悪夢:サーバーリソースの枯渇
11月11日のセールが始まった直後、PostgreSQLサーバーのCPU使用率が突然100%に張り付きました。ロードアベレージは3.2から28へと跳ね上がり、16GBのRAMは枯渇してスワップが激しく発生し始めます。
通常、このような場合どう対処するでしょうか。緊急メンテの通知を送り、深夜のトラフィックが落ち着くのを待ってVMを停止し、ダッシュボードからスペックを引き上げる……というのが一般的かもしれません。しかし、そのわずか数分のダウンタイムによって決済中のトランザクションが大量に中断され、月間SLAを大きく損なうことになります。
本番稼働している私のProxmox VEクラスタでは、この課題をHotplug(ホットプラグ)によって完全に解決しました。この機能を利用すれば、VMが毎秒8,000リクエストを処理している最中でも、CPUコアの追加、16GBのRAM増設、ディスク容量の拡張を瞬時に実行できます。再起動もセッション切断も一切発生しません。
KVM/QEMUにおけるHotplugの動作メカニズム
KVMおよびQEMUは、物理コンポーネントのホットプラグに対応したサーバーマザーボードをエミュレートします。ホストとゲスト間の通信は、ACPIレイヤーとvirtioドライバ群を介して行われます。
- CPU Hotplug:
sockets × coresの計算式に基づいて最大vCPU上限をあらかじめ設定しておきます。リソース追加の指示を受けると、ホストがACPI割り込みを送信し、仮想マシン内のLinuxカーネルに対して待機中のコアをアクティブ化するよう通知します。 - RAM Hotplug: NUMAアーキテクチャを通じて仮想メモリモジュール(virtual DIMM)を割り当てることで動作します。ゲストOSはカーネルを再ロードすることなく、レジスタ上の新しいメモリアドレス空間を即座に認識します。
- Disk Hot-resize:
virtio-scsi-singleコントローラーを活用します。ホスト側でディスク容量を拡張した後、SCSIバスに再スキャン(rescan)シグナルを送信することで、ゲストカーネルがブロックデバイスを再認識・更新します。
前提条件:Proxmoxと内部OS間の双方向ステータス同期を確実に行うため、仮想マシン上でQEMU Guest Agentが動作している必要があります。
具体的な構築・設定手順
ステップ 1: QEMU Guest Agentのインストール
ハードウェア構成を変更する前に、仮想マシンとProxmox間の通信チャネルが正常に機能していることを確認します。
UbuntuまたはDebian仮想マシンの場合:
sudo apt update && sudo apt install -y qemu-guest-agent
sudo systemctl enable --now qemu-guest-agent
Rocky Linux、AlmaLinux、またはRHEL 8/9の場合:
sudo dnf install -y qemu-guest-agent
sudo systemctl enable --now qemu-guest-agent
ステップ 2: Proxmox VEでHotplugとNUMAを有効化
Proxmoxのデフォルト設定では、DiskとNetworkのみHotplugが有効になっています。CPUとRAMのホットプラグ構成を適用するために、初回の1度だけ約30秒のダウンタイムが必要です。
- Proxmox Web UIにアクセスし、対象VMを選択 > Options > Hotplug を開きます。
- Disk、Network、USB、Memory、CPU の5項目すべてにチェックを入れます。
- Hardware > Processors に移動し、Enable NUMA にチェックを入れます(RAMのホットプラグに必須)。
Proxmoxホストのターミナル操作に慣れている場合は、以下のコマンドを実行します(101は実際のVM IDに置き換えてください):
# すべてのホットプラグ機能を有効化
qm set 101 --hotplug disk,network,usb,memory,cpu
# NUMAを有効化
qm set 101 --numa 1
# 最大上限を8コアとして定義し、起動時は2コアのみ使用
qm set 101 --cores 8 --vcpus 2
仮想マシンを再起動します。これ以降、すべてのリソース拡張作業を100%オンライン(無停止)で実行できるようになります。
ステップ 3: 稼働中のCPUおよびRAMのオンライン増設
システムに過負荷の兆候が見られますか?VMのvCPUを2から4に引き上げ、RAM容量を4GB(4096MB)から8GB(8192MB)に拡張してみましょう。
Proxmox Shellからわずか数秒で実行可能です:
# 有効化するvCPU数を4に引き上げ
qm set 101 --vcpus 4
# RAMを8GBに拡張
qm set 101 --memory 8192
ステップ 4: 新しいハードウェアを自動認識するudevルールの設定
多くのLinuxカーネルは新たに追加されたvCPUやRAMを検出するものの、デフォルトでは offline 状態のままにする場合があります。/sys/devices/system/ 配下で各コアを手動でオンライン化する代わりに、udevを使って自動処理させましょう。
ゲスト仮想マシン内でルールファイルを作成します:
sudo tee /etc/udev/rules.d/80-hotplug-cpu-mem.rules << 'EOF'
# ホットプラグ時にCPUを自動でオンライン化
SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}="1"
# ホットプラグ時にRAMを自動でオンライン化
SUBSYSTEM=="memory", ACTION=="add", TEST=="state", ATTR{state}="online"
EOF
ルールを即座に再読み込みして適用します:
sudo udevadm control --reload-rules && sudo udevadm trigger
htop を起動するか free -m を実行してみてください。追加された2コアと4GBのRAMが即座に反映されていることが確認できます。
ステップ 5: アンマウント不要のディスク容量オンライン拡張(Hot-resize)
ディスク使用率100%は、データベースの書き込みロックや突然のクラッシュを引き起こす最大の要因の1つです。VMが VirtIO SCSI コントローラーを使用している場合、ディスク容量を瞬時に拡張できます。
まず、Proxmoxホスト側から scsi0 ディスクに20GBを追加割り当てします:
qm resize 101 scsi0 +20G
次に、Linux仮想マシンにSSH接続し、以下の3つのコマンドを実行します:
# 1. SCSIバスを再スキャンし、カーネルにsdaの新しい物理容量を認識させる
echo 1 | sudo tee /sys/class/block/sda/device/rescan
# 2. パーティション拡張ツールをインストール(未導入の場合)し、sda1を拡張
sudo apt install -y cloud-guest-utils || sudo dnf install -y cloud-utils-growpart
sudo growpart /dev/sda 1
# 3. ファイルシステムをオンラインで拡張
# EXT4ファイルシステムの場合:
sudo resize2fs /dev/sda1
# XFSファイルシステムの場合(Rocky/AlmaLinux/RHEL):
sudo xfs_growfs /
これで完了です。NginxやMySQLのプロセスがリクエストを正常に処理し続けたまま、ルートパーティションが20GB拡張されました。
本番環境における運用のポイント
- 無計画なHot-unplug(縮小)を避ける: リソースの追加(ホットアド)は極めて安全です。しかし、高負荷時にCPUを削減したりRAMを縮小(ホットアンプラグ)したりすると、メモリアドレスの急な消失によりカーネルパニックやプロセスクラッシュを引き起こすリスクがあります。リソースの縮小は計画的なメンテナンスウィンドウに実施してください。
- Windows Serverに関する注意点: 最新の
virtio-win-guest-tools.exeを導入してください。Windows Server 2016以降であれば、ホットプラグされたCPUとRAMを自動認識します。なお、Windows 10/11のHomeおよびProエディションはRAMのホットアドのみ対応しており、稼働中のCPU追加には対応していません。 - BallooningとHotplugの競合: Memory BallooningとHotplugを同時に有効にすると、Ballooningドライバが意図せずRAMを回収してしまうことがあります。データベースなどの安定したパフォーマンスを確保するため、最小RAM(Minimum RAM)を最大RAMの75〜80%程度に設定しておくことを推奨します。
まとめ
HotplugとNUMAをあらかじめ設定したテンプレートをわずか5分で用意しておくだけで、深夜の無駄な緊急メンテナンスから完全に解放されます。インフラリソースを柔軟に適応させる能力こそが、不安定なシステムと99.99%のSLAを達成するサービスの決定的な違いです。

