VPS에서 Proxmox 중첩 가상화 실행 가능 여부 확인
대부분의 VPS는 보안상 vmx 플래그를 숨깁니다. kvm-ok 명령어로 가상화 지원 여부를 1분 만에 확인하는 방법과 KVM 실행 시 발생하는 오류 메시지, 그리고 중첩 가상화가 반드시 필요한 경우와 그렇지 않은 경우를 명확히 구분하여 설명합니다.
간단한 답변
중첩 가상화(Nested virtualization)는 가상 머신 내부에서 실행되는 하이퍼바이저를 의미합니다. 즉, 이미 게스트 상태인 VPS가 자체적으로 또 다른 게스트를 호스팅하려는 경우입니다. 이는 서비스 제공업체의 하이퍼바이저가 CPU의 가상화 확장 기능을 인스턴스에 의도적으로 노출할 때만 작동합니다. /proc/cpuinfo를 확인하여 Intel의 경우 vmx 플래그가, AMD의 경우 svm 플래그가 있는지 확인하십시오. 두 플래그 모두 보이지 않는다면 VPS 내부에서 어떤 설정을 하더라도 해결할 수 없습니다.
먼저 기대치를 명확히 하겠습니다. Docker는 이 기능이 전혀 필요하지 않습니다. 컨테이너는 VPS의 커널을 공유하며 /dev/kvm를 사용하지 않습니다. 만약 실제 목표가 "서버에서 여러 서비스를 컨테이너로 실행하는 것"이라면 이미 필요한 환경을 갖춘 상태입니다. 중첩 가상화가 필요한 경우는 두 번째 커널이 필요하거나, Proxmox 실습, Windows 게스트 실행, Firecracker microVM 사용, Android 에뮬레이터 구동, 실제 VM 기반의 Kubernetes 테스트베드 구축, 또는 VM 이미지를 부팅하는 CI 러너를 운영할 때입니다.
실제로 중첩되는 대상
세 개의 계층이 존재합니다.
- L0: 베어메탈 위에서 동작하는 공급자의 하이퍼바이저입니다. 사용자는 이 계층에 접근할 수 없습니다.
- L1: 사용자의 VPS입니다. L0의 관점에서는 하나의 게스트일 뿐입니다.
- L2: VPS 내부에서 실행하려는 VM입니다.
하드웨어 가상화는 Intel의 경우 VT-x(vmx 플래그)와 EPT, AMD의 경우 AMD-V / SVM(svm)과 RVI/NPT로 구성됩니다. 하이퍼바이저는 이러한 명령어를 사용하여 게스트 모드로 진입하고 CPU가 두 개의 페이지 테이블을 동시에 참조하도록 합니다.
이 명령어들은 재진입(re-entrant)을 고려하여 설계되지 않았으므로 중첩은 에뮬레이션 방식으로 구현됩니다. L1이 VMX 명령어를 실행하면 L0로 트랩(trap)이 발생하며, L0는 L1을 대신하여 L2를 위한 섀도우 구조를 유지합니다. KVM은 이 작업을 잘 수행하지만, 매 종료(exit)마다 L0가 추가적인 작업을 수행해야 하므로 공급자가 이를 허용해야만 합니다.
가속화된 L2를 사용하려면 다음 두 가지 조건이 모두 충족되어야 합니다.
- L0의 KVM 모듈이
nested=1옵션으로 로드되어야 합니다. - L0가 VPS에 해당 플래그를 포함하는 CPU 모델을 제공해야 합니다. 이는 libvirt에서는
<cpu mode='host-passthrough'/>, Proxmox에서는cpu: host, 원시 QEMU에서는-cpu host로 설정합니다. 일반적인 에뮬레이션 모델(qemu64,kvm64)은 중첩이 전역적으로 활성화되어 있더라도vmx을 숨깁니다.
1분 안에 VPS 확인하기
# 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 기능에 의존하는 게스트는 해당 기능이 없는 머신으로 안전하게 마이그레이션할 수 없습니다. 고객을 마이그레이션하여 노드를 비우는 호스트는 중첩 가상화를 활성화하는 순간 이 기능을 포기해야 합니다. - 공격 표면. 중첩된 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 큐보다 하이퍼바이저를 훨씬 더 자주 호출하며, 중첩 가상화 환경에서는 모든 호출 비용이 두 배로 발생합니다.
네트워킹: 튜토리얼에서 생략하는 부분
VPS는 하나의 공인 IP를 가지며 알 수 없는 MAC 주소를 차단하는 네트워크 구조 내에 위치합니다. 이로 인해 두 가지 결과가 발생합니다.
L2 게스트를 공인 네트워크에 브리지로 연결하는 방식은 일반적으로 작동하지 않습니다. 공인 NIC에 br0를 설정하고 게스트에 고유 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 웹 UI는 루프백 주소에 바인딩하고, SSH 터널(ssh -N -L 8006:127.0.0.1:8006 you@your-vps)을 통하거나 VPS에 직접 호스팅하는 WireGuard VPN을 통해 접속해야 합니다. 이렇게 하면 전체 192.168.122.0/24 게스트 대역을 사설 네트워크 한 홉 거리로 둘 수 있습니다. 방화벽은 sudo ufw allow 22,80,443/tcp만 허용하도록 엄격하게 유지하십시오. ufw를 활성화한 직후 게스트의 아웃바운드 연결이 끊긴다면, 보통 /etc/default/ufw 내의 DEFAULT_FORWARD_POLICY="DROP" 설정이 원인입니다. 이를 ACCEPT으로 변경하고 ufw를 다시 로드하십시오.
VPS에서의 Proxmox
Proxmox VE 9는 기반이 Debian 13이므로, pve-no-subscription 저장소를 추가하고 proxmox-ve 패키지를 설치하여 Debian VPS에 올릴 수 있습니다. 저장소와 키링 설정 줄은 반드시 Proxmox의 최신 공식 문서에서 가져와야 합니다. 오래된 블로그 게시물에서 복사한 URL은 설치 실패의 원인이 됩니다. Proxmox를 임대 하드웨어에 설치하는 것이 적절한지 여부는 아래의 네트워크 설정을 시작하기 전에 결정해야 합니다. 가정용 Proxmox 서버와 임대 VPS 간의 비용 및 성능 비교 문서는 전력과 하드웨어 계산을 이미 마친 상태에서 이 질문에 대한 답을 제공합니다.
패키지 설치는 어려운 부분이 아닙니다. Proxmox는 물리적 NIC에 브리지된 vmbr0을 요구하는데, 이는 앞서 언급한 MAC 필터링 문제로 직결됩니다. VPS에서 정상적으로 작동하는 구성은 물리적 포트가 연결되지 않은 NAT 또는 라우팅 방식의 vmbr0을 사용하는 것입니다. 게스트는 사설 대역에 배치하고, 공개 서비스는 호스트의 DNAT 규칙이나 리버스 프록시를 통해 처리합니다. 공개 서비스가 VM이 아닌 컨테이너 형태라면, 하나의 Docker Compose 파일로 여러 앱을 처리하는 Traefik 가이드가 자동 인증서 발급을 포함한 동일한 라우팅 작업을 다룹니다. 작업을 시작하기 전에 /etc/network/interfaces 스냅샷을 먼저 생성하십시오. 잘못된 브리지 설정은 콘솔 접근이 불가능한 서버에서 사용자를 영구적으로 차단할 수 있습니다.
성능에 대한 솔직한 평가
중첩 가상화는 단일 계층보다 느리며, 그 원인은 분산된 것이 아니라 구체적인 메커니즘에 있습니다. 비용이 발생하는 지점은 메모리 접근이 아니라 VM exit입니다. EPT/NPT가 활성화된 상태에서 L0는 L2를 위한 섀도 페이지 테이블을 유지하며, 일반적인 메모리 읽기는 하드웨어 속도로 수행됩니다. 비용이 발생하는 지점은 게스트 모드를 벗어나는 모든 작업, 즉 I/O, 타이머 인터럽트, MMIO, 프로세서 간 인터럽트입니다. L2 exit는 L0가 처리하며, 다시 L1으로 전달될 수 있기 때문입니다. RAM에 이미 로드된 데이터를 처리하는 CPU 집약적 작업은 네이티브 환경과 유사한 성능을 보이지만, 시스템 콜, 패킷 처리, 디스크 I/O가 주를 이루는 작업은 계층 구조의 영향을 받습니다.
따라서 모든 장치에 virtio를 사용해야 합니다. 또한 qcow2 파일이 이미 공급자가 가상화한 디스크 위에 존재한다면, 두 개의 씬 프로비저닝 계층이 쌓인 상태가 됩니다. 이때 게스트 디스크에서 cache=none를 사용하면 동일한 블록이 두 개의 페이지 캐시에 동시에 머무르는 현상을 방지할 수 있습니다. 벤치마크 수치는 제공하지 않습니다. 본인의 인스턴스에서 직접 워크로드를 측정하십시오.
Failure modes, and the strings you will see
INFO: /dev/kvm does not exist / KVM acceleration can NOT be used from kvm-ok. Either the module is not loaded, or the flag is not exposed. Check /proc/cpuinfo first.
kvm: disabled by bios in dmesg. On bare metal, flip the VT-x/SVM toggle in firmware. Inside a VPS it means L0 is not handing you the extensions, and nothing you type in the guest changes that.
modprobe: ERROR: could not insert 'kvm_intel': Operation not supported. The CPU your kernel sees has no vmx, again, an L0 decision.
Could not access KVM kernel module: Permission denied. Permissions, not hardware. ls -l /dev/kvm should show group kvm, mode 660; add yourself to that group and start a fresh login shell, since group membership does not apply to an already-running session.
kvm: Device or resource busy when QEMU starts. Another hypervisor module holds the CPU: run lsmod, look for vboxdrv or VMware modules alongside kvm_intel, and unload the one you do not want.
/var/run/libvirt/libvirt-sock: No such file or directory from virsh. The daemon is down: sudo systemctl enable --now libvirtd.
Proxmox: KVM virtualisation configured, but not available. A guest has KVM acceleration ticked on a host that cannot provide it. Fix the nesting, or untick it and accept emulation.
Android emulator: x86_64 emulation currently requires hardware acceleration! /dev/kvm again, usually the group case.
No error at all, and everything is glacial. QEMU with no accelerator flag falls back to TCG, its software emulator. It is correct and it is slow, a boot measured in seconds becomes one measured in minutes. Pass -accel kvm explicitly, so QEMU stops with an error instead of quietly emulating.
A guest vanishes mid-run. Look in dmesg for Out of memory: Killed process ... qemu-system-x86_64. An L2 guest is a process on L1, and the OOM killer treats it like any other. L2 RAM comes out of L1's fixed allocation, no borrowing from the host.
운영: 백업, 업그레이드, 제한
백업. 실행 중인 게스트의 qcow2 파일을 그대로 복사하면 손상된 이미지가 생성됩니다. virsh shutdown guest1를 수행한 뒤 복사하거나, 외부 스냅샷(virsh snapshot-create-as guest1 snap1 --disk-only --atomic)을 생성하여 쓰기 작업을 오버레이로 분기시킨 후 정지된 베이스 이미지를 복사하십시오. 그 후 virsh blockcommit을 사용하여 스냅샷을 병합합니다. 복사본은 반드시 VPS 외부로 전송하십시오. 동일한 디스크에 저장된 스냅샷은 어떠한 장애로부터도 보호해주지 못합니다.
업그레이드. apt full-upgrade은 새로운 kvm_intel/kvm_amd 모듈을 설치하지만, 재부팅하기 전까지는 실행 중인 커널이 기존 모듈을 계속 사용합니다. 이전 커널을 삭제하지 말고 유지하십시오. 커널 변경 시마다 kvm-ok을 다시 실행해야 합니다. vmx 없이 부팅된 호스트는 부팅 항목 선택만으로 즉시 복구할 수 있습니다.
확장성 한계. 공인 IP가 하나뿐이라면 모든 L2 서비스는 프록시나 L1의 DNAT 규칙을 거쳐 외부와 통신해야 합니다. 라이브 마이그레이션은 지원되지 않습니다. CPU 경합이 발생하면 중첩된 가상화의 exit 경로에서 가장 먼저 성능 저하가 나타납니다. 여러 게스트를 운영하는 하이퍼바이저는 이미 RAM 자원을 모두 할당한 상태이므로, 중첩된 VM은 고정된 할당량을 초과하여 메모리를 사용할 수 없습니다. 랩 환경이 이 범위를 벗어나면 중첩 스택을 더 쌓는 것이 아니라, 사용자가 직접 L0가 되어 이러한 제약이 적용되지 않는 전용 장비를 도입해야 합니다.
FAQ
VPS에서 Docker를 실행하려면 중첩 가상화(nested virtualization)가 필요한가요?
아니요. 컨테이너는 VPS의 커널을 공유하며 /dev/kvm을 열지 않으므로, vmx나 svm 플래그가 없는 일반 인스턴스에서도 Docker와 Docker Compose를 문제없이 실행할 수 있습니다. 중첩 가상화는 Proxmox 랩, Windows 게스트, Firecracker microVM, Android 에뮬레이터, VM 이미지를 부팅하는 CI 러너와 같이 두 번째 커널이 필요한 경우에만 중요합니다.
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이 그룹 kvm와 모드 660로 존재해야 합니다. 이 질문과 관련하여 /sys/module/kvm_intel/parameters/nested은 무시하십시오. 해당 파일은 제공자의 하이퍼바이저가 노출한 정보가 아니라 사용자의 KVM 모듈 자체를 설명합니다.
왜 대부분의 VPS 제공자는 중첩 가상화를 비활성화하나요?
vmx을 노출한다는 것은 해당 플래그를 포함한 CPU 모델을 게스트에게 전달한다는 의미입니다. 해당 CPU 기능에 의존하는 게스트는 해당 기능이 없는 머신으로 라이브 마이그레이션할 수 없으므로, 고객을 이동시켜 노드를 비우는 제공자는 이 기능을 포기하게 됩니다. 또한 중첩 VMX/SVM 코드 경로는 오랜 CVE 이력을 가지고 있습니다. 일부 호스트는 요청 시 VM별로 이를 활성화해주기도 하며, 다른 곳은 중첩 가상화를 요금제 기능으로 명시하기도 합니다.
중첩 VM이 공용 브리지에서 네트워크를 사용할 수 없습니다. 무엇이 문제인가요?
제공자의 스위치는 할당받지 않은 MAC 주소에서 오는 프레임을 차단합니다. 따라서 공용 NIC에 브리지된 L2 게스트가 ARP를 보내도 응답을 받을 수 없습니다. br0 디버깅을 멈추고, libvirt의 NAT default 네트워크(virbr0, 192.168.122.0/24)를 사용하십시오. 게스트에게 고정 IP를 할당하고, 외부로 공개할 서비스는 VPS 자체의 리버스 프록시나 DNAT 규칙을 통해 노출하십시오.
중첩 VM은 얼마나 느려지나요?
성능 저하는 메모리 접근이 아니라 VM exit에서 발생합니다. EPT/NPT가 활성화된 상태에서 L2 내부의 일반적인 읽기/쓰기 작업은 하드웨어 속도로 실행되지만, I/O, 타이머 인터럽트, MMIO, IPI는 L0에서 처리되며 L1을 거쳐 되돌아올 수 있습니다. 이미 RAM에 있는 데이터를 처리하는 CPU 집약적 작업은 네이티브와 비슷하지만, 시스템 콜, 패킷, 디스크 작업이 많은 워크로드는 모든 계층의 영향을 받습니다. 모든 곳에 virtio 장치를 사용하고 게스트 디스크에 cache=none를 적용한 뒤, 직접 워크로드를 측정해 보십시오.