VPS com virtualização aninhada: roda Proxmox?
A maioria dos VPS oculta a flag vmx. Verifique com kvm-ok em 1 minuto e saiba se pode rodar guests KVM ou Proxmox, incluindo os erros exatos.
A resposta curta
A virtualização aninhada consiste em executar um hypervisor dentro de uma máquina virtual: o seu VPS já é um guest e pretende alojar os seus próprios guests. Isto só funciona quando o hypervisor do fornecedor expõe deliberadamente as extensões de virtualização da CPU à sua instância. Verifique /proc/cpuinfo quanto à flag vmx (Intel) ou svm (AMD). Se nenhuma aparecer, nada do que configurar dentro do VPS resolverá o problema.
Primeiro, uma clarificação importante: o Docker não precisa de nada disto. Os containers partilham o kernel do VPS e nunca acedem a /dev/kvm. Se o objetivo real for "executar vários serviços em containers no meu servidor", já tem tudo o que precisa. A virtualização aninhada é relevante quando pretende um segundo kernel, um laboratório Proxmox, um guest Windows, microVMs Firecracker, um emulador Android, um ambiente de testes Kubernetes com VMs reais ou runners de CI que iniciam imagens de VMs.
O que está realmente aninhado
Três camadas:
- L0, o hypervisor do provedor, no hardware físico. Você não tem acesso a ele.
- L1, o seu VPS. Para o L0, ele é apenas um guest.
- L2, a VM que você quer executar dentro do seu VPS.
A virtualização de hardware usa VT-x (a flag vmx) e EPT em processadores Intel, ou AMD-V / SVM (svm) e RVI/NPT em processadores AMD. Um hypervisor usa essas instruções para entrar no modo guest e permitir que a CPU percorra duas tabelas de páginas ao mesmo tempo.
Nenhuma dessas tecnologias foi projetada para reentrada. Por isso, o aninhamento é emulado: quando o L1 executa uma instrução VMX, como VMLAUNCH ou VMRESUME, ela gera um trap para o L0. O L0 mantém, em nome do L1, as estruturas shadow do L2. Em CPUs com VMCS shadowing, as instruções VMREAD e VMWRITE do L1 podem ser atendidas sem um exit. Isso elimina grande parte desse tráfego, mas não todo ele. O KVM faz isso bem, mas é o L0 que executa trabalho adicional em cada exit. Por isso, o provedor precisa ativar esse recurso.
Quando o L0 é KVM, as duas condições seguintes precisam ser atendidas para que um L2 use aceleração:
- O módulo KVM do L0 foi carregado com
nested=1. - O L0 fornece ao seu VPS um modelo de CPU que inclui a flag:
<cpu mode='host-passthrough'/>no libvirt,cpu: hostno Proxmox e-cpu hostno QEMU direto. Um modelo genérico emulado (qemu64,kvm64) ocultavmx, mesmo quando o aninhamento está ativado globalmente.
Outros hypervisors têm a sua própria opção. O Hyper-V, por exemplo, emula as extensões de virtualização para um hypervisor aninhado dentro das suas VMs, mas apenas nas VMs em que o aninhamento foi ativado individualmente.
Verifique o seu VPS em um minuto
# 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/kvmUma instância utilizável mostra vmx ou svm, kvm-ok indica KVM acceleration can be used, e /dev/kvm existe com o modo root:kvm 660. Se o sinalizador estiver presente, mas o nó de dispositivo não existir, carregue o módulo manualmente e consulte o log do kernel:
sudo modprobe kvm_intel # or kvm_amd
sudo dmesg | tail -n 20Um ficheiro é citado constantemente e costuma ser interpretado de forma errada:
cat /sys/module/kvm_intel/parameters/nested # Y or NDentro do seu VPS, essa é a configuração do seu módulo KVM. Ela determina se um convidado L2 poderia aninhar um terceiro nível. Não indica se L0 ativou o aninhamento para si; /proc/cpuinfo e kvm-ok respondem a isso. O parâmetro nested é a opção que configura numa máquina que controla diretamente:
echo 'options kvm_intel nested=1' | sudo tee /etc/modprobe.d/kvm-nested.conf
sudo modprobe -r kvm_intel && sudo modprobe kvm_intelA remoção do módulo é recusada enquanto houver uma VM em execução, por isso desligue primeiro os guests. Se essa máquina for um host Proxmox, ativar a virtualização aninhada no Proxmox VE 9 descreve a mesma alteração em modprobe.d e também a definição cpu: host por VM que torna a flag visível dentro de um guest.
Por que a maioria dos hosts VPS o deixa desativado
- Migração em tempo real. Conceder
vmxsignifica expor um modelo de CPU que inclui esse sinalizador. Uma máquina virtual que dependa dessas funcionalidades da CPU não pode ser migrada com segurança para uma máquina cuja CPU não as tenha. Um host que esvazia nós migrando clientes perde essa capacidade assim que ativa o nesting. - Superfície de ataque. Os caminhos VMX/SVM aninhados estão entre os códigos mais complexos da camada de virtualização do kernel, com um histórico de CVEs à altura.
- L0 pode não ser KVM. Se
systemd-detect-virtmostrarvmware,xenoumicrosoft, as regras de nesting são definidas por essa pilha, não pelo KVM.
A sua instância não mostra o sinalizador? Contacte o suporte (alguns provedores ativam-no por VM), escolha um plano que documente o nesting ou migre para uma máquina dedicada. O restante pressupõe acesso root a uma máquina que mostre o sinalizador.
Executar um guest L2 com libvirt
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'Não é necessária uma sessão gráfica. Uma instalação pela consola série demora algum tempo, por isso inicie-a dentro de uma shell persistente: o mesmo fluxo de trabalho do tmux que mantém as sessões do Claude Code ativas numa VPS mantém uma consola virt-install ligada mesmo depois de uma ligação SSH interrompida. Se --os-variant debian13 for rejeitado, a sua osinfo-db é anterior a essa versão; execute osinfo-query os e escolha um nome existente. --cpu host-passthrough encaminha vmx para o L2, sendo necessário apenas se o L2 também tiver de executar virtualização. Torne o guest seguro para o arranque com virsh autostart guest1.
O barramento virtio no disco e na NIC não é um detalhe: os dispositivos IDE e e1000 emulados fazem muito mais saídas para o hypervisor do que as filas virtio. Com nesting, uma saída que o L0 não consegue concluir sozinho é refletida para o L1, onde o processamento pode desencadear novas saídas.
Rede: a parte que os tutoriais ignoram
O seu VPS tem 1 IP público e está atrás de uma infraestrutura que filtra endereços MAC desconhecidos. Daqui resultam duas consequências.
Normalmente, não é possível ligar convidados L2 à rede pública através de uma bridge. Coloque br0 na NIC pública, atribua ao convidado o seu próprio MAC e verá pedidos ARP a sair sem qualquer resposta. O switch do fornecedor descarta os frames de um MAC que nunca lhe foi atribuído. Se esse for o sintoma, pare de depurar a bridge. Esse é o mecanismo.
Use a rede NAT. O libvirt fornece default: virbr0, 192.168.122.0/24, concessões do dnsmasq e conectividade de saída imediata. Para ligações de entrada, termine o TLS em L1 e faça proxy para o convidado. Os caminhos dos certificados abaixo vêm de emitir um certificado Let's Encrypt com Certbot no Nginx:
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;
}
}Atribua primeiro uma concessão estática ao convidado (virsh net-edit default), para que o endereço em proxy_pass não mude.
As interfaces de gestão devem ficar fora da Internet: o VNC na porta 5900 e a interface web do Proxmox na porta 8006 devem ficar ligadas ao loopback e ser acedidas através de um túnel SSH (ssh -N -L 8006:127.0.0.1:8006 you@your-vps) ou por uma VPN WireGuard auto-hospedada para o VPS, que coloca todo o intervalo de convidados 192.168.122.0/24 a um salto privado de distância. Mantenha a firewall restritiva, sudo ufw allow 22,80,443/tcp, e nada mais. Se os convidados perderem a conectividade de saída logo depois de ativar o ufw, a causa habitual é DEFAULT_FORWARD_POLICY="DROP" em /etc/default/ufw. Defina-o como ACCEPT e recarregue o ufw.
Proxmox em um VPS
O Proxmox VE 9 usa o Debian 13 como base. Por isso, ele é instalado em um VPS Debian adicionando o repositório pve-no-subscription e o pacote proxmox-ve. Use as linhas do repositório e do keyring da documentação atual do próprio Proxmox. Uma URL copiada de uma publicação antiga em um blog pode interromper a instalação. Antes de passar uma noite a configurar a rede abaixo, vale decidir se o Proxmox deve mesmo ser usado em hardware alugado. A comparação de custos e capacidades entre um servidor Proxmox em casa e um VPS alugado apresenta essa questão com os cálculos de energia e hardware já feitos.
Os pacotes não são a parte difícil. O Proxmox espera que vmbr0 esteja ligado a uma NIC física por bridge. Isso conduz diretamente ao problema de filtragem de MAC descrito acima. A configuração que funciona em um VPS é uma vmbr0 com NAT ou roteamento, sem nenhuma porta física associada, com os guests em uma faixa privada e regras DNAT ou um reverse proxy no host para tudo o que for público. Quando os serviços públicos são containers em vez de VMs, Traefik encaminhando várias aplicações a partir de um único ficheiro Docker Compose executa a mesma função de encaminhamento com certificados automáticos. Faça primeiro um snapshot de /etc/network/interfaces. Uma definição incorreta da bridge pode bloquear o acesso a uma máquina cuja consola talvez não esteja disponível.
Desempenho, com números honestos
O aninhamento é mais lento do que o nível único, e o mecanismo é específico, não difuso: o custo recai sobre as saídas e a tradução de endereços, não sobre as instruções comuns. Quando o EPT/NPT está disponível, o L0 combina as tabelas de páginas do L1 para o L2 com as suas próprias numa única tabela shadow, para que um acerto na TLB seja executado à velocidade do hardware. Uma falha na TLB custa mais: o hardware percorre simultaneamente a tabela de páginas do guest e a tabela shadow, e cada alteração que o L1 faz nas suas próprias tabelas força uma saída para que o L0 possa sincronizar a tabela shadow. O que fica caro é cada operação que sai do modo guest: E/S, interrupções do temporizador, MMIO e interrupções entre processadores, porque uma saída do L2 é tratada pelo L0 e pode ser refletida novamente através do L1. Trabalho limitado pela CPU sobre um working set pequeno aproxima-se do desempenho nativo; working sets grandes em memória pagam o custo das falhas na TLB, e tudo o que for dominado por syscalls, pacotes e E/S de disco evidencia as camadas.
Portanto: dispositivos virtio em todo o lado. E o seu ficheiro qcow2 fica num disco que o fornecedor já virtualizou, com duas camadas de thin provisioning sobrepostas, onde cache=none no disco do guest impede que os mesmos blocos permaneçam simultaneamente em duas page caches. Não há números de benchmark aqui: meça a sua própria carga de trabalho na sua própria instância.
Modos de falha e mensagens apresentadas
INFO: /dev/kvm does not exist / KVM acceleration can NOT be used de kvm-ok. O módulo não está carregado ou a flag não está exposta. Verifique primeiro /proc/cpuinfo.
kvm: disabled by bios em dmesg. Em bare metal, alterne a opção VT-x/SVM no firmware. Numa VPS, isso significa que L0 não está a disponibilizar as extensões. Nada do que introduzir no guest altera essa situação.
modprobe: ERROR: could not insert 'kvm_intel': Operation not supported. A CPU que o kernel deteta não tem vmx. Mais uma vez, esta é uma decisão de L0.
Could not access KVM kernel module: Permission denied. É um problema de permissões, não de hardware. ls -l /dev/kvm deve apresentar o grupo kvm e o modo 660. Adicione a sua conta a esse grupo e inicie uma nova shell de login, porque a associação ao grupo não se aplica a uma sessão já em execução.
kvm: Device or resource busy quando o QEMU arranca. Outro módulo de hypervisor está a controlar a CPU. Execute lsmod, procure vboxdrv ou módulos VMware juntamente com kvm_intel e descarregue o módulo que não pretende utilizar.
/var/run/libvirt/libvirt-sock: No such file or directory de virsh. O daemon está parado: sudo systemctl enable --now libvirtd.
Proxmox: KVM virtualisation configured, but not available. Um guest tem a aceleração KVM ativada num host que não a consegue disponibilizar. Corrija o nesting ou desative a opção e aceite a emulação.
Emulador Android: x86_64 emulation currently requires hardware acceleration! /dev/kvm novamente, normalmente um problema de grupo.
Nenhum erro e tudo muito lento. O QEMU sem uma flag de acelerador recorre ao TCG, o seu emulador de software. O funcionamento está correto, mas é lento: um boot medido em segundos passa a ser medido em minutos. Indique -accel kvm explicitamente para que o QEMU termine com um erro em vez de emular silenciosamente.
Um guest desaparece durante a execução. Procure Out of memory: Killed process ... qemu-system-x86_64 em dmesg. Um guest L2 é um processo no L1 e o OOM killer trata-o como qualquer outro processo. A RAM do L2 é retirada da alocação fixa do L1; não há memória emprestada do host.
Operação: backups, atualizações e limites
Backups. Copiar o qcow2 de um guest em execução pode gerar uma imagem inconsistente, porque o guest continua a escrever enquanto a cópia é lida. Execute virsh shutdown guest1, aguarde até virsh domstate guest1 indicar shut off (o comando de desligamento pode terminar enquanto o guest ainda está a parar) e só depois copie; ou crie um snapshot externo (virsh snapshot-create-as guest1 snap1 --disk-only --atomic), para que as escritas sejam desviadas para um overlay enquanto copia a base, agora estática, e depois consolide-o com virsh blockcommit guest1 vda --active --pivot. Transfira as cópias para fora do VPS. Um snapshot no mesmo disco não protege contra nada.
Atualizações. apt full-upgrade instala novos módulos kvm_intel/kvm_amd, mas o kernel em execução continua a utilizar os módulos antigos até reiniciar. Mantenha o kernel anterior instalado e execute novamente kvm-ok após cada alteração do kernel: se um host voltar sem vmx, basta selecionar outra entrada de arranque para o pôr a funcionar novamente.
Onde isto deixa de escalar. Um único IP público significa que todos os serviços L2 chegam ao exterior através de um proxy ou de uma regra DNAT em L1. A migração em tempo real não é uma opção. Quando há contenção de CPU, o caminho de saída nested é o primeiro a ser afetado. Além disso, um hypervisor com vários guests é uma máquina cuja RAM já foi alocada; as VMs nested não podem usar overcommit para ultrapassar uma alocação fixa. Quando um laboratório ultrapassa essa capacidade, a resposta não é criar uma pilha nested mais alta. É usar uma máquina dedicada, onde você é L0 e nada disto se aplica.
FAQ
Preciso de virtualização aninhada para executar Docker numa VPS?
Não. Os contentores partilham o kernel da sua VPS e nunca abrem /dev/kvm, por isso uma instância normal, sem a flag vmx ou svm, executa Docker e Docker Compose sem problemas. O nesting só é necessário quando pretende executar um segundo kernel: um laboratório Proxmox, um convidado Windows, microVMs Firecracker, um emulador Android ou runners de CI que arrancam imagens de VM.
Como verifico se a minha VPS suporta virtualização aninhada?
Execute grep -o -E 'vmx|svm' /proc/cpuinfo | sort -u e depois kvm-ok a partir do pacote cpu-checker. Uma instância utilizável apresenta vmx (Intel) ou svm (AMD), kvm-ok indica KVM acceleration can be used, e /dev/kvm existe com o grupo kvm e o modo 660. Ignore /sys/module/kvm_intel/parameters/nested neste caso. Esse ficheiro descreve o seu próprio módulo KVM, não o que o hypervisor do fornecedor expôs à sua instância.
Porque é que a maioria dos fornecedores de VPS desativa a virtualização aninhada?
Expor vmx significa fornecer ao convidado um modelo de CPU que inclui essa flag. Um convidado que dependa dessas funcionalidades da CPU não pode ser migrado em direto para uma máquina cuja CPU não as suporte. Um fornecedor que drena nós ao mover clientes entre máquinas tem de abdicar dessa flexibilidade. Os caminhos de código VMX/SVM aninhados também têm um histórico extenso de CVEs. Alguns hosts ativam esta funcionalidade por VM mediante pedido. Outros documentam o nesting como uma funcionalidade do plano.
A minha VM aninhada não tem rede na bridge pública. O que está errado?
O switch do fornecedor descarta frames provenientes de um endereço MAC que nunca lhe foi atribuído. Por isso, um convidado L2 ligado à NIC pública através de uma bridge envia ARP e não recebe resposta. Pare de depurar br0. Use a rede NAT default do libvirt (virbr0, 192.168.122.0/24), atribua ao convidado uma concessão estática e publique os serviços através de um reverse proxy ou de uma regra DNAT na própria VPS.
Quanto mais lenta é uma VM aninhada?
O custo ocorre nas saídas da VM e na tradução de endereços. Com EPT/NPT ativo, as instruções e os acertos da TLB dentro de L2 executam à velocidade do hardware. No entanto, uma falha da TLB percorre tabelas de páginas adicionais, e as operações de I/O, as interrupções do temporizador, o MMIO e os IPIs são tratados por L0 e podem ser devolvidos através de L1. O trabalho limitado pela CPU e com um working set pequeno aproxima-se do desempenho nativo. Working sets grandes em memória e cargas intensivas em syscalls, pacotes e disco sentem cada camada. Use dispositivos virtio em todo o ambiente e cache=none nos discos convidados. Depois, meça a sua própria carga de trabalho.