VPSでネスト仮想化してProxmoxを実行できる?
VPSでProxmoxやKVMのゲストを動かせるか、1分でkvm-okを使って確認できます。vmxまたはsvmフラグが隠されている場合のエラー文字列も紹介します。
短い回答
ネスト仮想化とは、仮想マシン内でハイパーバイザーを実行することです。VPS はすでにゲストであり、その中で独自のゲストをホストする構成です。これは、プロバイダーのハイパーバイザーが CPU の仮想化拡張機能をインスタンスに明示的に公開している場合に限って動作します。/proc/cpuinfo で vmx フラグ (Intel) または svm (AMD) を確認してください。どちらも表示されない場合、VPS 内でどのような設定をしても解決できません。
まず、期待値を調整しておきます。Docker にこの機能は必要ありません。 コンテナは VPS のカーネルを共有し、/dev/kvm に触れることもありません。実際の目的が「自分のサーバーで複数のサービスをコンテナで実行する」ことであれば、すでに必要なものは揃っています。ネスト仮想化が必要になるのは、別のカーネル、Proxmox の検証環境、Windows ゲスト、Firecracker microVM、Android エミュレーター、実 VM を使う Kubernetes のテスト環境、または VM イメージを起動する CI runner を実行する場合です。
実際にネストされるもの
3 つの層があります。
- L0 は、物理マシン上で動作するプロバイダーのハイパーバイザーです。ここにはアクセスできません。
- L1 は、使用している VPS です。L0 から見ると、単なるゲストです。
- L2 は、VPS 内で実行する VM です。
ハードウェア仮想化では、Intel の場合は VT-x(vmx フラグ)と EPT、AMD の場合は AMD-V / SVM(svm)と RVI/NPT を使用します。ハイパーバイザーはこれらの命令を使ってゲストモードに入り、CPU が 2 つのページテーブルを同時にたどれるようにします。
いずれも再入可能な動作を想定して設計されていないため、ネストはエミュレーションされます。L1 が VMX 命令を実行すると L0 にトラップし、L0 が L1 に代わって L2 用のシャドー構造を管理します。KVM はこの処理を適切に行いますが、各 exit で L0 に追加の処理が発生します。そのため、プロバイダー側で有効化する必要があります。
アクセラレーションを有効にした L2 を実行するには、次の 2 つの条件を両方満たす必要があります。
- L0 の KVM モジュールが
nested=1付きでロードされていること。 - L0 が、該当フラグを持つ CPU モデルを VPS に提供すること。libvirt では
<cpu mode='host-passthrough'/>、Proxmox ではcpu: host、raw QEMU では-cpu hostです。汎用のエミュレーションモデル(qemu64、kvm64)では、ネストがグローバルに有効でもvmxが隠されます。
VPS を 1 分で確認する
# 1. Are you in a VM, and under what?
systemd-detect-virt # kvm, vmware, xen, microsoft, or "none" on metal
# 2. Does the CPU expose the extensions to you?
grep -o -E 'vmx|svm' /proc/cpuinfo | sort -u
lscpu | grep -i -E 'virtual|hypervisor'
# 3. The definitive check
sudo apt update && sudo apt install -y cpu-checker
kvm-ok
# 4. The device node the whole stack depends on
ls -l /dev/kvm使用可能なインスタンスでは vmx または svm が表示され、kvm-ok は KVM acceleration can be used を示し、/dev/kvm は root:kvm モード 660 で存在します。フラグが存在するのにデバイスノードがない場合は、モジュールを手動でロードしてカーネルログを確認します。
sudo modprobe kvm_intel # or kvm_amd
sudo dmesg | tail -n 20常に引用され、広く誤解されているファイルがあります。
cat /sys/module/kvm_intel/parameters/nested # Y or NVPS 内では、これは 自身の KVM モジュールの設定です。L2 ゲストが第 3 レベルをネストできるかどうかを制御します。L0 がネストを有効にしたかどうかは示しません。その確認には /proc/cpuinfo と kvm-ok を使用します。nested パラメーターは、自分が完全に所有するマシンで設定する項目です。
echo 'options kvm_intel nested=1' | sudo tee /etc/modprobe.d/kvm-nested.conf
sudo modprobe -r kvm_intel && sudo modprobe kvm_intelVM の実行中はモジュールを削除できません。先にゲストを停止してください。
ほとんどの VPS ホスティング事業者が無効にしている理由
- ライブマイグレーション。
vmxを提供するには、そのフラグを持つ CPU モデルを公開する必要があります。その CPU 機能に依存するゲストは、それらの機能を持たない CPU のマシンへ安全に移行できません。顧客のノードをマイグレーションして排出するホストでは、ネスティングを有効にした時点でこの運用ができなくなります。 - 攻撃対象領域。 ネストされた VMX/SVM の処理経路は、カーネルの仮想化層でも特に複雑なコードであり、それに見合う CVE の履歴があります。
- L0 が KVM とは限りません。
systemd-detect-virtがvmware、xen、またはmicrosoftを出力する場合、ネスティングの規則は KVM ではなく、そのスタックの規則に従います。
インスタンスにフラグが表示されない場合は、サポートに問い合わせてください。一部の事業者では VM ごとに有効化できます。ネスティングを明記したプランを選ぶか、専用サーバーへ移行してください。以降は、フラグが表示されるマシンで root を使用していることを前提とします。
libvirt で L2 ゲストを実行する
sudo apt install -y qemu-system-x86 libvirt-daemon-system virtinst ovmf
sudo systemctl enable --now libvirtd
sudo usermod -aG libvirt,kvm "$USER" # log out and back in
virt-install \
--name guest1 \
--memory 2048 \
--vcpus 2 \
--cpu host-passthrough \
--disk path=/var/lib/libvirt/images/guest1.qcow2,size=20,format=qcow2,bus=virtio \
--network network=default,model=virtio \
--os-variant debian13 \
--location https://deb.debian.org/debian/dists/trixie/main/installer-amd64/ \
--graphics none \
--console pty,target_type=serial \
--extra-args 'console=ttyS0,115200n8'グラフィカルセッションは必要ありません。シリアルインストールにはしばらく時間がかかるため、永続シェル内で開始してください。同じ VPS 上で Claude Code セッションを維持する tmux のワークフローにより、SSH 接続が切断されても virt-install コンソールへの接続を維持できます。--os-variant debian13 が拒否される場合は、使用している osinfo-db がリリースより前のバージョンです。osinfo-query os を実行し、存在する名前を選択してください。--cpu host-passthrough は vmx を L2 へ転送します。これは、L2 でさらに仮想化する必要がある場合にのみ必要です。virsh autostart guest1 を使用して、ゲストが安全に起動できるようにします。
ディスクと NIC で使用する virtio バスは、単なる装飾ではありません。エミュレートされた IDE および e1000 デバイスでは、virtio キューよりも頻繁にハイパーバイザーへのトラップが発生します。ネスティング環境では、そのたびにトラップの処理コストが 2 重に発生します。
ネットワーク: チュートリアルで省略されがちな部分
VPS にはパブリック IP が 1 つあり、不明な MAC アドレスをフィルタリングするネットワーク基盤の背後にあります。ここから、2 つの結果が生じます。
L2 ゲストをパブリックネットワークにブリッジしても、通常は動作しません。 br0 をパブリック NIC に配置し、ゲストに独自の MAC を割り当てると、ARP が送信されても応答が返らない状態になります。プロバイダーのスイッチが、リースしていない MAC アドレスからのフレームを破棄するためです。この症状が出た場合は、ブリッジのデバッグを続けないでください。原因はこの仕組みにあります。
代わりに NAT ネットワークを使用してください。 libvirt には default が付属します。virbr0、192.168.122.0/24、dnsmasq のリースが利用でき、外向きの通信はすぐに動作します。内向きの通信では、L1 で TLS を終端してからプロキシします。以下の証明書パスは Nginx で Certbot を使用して Let's Encrypt 証明書を発行する の手順に基づいています。
server {
listen 443 ssl;
server_name lab.example.com;
ssl_certificate /etc/letsencrypt/live/lab.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/lab.example.com/privkey.pem;
location / {
proxy_pass http://192.168.122.50:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}最初にゲストへ静的リースを割り当ててください (virsh net-edit default)。これにより、proxy_pass 内のアドレスが変わらなくなります。
管理インターフェースはインターネットに公開しないでください。5900 の VNC と 8006 の Proxmox Web UI は loopback にバインドし、SSH トンネル (ssh -N -L 8006:127.0.0.1:8006 you@your-vps) 経由でアクセスします。または、VPS 内に自己ホスト型 WireGuard VPN を構築する 方法を使用します。これにより、192.168.122.0/24 ゲスト範囲全体へ、プライベートネットワーク上の 1 ホップで到達できます。ファイアウォールは狭く保ち、sudo ufw allow 22,80,443/tcp だけを許可してください。それ以外は許可しません。ufw を有効にした直後にゲストの外向き通信が失われた場合、通常の原因は /etc/default/ufw 内の DEFAULT_FORWARD_POLICY="DROP" です。ACCEPT に設定してから、ufw を再読み込みしてください。
VPS 上の Proxmox
Proxmox VE 9 の基盤は Debian 13 です。そのため、Debian VPS にインストールするには pve-no-subscription リポジトリと proxmox-ve パッケージを追加します。リポジトリと keyring の行は、Proxmox の公式ドキュメントにある現行の内容を使用してください。古いブログ記事からコピーした URL では、インストールに失敗します。そもそも Proxmox をレンタルハードウェアで運用すべきかは、以下のネットワーク設定に時間をかける前に決めておく価値があります。自宅の Proxmox 機とレンタル VPS のコストおよび機能の比較では、電力とハードウェアの計算を済ませたうえで、この問題を検討しています。
難しいのはパッケージではありません。Proxmox は vmbr0 を物理 NIC にブリッジする構成を想定しているため、上記の MAC フィルタリングによる行き詰まりに直結します。VPS で機能する構成は、物理ポートを割り当てない NAT またはルーティングされた vmbr0、プライベート範囲に配置したゲスト、そして外部公開するサービス用にホストへ設定した DNAT ルールまたはリバースプロキシです。外部公開するサービスが VM ではなくコンテナの場合は、1 つの Docker Compose ファイルから複数のアプリの前段に Traefik を置く構成で、同じルーティング処理を自動証明書付きで実現できます。最初に /etc/network/interfaces のスナップショットを取得してください。ブリッジ定義を誤ると、コンソールを利用できない可能性があるマシンから締め出されます。
正直な性能評価
Nested 構成は単一レベル構成より低速です。ただし、コストが広く分散するのではなく、発生箇所は明確です。コストがかかるのはメモリアクセスではなく、exit です。 EPT/NPT が有効な場合、L0 は L2 用の shadow page table を保持し、通常のメモリ読み取りはハードウェア速度で実行されます。コストが大きくなるのは、guest mode から抜ける操作です。I/O、タイマー割り込み、MMIO、プロセッサ間割り込みなどが該当します。L2 の exit は L0 が処理し、L1 を経由して返される場合があります。RAM にすでにあるデータを処理する CPU バウンドの処理は、ネイティブに近い性能になります。一方、システムコール、パケット、ディスク I/O が支配的な処理では、各層の影響が現れます。
そのため、デバイスには全面的に virtio を使用します。また、qcow2 ファイルは、プロバイダーがすでに仮想化しているディスク上に置かれます。これは thin provisioning の層が 2 つ重なった状態です。ゲストディスク上の cache=none によって、同じブロックが 2 つのページキャッシュに同時に存在する状態が止まります。ここではベンチマークの数値を示しません。自身のインスタンスで、自身のワークロードを測定してください。
障害パターンと表示される文字列
INFO: /dev/kvm does not exist / KVM acceleration can NOT be used が kvm-ok から表示されます。モジュールが読み込まれていないか、フラグが公開されていません。まず /proc/cpuinfo を確認してください。
kvm: disabled by bios が dmesg に表示されます。ベアメタルでは、ファームウェアで VT-x/SVM の切り替えを有効にしてください。VPS 内で表示される場合は、L0 が拡張機能をゲストに渡していないという意味です。ゲスト内で入力する操作によって変更することはできません。
modprobe: ERROR: could not insert 'kvm_intel': Operation not supported です。 カーネルが認識している CPU に vmx がありません。これも L0 側の判断です。
Could not access KVM kernel module: Permission denied です。 ハードウェアではなく、権限の問題です。ls -l /dev/kvm のグループは kvm、モードは 660 になっている必要があります。自分をそのグループに追加し、新しいログインシェルを起動してください。すでに実行中のセッションには、グループメンバーシップの変更は適用されません。
QEMU の起動時に kvm: Device or resource busy が表示されます。別のハイパーバイザーモジュールが CPU を保持しています。lsmod を実行し、kvm_intel とともに vboxdrv または VMware のモジュールを探してください。使用しないモジュールをアンロードします。
virsh から /var/run/libvirt/libvirt-sock: No such file or directory が表示されます。デーモンが停止しています。sudo systemctl enable --now libvirtd を実行してください。
Proxmox: KVM virtualisation configured, but not available. KVM アクセラレーションが、対応できないホスト上のゲストで有効になっています。ネスト構成を修正するか、設定を無効にしてエミュレーションを使用してください。
Android emulator: x86_64 emulation currently requires hardware acceleration! /dev/kvm と同じです。通常はグループ設定の問題です。
エラーはまったく表示されず、すべての処理が極端に遅い。 アクセラレーターフラグなしで QEMU を実行すると、ソフトウェアエミュレーターである TCG にフォールバックします。動作は正しいものの速度が遅く、数秒で完了するブートが数分かかるようになります。-accel kvm を明示的に指定してください。これにより、QEMU は黙ってエミュレーションに切り替えず、エラーで停止します。
ゲストが実行中に突然消える。 dmesg で Out of memory: Killed process ... qemu-system-x86_64 を確認してください。L2 ゲストは L1 上のプロセスであり、OOM killer は他のプロセスと同じように扱います。L2 の RAM は L1 に固定割り当てされたメモリから確保され、ホストから借用することはありません。
運用: バックアップ、アップグレード、制約
バックアップ。 実行中の guest の qcow2 をコピーすると、イメージが破損します。virsh shutdown guest1 を実行してからコピーするか、外部スナップショット(virsh snapshot-create-as guest1 snap1 --disk-only --atomic)を作成してください。外部スナップショットを作成すると、コピー中は書き込みがオーバーレイに振り分けられ、静的になったベースをコピーできます。その後、virsh blockcommit で変更をベースに統合します。コピーは VPS の外部へ転送してください。同じディスク上のスナップショットだけでは、障害から保護できません。
アップグレード。 apt full-upgrade は新しい kvm_intel/kvm_amd モジュールをインストールしますが、実行中の kernel が新しいモジュールを使用するのは再起動後です。以前の kernel はインストールしたままにし、kernel を変更するたびに kvm-ok を再実行してください。vmx がない状態でホストが起動しても、別のブートエントリを選べば復旧できます。
この構成の限界。 パブリック IP が 1 つしかない場合、すべての L2 サービスは L1 上のプロキシまたは DNAT ルールを経由して外部と通信します。ライブマイグレーションは利用できません。CPU が競合すると、最初に影響を受けるのは nested の exit パスです。また、複数の guest を持つ hypervisor は、その RAM をすでに割り当て済みのマシンです。nested VM は、固定された割り当てを overcommit で解消できません。ラボの規模がこの構成を超えた場合、nested の階層を増やすのではなく、専用のマシンに移行してください。そのマシンでは自分が L0 となるため、これらの制約は適用されません。
FAQ
Docker を VPS 上で実行するために、ネスト型仮想化は必要ですか?
いいえ。コンテナは VPS のカーネルを共有し、/dev/kvm を開くこともないため、vmx や svm フラグのない通常のインスタンスでも Docker と Docker Compose は問題なく動作します。ネスト型仮想化が必要になるのは、2 つ目のカーネルを実行する場合だけです。たとえば、Proxmox の検証環境、Windows ゲスト、Firecracker microVM、Android エミュレーター、VM イメージを起動する CI runner などです。
VPS がネスト型仮想化をサポートしているか確認するにはどうすればよいですか?
grep -o -E 'vmx|svm' /proc/cpuinfo | sort -u を実行し、続いて cpu-checker パッケージの kvm-ok を実行します。使用可能なインスタンスでは、vmx(Intel)または svm(AMD)が表示されます。kvm-ok では KVM acceleration can be used が報告され、/dev/kvm は group kvm、mode 660 で存在します。この質問では /sys/module/kvm_intel/parameters/nested は無視してください。このファイルが示すのはプロバイダーのハイパーバイザーが公開した機能ではなく、自身の KVM モジュールです。
ほとんどの VPS プロバイダーがネスト型仮想化を無効にしているのはなぜですか?
vmx を公開するには、そのフラグを持つ CPU モデルをゲストに提供する必要があります。その CPU 機能に依存するゲストは、対応する CPU を持たないマシンへライブマイグレーションできません。ノード間で顧客を移動してノードを停止するプロバイダーにとって、これは運用上の制約になります。また、ネストされた VMX/SVM のコードパスには長い CVE の履歴があります。それでも、一部のホストはリクエストに応じて VM ごとに有効化しています。ネスト型仮想化をプランの機能として明記しているプロバイダーもあります。
ネストされた VM がパブリックブリッジ上でネットワークに接続できません。何が問題ですか?
プロバイダーのスイッチは、リースしていない MAC address からのフレームを破棄します。そのため、パブリック NIC にブリッジ接続された L2 ゲストが ARP を送信しても、応答を受信できません。br0 の調査は中止し、libvirt の NAT default network(virbr0、192.168.122.0/24)を使用してください。ゲストには static lease を割り当て、公開するサービスは VPS 自体の reverse proxy または DNAT rule 経由で公開します。
ネストされた VM はどの程度遅くなりますか?
コストが発生するのは VM exit であり、メモリアクセスではありません。EPT/NPT が有効であれば、L2 内の通常の読み取りと書き込みはハードウェア速度で実行されます。一方、I/O、timer interrupt、MMIO、IPI は L0 が処理し、L1 を経由して戻される場合があります。すでに RAM にあるデータを処理する CPU-bound な処理はネイティブに近い速度になります。しかし、system call、packet、disk に負荷が集中するワークロードでは、各層のオーバーヘッドが現れます。すべてのデバイスに virtio を使用し、ゲストディスクでは cache=none を使用したうえで、自身のワークロードを測定してください。