วิธีเช็ค VPS รองรับ Nested Virtualization เพื่อรัน Proxmox
ตรวจสอบว่า VPS ของคุณรองรับการทำ Nested Virtualization หรือไม่ด้วยคำสั่ง kvm-ok เพื่อรัน Proxmox หรือ KVM พร้อมวิธีสังเกต flag vmx และ svm ที่ผู้ให้บริการมักจะปิดกั้นไว้
คำตอบโดยสรุป
Nested virtualization คือการรัน hypervisor ซ้อนอยู่ภายในเครื่องเสมือน (virtual machine) อีกชั้นหนึ่ง กล่าวคือ VPS ของคุณเป็น guest อยู่แล้ว แต่คุณต้องการให้มันทำหน้าที่เป็น host เพื่อรัน guest ของตัวเองอีกที วิธีนี้จะใช้งานได้ก็ต่อเมื่อ hypervisor ของผู้ให้บริการตั้งใจเปิดเผยส่วนขยายการทำ virtualization ของ CPU ให้กับ instance ของคุณเท่านั้น ให้ตรวจสอบ /proc/cpuinfo ว่ามี flag vmx (สำหรับ Intel) หรือ svm (สำหรับ AMD) ปรากฏอยู่หรือไม่ หากไม่พบทั้งสองอย่าง การตั้งค่าใดๆ ภายใน VPS ก็จะไม่สามารถแก้ไขปัญหานี้ได้
ข้อควรทราบเบื้องต้น: Docker ไม่จำเป็นต้องใช้ฟีเจอร์นี้ คอนเทนเนอร์จะใช้ kernel ร่วมกับ VPS ของคุณและไม่เคยเรียกใช้งาน /dev/kvm หากเป้าหมายที่แท้จริงคือ "การรันหลายบริการในคอนเทนเนอร์บนเซิร์ฟเวอร์" คุณมีสิ่งที่จำเป็นครบถ้วนแล้ว การทำ nesting จะมีความสำคัญก็ต่อเมื่อคุณต้องการ kernel ชุดที่สอง, ห้องทดลอง Proxmox, Windows guest, Firecracker microVMs, Android emulator, Kubernetes testbed ที่เป็น VM จริงๆ หรือ CI runner ที่ต้องบูต VM image ขึ้นมาใช้งาน
สิ่งที่ถูกซ้อนอยู่จริงคืออะไร
มีสามชั้น:
- L0, ไฮเปอร์ไวเซอร์ของผู้ให้บริการ ซึ่งทำงานบนฮาร์ดแวร์โดยตรง คุณไม่สามารถเข้าถึงส่วนนี้ได้
- L1, VPS ของคุณ ซึ่งสำหรับ L0 แล้วถือเป็นเพียงเกสต์ (guest) ตัวหนึ่ง
- L2, เครื่องเสมือน (VM) ที่คุณต้องการรันภายใน VPS ของคุณ
การทำ Hardware virtualization คือการใช้ VT-x (แฟล็ก vmx) ร่วมกับ EPT บน Intel หรือ AMD-V / SVM (svm) ร่วมกับ RVI/NPT บน AMD ไฮเปอร์ไวเซอร์จะใช้คำสั่งเหล่านี้เพื่อเข้าสู่โหมดเกสต์และอนุญาตให้ CPU ประมวลผลตารางหน้าหน่วยความจำ (page table) สองชุดพร้อมกัน
เนื่องจากสถาปัตยกรรมเหล่านี้ไม่ได้ถูกออกแบบมาให้รองรับการเรียกซ้อน (re-entrant) การทำ nesting จึงต้องอาศัยการจำลอง: เมื่อ L1 รันคำสั่ง VMX ระบบจะดักจับ (trap) ไปยัง L0 ซึ่งจะทำหน้าที่ดูแลโครงสร้างเงา (shadow structures) สำหรับ L2 แทน L1 โดยที่ KVM ทำหน้าที่นี้ได้ดี แต่ L0 จะต้องทำงานเพิ่มขึ้นในทุกครั้งที่มีการออกจากโหมดเกสต์ (exit) นี่คือเหตุผลที่ผู้ให้บริการต้องเป็นผู้เปิดใช้งานฟีเจอร์นี้
เงื่อนไขสองประการที่ต้องเป็นจริงเพื่อให้ L2 ทำงานแบบเร่งความเร็ว (accelerated) ได้:
- โมดูล KVM ของ L0 ต้องถูกโหลดด้วย
nested=1 - L0 ต้องกำหนด CPU model ให้กับ VPS ของคุณที่รองรับแฟล็กดังกล่าว ได้แก่
<cpu mode='host-passthrough'/>ใน libvirt,cpu: hostใน Proxmox หรือ-cpu hostใน QEMU แบบ raw หากใช้ CPU model แบบจำลองทั่วไป (qemu64,kvm64) ระบบจะซ่อนvmxไว้ แม้ว่าจะเปิดใช้งาน nesting ไว้ทั่วทั้งระบบแล้วก็ตาม
ตรวจสอบ 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 หากพบแฟล็กดังกล่าวแต่ไม่พบ device node ให้โหลดโมดูลด้วยตนเองและตรวจสอบ log ของเคอร์เนล:
sudo modprobe kvm_intel # or kvm_amd
sudo dmesg | tail -n 20มีไฟล์หนึ่งที่ถูกอ้างถึงอยู่บ่อยครั้งและมักถูกตีความผิด:
cat /sys/module/kvm_intel/parameters/nested # Y or Nภายใน VPS ของคุณ นั่นคือการตั้งค่าของโมดูล KVM ของคุณ ซึ่งเป็นตัวกำหนดว่า guest ระดับ L2 จะสามารถทำ nesting ซ้อนลงไปเป็นระดับที่สามได้หรือไม่ ค่านี้ไม่ได้ระบุว่า L0 ได้เปิดใช้งาน nesting ให้คุณหรือไม่ โดย /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_intelระบบจะปฏิเสธการลบโมดูลในขณะที่ VM กำลังทำงาน ดังนั้นให้ปิด guest ทั้งหมดก่อน
เหตุผลที่ผู้ให้บริการ VPS ส่วนใหญ่ปิดการใช้งานฟีเจอร์นี้
- การย้ายเครื่องแบบ Live migration: การส่งมอบ
vmxให้คุณหมายถึงการเปิดเผย CPU model ที่มี flag ดังกล่าว ซึ่ง guest ที่ต้องพึ่งพาฟีเจอร์ของ CPU เหล่านั้นจะไม่สามารถย้ายไปยังเครื่องที่ไม่มีฟีเจอร์เดียวกันได้อย่างปลอดภัย ผู้ให้บริการที่ใช้วิธีระบายโหลดออกจากโหนดด้วยการย้ายลูกค้า จะสูญเสียความสามารถนี้ทันทีที่เปิดใช้งาน nesting - พื้นที่เสี่ยงต่อการโจมตี (Attack surface): เส้นทางการทำงานของ nested VMX/SVM ถือเป็นส่วนของโค้ดที่ซับซ้อนที่สุดในชั้น virtualization ของ kernel และมีประวัติการพบช่องโหว่ (CVE) อยู่บ่อยครั้ง
- L0 อาจไม่ใช่ KVM: หาก
systemd-detect-virtแสดงผลลัพธ์เป็นvmware,xenหรือmicrosoftกฎการทำ nesting จะเป็นไปตาม stack นั้นๆ ไม่ใช่ของ KVM
หาก instance ของคุณไม่มี flag ดังกล่าว ให้ติดต่อฝ่ายสนับสนุน (บางแห่งเปิดให้เป็นราย VM), เลือกแผนบริการที่ระบุว่ารองรับ nesting หรือย้ายไปใช้ dedicated box เนื้อหาหลังจากนี้จะถือว่าคุณมีสิทธิ์ root บนเครื่องที่แสดง flag ดังกล่าวแล้ว
การรัน L2 guest ด้วย 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'ไม่จำเป็นต้องใช้ graphical session การติดตั้งผ่าน serial จะใช้เวลาสักพัก ดังนั้นให้เริ่มการติดตั้งภายใน persistent shell: workflow ของ tmux ที่ช่วยให้เซสชัน Claude Code ทำงานต่อเนื่องบน VPS จะช่วยรักษาการเชื่อมต่อ virt-install ให้คงอยู่แม้การเชื่อมต่อ SSH จะหลุด หาก --os-variant debian13 ถูกปฏิเสธ แสดงว่า osinfo-db ของคุณเก่ากว่าเวอร์ชันที่รองรับ ให้รัน osinfo-query os แล้วเลือกชื่อที่มีอยู่จริง --cpu host-passthrough จะส่งผ่าน vmx ลงไปยัง L2 ซึ่งจำเป็นเฉพาะในกรณีที่ L2 ต้องทำ virtualization ซ้อนอีกชั้นเท่านั้น ทำให้ guest บูตได้อย่างปลอดภัยด้วย virsh autostart guest1
บัส virtio บนดิสก์และ NIC ไม่ใช่แค่การตกแต่ง: อุปกรณ์ IDE และ e1000 แบบจำลองจะดักจับ (trap) ไปยัง hypervisor บ่อยกว่า virtio queues มาก และภายใต้การทำ nesting ทุกการดักจับจะต้องเสียค่าใช้จ่ายในการประมวลผลเป็นสองเท่า
ระบบเครือข่าย: ส่วนที่บทเรียนทั่วไปมักข้ามไป
VPS ของคุณมี public IP หนึ่งหมายเลขและอยู่หลังโครงสร้างเครือข่ายที่คัดกรอง MAC address ที่ไม่รู้จัก ซึ่งส่งผลตามมา 2 ประการ
การทำ Bridging ให้ guest ระดับ L2 เชื่อมต่อกับ public network มักจะใช้งานไม่ได้ หากคุณใส่ br0 บน public NIC และกำหนด MAC address ให้ guest เอง คุณจะพบว่า ARP request ถูกส่งออกไปแต่ไม่มีการตอบกลับ เนื่องจาก switch ของผู้ให้บริการจะทิ้งเฟรมที่มาจาก MAC address ที่ไม่ได้มีการเช่าใช้งาน หากคุณพบอาการนี้ ให้หยุดการแก้ไขปัญหาที่ bridge เพราะนี่คือกลไกการทำงานของระบบ
ให้ใช้ NAT network แทน libvirt มาพร้อมกับ default: virbr0, 192.168.122.0/24, และ dnsmasq สำหรับการแจกจ่าย IP ซึ่งช่วยให้การเชื่อมต่อขาออกใช้งานได้ทันที สำหรับการเชื่อมต่อขาเข้า ให้ทำ TLS termination ที่ L1 แล้วใช้ proxy ส่งต่อเข้ามา โดยเส้นทางของ certificate ที่ระบุไว้ด้านล่างมาจาก การออกใบรับรอง Let's Encrypt ด้วย Certbot บน 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;
}
}กำหนด static lease ให้ guest ก่อน (virsh net-edit default) เพื่อให้ที่อยู่ใน proxy_pass นั้นคงที่
อินเทอร์เฟซสำหรับจัดการระบบต้องไม่เปิดเผยบนอินเทอร์เน็ต: VNC บนพอร์ต 5900 และ Proxmox web UI บนพอร์ต 8006 ควรอยู่บน loopback เท่านั้น โดยเข้าถึงผ่าน SSH tunnel (ssh -N -L 8006:127.0.0.1:8006 you@your-vps) หรือผ่าน การเชื่อมต่อ WireGuard VPN เข้าสู่ VPS ซึ่งจะทำให้ช่วง IP ของ guest 192.168.122.0/24 อยู่ห่างออกไปเพียงหนึ่ง private hop เท่านั้น ให้จำกัดการตั้งค่า firewall ให้แคบที่สุด โดยเปิดเฉพาะ sudo ufw allow 22,80,443/tcp เท่านั้น หาก guest สูญเสียการเชื่อมต่อขาออกทันทีหลังจากที่คุณเปิดใช้งาน ufw สาเหตุที่พบบ่อยคือ DEFAULT_FORWARD_POLICY="DROP" ในไฟล์ /etc/default/ufw ให้ตั้งค่าเป็น ACCEPT แล้วโหลด ufw ใหม่
การใช้งาน Proxmox บน VPS
Proxmox VE 9 มีพื้นฐานมาจาก Debian 13 ดังนั้นจึงสามารถติดตั้งบน Debian VPS ได้โดยการเพิ่ม repository pve-no-subscription และแพ็กเกจ proxmox-ve ให้คัดลอกบรรทัด repository และ keyring จากเอกสารประกอบฉบับปัจจุบันของ Proxmox โดยตรง เนื่องจาก URL ที่คัดลอกมาจากบล็อกเก่าอาจทำให้การติดตั้งล้มเหลว ควรพิจารณาให้ถี่ถ้วนก่อนว่าการเช่าฮาร์ดแวร์เพื่อรัน Proxmox นั้นคุ้มค่าหรือไม่ ก่อนที่จะเสียเวลาทั้งคืนไปกับการตั้งค่าเครือข่ายที่ซับซ้อน และ การเปรียบเทียบต้นทุนและความสามารถระหว่างการใช้ Proxmox ที่บ้านกับ VPS ที่เช่ามา เป็นบทสรุปของคำถามดังกล่าวที่ได้คำนวณเรื่องพลังงานและฮาร์ดแวร์ไว้ให้แล้ว
ส่วนของแพ็กเกจไม่ใช่เรื่องยาก Proxmox ต้องการ vmbr0 ที่ทำ bridge เข้ากับ physical NIC ซึ่งมักจะติดปัญหาเรื่อง MAC-filtering ที่กล่าวไปข้างต้น รูปแบบที่ใช้งานได้จริงบน VPS คือการใช้ vmbr0 แบบ NAT หรือ routed โดยไม่ต้องเชื่อมต่อกับพอร์ตจริง ให้ guest อยู่ในวงเครือข่ายส่วนตัว (private range) และใช้กฎ DNAT หรือ reverse proxy บน host สำหรับบริการที่ต้องการเปิดสู่สาธารณะ ในกรณีที่บริการที่เปิดสู่สาธารณะเป็น container แทนที่จะเป็น VM บทความเรื่อง Traefik สำหรับจัดการแอปพลิเคชันหลายตัวจากไฟล์ Docker Compose เดียว จะครอบคลุมงานด้านการกำหนดเส้นทาง (routing) แบบเดียวกันพร้อมการจัดการ certificate อัตโนมัติ ให้ทำ Snapshot /etc/network/interfaces ไว้ก่อนเสมอ เพราะการกำหนดค่า bridge ที่ผิดพลาดอาจทำให้คุณถูกตัดขาดจากเครื่องที่ไม่มีคอนโซลให้เข้าถึงได้
ประสิทธิภาพตามความเป็นจริง
การทำ Nested virtualization นั้นช้ากว่าการทำงานระดับเดียว โดยกลไกที่เป็นสาเหตุหลักไม่ใช่การเข้าถึงหน่วยความจำ แต่เป็นเรื่องของ VM exit เมื่อมี EPT/NPT ใช้งานอยู่ L0 จะดูแล shadow page tables สำหรับ L2 ทำให้การอ่านหน่วยความจำปกติทำงานได้ด้วยความเร็วระดับฮาร์ดแวร์ สิ่งที่ทำให้เกิดภาระงานสูงคือทุกการดำเนินการที่ทำให้หลุดออกจาก guest mode เช่น I/O, timer interrupts, MMIO, inter-processor interrupts เนื่องจาก L2 exit จะถูกจัดการโดย L0 และอาจต้องส่งต่อกลับไปยัง L1 งานที่เน้นการประมวลผลของ CPU บนข้อมูลที่อยู่ใน RAM อยู่แล้วจะมีความเร็วใกล้เคียงกับ native แต่สำหรับงานที่เน้น syscall, แพ็กเก็ตเครือข่าย และ disk I/O จะเห็นผลกระทบจากจำนวนชั้นที่ซ้อนกันชัดเจน
ดังนั้น ควรใช้ virtio devices ในทุกกรณี และไฟล์ qcow2 ของคุณที่วางอยู่บนดิสก์ซึ่งผู้ให้บริการทำ virtualization ไว้แล้ว จะทำให้เกิดการซ้อนทับของ thin-provisioning สองชั้น ซึ่งการใช้ cache=none บนดิสก์ของ guest จะช่วยป้องกันไม่ให้บล็อกข้อมูลเดียวกันถูกเก็บอยู่ใน page cache สองที่พร้อมกัน เราไม่มีตัวเลขผลการทดสอบมาตรฐานให้ที่นี่ คุณควรวัดผลจากภาระงานจริงบนอินสแตนซ์ของคุณเอง
รูปแบบความล้มเหลวและข้อความที่คุณจะพบ
INFO: /dev/kvm does not exist / KVM acceleration can NOT be used จาก kvm-ok อาจเกิดจากโมดูลไม่ได้ถูกโหลด หรือไม่ได้เปิดใช้งาน flag ให้ตรวจสอบ /proc/cpuinfo เป็นอันดับแรก
kvm: disabled by bios ใน dmesg หากเป็นเครื่อง bare metal ให้สลับเปิด VT-x/SVM ใน firmware หากเป็น VPS หมายความว่า L0 ไม่ได้ส่งต่อส่วนขยาย (extensions) มาให้ ซึ่งการตั้งค่าใดๆ ใน guest ก็ไม่สามารถแก้ไขปัญหานี้ได้
modprobe: ERROR: could not insert 'kvm_intel': Operation not supported CPU ที่ kernel มองเห็นไม่มี vmx ซึ่งเป็นผลจากการตัดสินใจของ L0 เช่นกัน
Could not access KVM kernel module: Permission denied เป็นปัญหาเรื่องสิทธิ์ ไม่ใช่ฮาร์ดแวร์ ls -l /dev/kvm ควรแสดงกลุ่ม kvm และโหมด 660 ให้เพิ่มผู้ใช้ของคุณเข้ากลุ่มดังกล่าวแล้วเริ่ม login shell ใหม่ เนื่องจากสถานะการเป็นสมาชิกกลุ่มจะไม่มีผลกับ session ที่กำลังทำงานอยู่
kvm: Device or resource busy เมื่อ QEMU เริ่มทำงาน เกิดจากมี hypervisor โมดูลอื่นยึด CPU ไว้ ให้รัน lsmod แล้วมองหา vboxdrv หรือโมดูลของ VMware ที่ทำงานอยู่คู่กับ kvm_intel จากนั้นให้ unload โมดูลที่ไม่ต้องการออก
/var/run/libvirt/libvirt-sock: No such file or directory จาก virsh หมายความว่า daemon ไม่ทำงาน ให้ใช้ sudo systemctl enable --now libvirtd
Proxmox: KVM virtualisation configured, but not available. guest มีการเปิดใช้งาน KVM acceleration บน host ที่ไม่รองรับ ให้แก้ไขการทำ nesting หรือยกเลิกการเลือกตัวเลือกดังกล่าวแล้วยอมรับการทำงานแบบ emulation
Android emulator: x86_64 emulation currently requires hardware acceleration! เกิดจาก /dev/kvm เช่นเดิม ซึ่งมักเป็นปัญหาเรื่องกลุ่มผู้ใช้
ไม่มีข้อความผิดพลาดแต่ทำงานช้ามาก QEMU ที่ไม่มี flag ตัวเร่งความเร็วจะถอยกลับไปใช้ TCG ซึ่งเป็น software emulator แม้จะทำงานได้ถูกต้องแต่จะช้ามาก การบูตที่ปกติใช้เวลาไม่กี่วินาทีอาจกลายเป็นหลายนาที ให้ระบุ -accel kvm อย่างชัดเจน เพื่อให้ QEMU หยุดทำงานและแสดงข้อความผิดพลาดแทนที่จะทำงานแบบ emulation ไปเรื่อยๆ อย่างเงียบเชียบ
guest หายไปในระหว่างการทำงาน ให้ตรวจสอบ dmesg เพื่อหา Out of memory: Killed process ... qemu-system-x86_64 เนื่องจาก L2 guest เป็นเพียง process หนึ่งบน L1 ตัว OOM killer จึงจัดการกับมันเหมือน process อื่นๆ โดย RAM ของ L2 จะถูกดึงมาจากส่วนที่ L1 จัดสรรไว้เท่านั้น ไม่มีการยืมทรัพยากรจาก host โดยตรง
การใช้งาน: การสำรองข้อมูล การอัปเกรด และข้อจำกัด
การสำรองข้อมูล การคัดลอกไฟล์ qcow2 ของ guest ที่กำลังทำงานอยู่จะทำให้ได้อิมเมจที่เสียหาย คุณต้องใช้ virsh shutdown guest1 ก่อนแล้วจึงคัดลอก หรือสร้าง external snapshot (virsh snapshot-create-as guest1 snap1 --disk-only --atomic) เพื่อให้การเขียนข้อมูลเปลี่ยนไปลงที่ overlay ในขณะที่คุณคัดลอกไฟล์ base ที่หยุดนิ่งอยู่ จากนั้นจึงรวมไฟล์กลับด้วย virsh blockcommit ให้ส่งสำเนาข้อมูลออกไปนอก VPS เพราะการทำ snapshot ไว้บนดิสก์ลูกเดิมไม่สามารถป้องกันความเสียหายใดๆ ได้
การอัปเกรด apt full-upgrade จะติดตั้งโมดูล kvm_intel/kvm_amd ใหม่ แต่ kernel ที่กำลังทำงานอยู่จะยังคงใช้โมดูลเก่าจนกว่าคุณจะรีบูตเครื่อง ให้คง kernel รุ่นก่อนหน้าไว้ในระบบและรัน kvm-ok ใหม่ทุกครั้งหลังมีการเปลี่ยนแปลง kernel หากโฮสต์กลับมาทำงานโดยไม่มี vmx คุณจะสามารถกู้คืนระบบให้กลับมาใช้งานได้ด้วยการเลือก boot entry เพียงครั้งเดียว
จุดที่ระบบนี้ขยายต่อไม่ได้ การมี public IP เพียงหนึ่งหมายเลขทำให้บริการ L2 ทุกตัวต้องเข้าถึงโลกภายนอกผ่าน proxy หรือกฎ DNAT บน L1 การทำ live migration ไม่สามารถทำได้ ในสภาวะที่ CPU แย่งทรัพยากรกัน เส้นทาง nested exit จะเป็นส่วนแรกที่ได้รับผลกระทบ และ hypervisor ที่มี guest หลายตัวคือเครื่องที่ใช้ RAM ไปจนหมดแล้ว VM แบบซ้อนทับไม่สามารถใช้วิธี overcommit เพื่อแก้ปัญหาการจัดสรรทรัพยากรที่จำกัดได้ เมื่อห้องปฏิบัติการของคุณเติบโตเกินกว่าขีดจำกัดนี้ คำตอบไม่ใช่การเพิ่มชั้น nested stack ให้สูงขึ้น แต่คือการใช้เครื่องเซิร์ฟเวอร์เฉพาะที่คุณเป็น L0 ซึ่งข้อจำกัดเหล่านี้จะไม่มีผลอีกต่อไป
FAQ
ฉันจำเป็นต้องใช้ nested virtualization เพื่อรัน Docker บน VPS หรือไม่?
ไม่จำเป็น คอนเทนเนอร์ใช้ kernel ร่วมกับ VPS ของคุณและไม่เคยเปิด /dev/kvm ดังนั้น instance ปกติที่ไม่มี flag vmx หรือ svm จึงสามารถรัน Docker และ Docker Compose ได้ตามปกติ การทำ nesting จะมีความสำคัญก็ต่อเมื่อคุณต้องการ kernel ชุดที่สอง เช่น การทำ Proxmox lab, การรัน Windows guest, Firecracker microVMs, Android emulator หรือ CI runners ที่ต้องบูต VM images
ฉันจะตรวจสอบได้อย่างไรว่า VPS ของฉันรองรับ nested virtualization?
ให้รัน grep -o -E 'vmx|svm' /proc/cpuinfo | sort -u จากนั้นรัน kvm-ok จากแพ็กเกจ cpu-checker หาก instance ใช้งานได้จริง ระบบจะแสดงผล vmx (สำหรับ Intel) หรือ svm (สำหรับ AMD) ส่วน kvm-ok จะรายงานค่า KVM acceleration can be used และไฟล์ /dev/kvm จะต้องมีอยู่โดยมีกลุ่มเป็น kvm และโหมดเป็น 660 ให้ละเว้น /sys/module/kvm_intel/parameters/nested สำหรับคำถามนี้ เนื่องจากไฟล์ดังกล่าวอธิบายโมดูล KVM ของคุณเอง ไม่ใช่สิ่งที่ hypervisor ของผู้ให้บริการเปิดเผยให้คุณเห็น
ทำไมผู้ให้บริการ VPS ส่วนใหญ่ถึงปิดการใช้งาน nested virtualization?
การเปิดเผย vmx หมายถึงการส่งมอบ CPU model ที่มี flag ดังกล่าวให้กับ guest ซึ่ง guest ที่ต้องพึ่งพาฟีเจอร์ CPU เหล่านี้จะไม่สามารถทำ live-migration ไปยังเครื่องที่ไม่มีฟีเจอร์ดังกล่าวได้ ผู้ให้บริการที่ใช้วิธีโยกย้ายลูกค้าเพื่อเคลียร์โหนดจึงไม่สามารถทำเช่นนั้นได้ นอกจากนี้ โค้ดส่วน nested VMX/SVM ยังมีประวัติช่องโหว่ CVE มาอย่างยาวนาน ผู้ให้บริการบางรายยังคงเปิดใช้งานให้ตามคำขอต่อ VM หรือระบุว่าการทำ nesting เป็นฟีเจอร์ของแผนบริการบางระดับ
ทำไม nested VM ของฉันถึงไม่มีเครือข่ายบน public bridge?
สวิตช์ของผู้ให้บริการจะทิ้งเฟรมที่มาจาก MAC address ซึ่งไม่ได้มีการเช่าไว้ให้คุณ ดังนั้น guest ที่ทำ L2 bridge เข้ากับ public NIC จึงส่ง ARP ออกไปแต่ไม่ได้รับสัญญาณตอบกลับ ให้หยุดการดีบั๊ก br0 แล้วหันไปใช้ NAT default network ของ libvirt (virbr0, 192.168.122.0/24) แทน โดยกำหนด static lease ให้กับ guest และเผยแพร่บริการสู่สาธารณะผ่าน reverse proxy หรือกฎ DNAT บนตัว VPS เอง
nested VM ทำงานช้าลงมากน้อยเพียงใด?
ภาระงานจะไปตกอยู่ที่ VM exits ไม่ใช่การเข้าถึงหน่วยความจำ เมื่อเปิดใช้งาน EPT/NPT การอ่านและเขียนข้อมูลทั่วไปภายใน L2 จะทำงานด้วยความเร็วระดับฮาร์ดแวร์ ในขณะที่ I/O, timer interrupts, MMIO และ IPI จะถูกจัดการโดย L0 และอาจต้องส่งผ่านกลับไปยัง L1 งานที่เน้น CPU สำหรับข้อมูลที่อยู่ใน RAM จะมีความเร็วใกล้เคียงกับ native แต่ภาระงานที่เน้น syscall, แพ็กเก็ตเครือข่าย และการอ่านเขียนดิสก์จะได้รับผลกระทบจากทุกเลเยอร์ ให้ใช้ virtio devices ในทุกจุดและใช้ cache=none บนดิสก์ของ guest จากนั้นจึงวัดผลจากภาระงานจริงของคุณเอง