{"id":12956,"date":"2025-05-27T13:30:14","date_gmt":"2025-05-27T13:30:14","guid":{"rendered":"https:\/\/www.ssdnodes.com\/?p=12956"},"modified":"2025-05-27T16:04:50","modified_gmt":"2025-05-27T16:04:50","slug":"nested-virtualization-example","status":"publish","type":"post","link":"https:\/\/www.ssdnodes.com\/blog\/nested-virtualization-example\/","title":{"rendered":"Nested Virtualization Example Using libvirt with ISO Images"},"content":{"rendered":"<p>Installing an ISO image on a VPS sounds overwhelming, but it\u2019s actually simpler than you think.<\/p>\n<p>With <a href=\"https:\/\/www.ssdnodes.com\/blog\/what-is-nested-virtualization\/\">nested virtualization<\/a>, you can run virtual machines inside your VPS.<\/p>\n<p>This guide walks you through the entire process of installing an ISO image on your VPS. We\u2019ll use the <a href=\"https:\/\/archlinux.org\/\" target=\"_blank\" rel=\"noopener\">Arch Linux<\/a> ISO image as an example, but you can install any other image of your choice.<\/p>\n<p>You'll first verify that your VPS supports nested virtualization, install the required packages, create virtual disks, then boot Arch Linux, and finally manage your VMs through the command line.<\/p>\n<p>By the end, you'll have mastered how to run fully functional virtual machines inside your VPS.<\/p>\n<h2>Prerequisites<\/h2>\n<p>To follow this tutorial, you\u2019ll need:<\/p>\n<ul>\n<li>A VPS with nested virtualization enabled. Our affordable <a href=\"https:\/\/www.ssdnodes.com\/nested-virtualization-vps\/\">Performance VPS<\/a> allows you to enable this feature.<\/li>\n<li>Access your sever via SSH, check out\u00a0<a href=\"https:\/\/www.ssdnodes.com\/blog\/tutorial-setting-up-and-securing-ssh-based-authentication\/\">How to access your server using SSH<\/a>\u00a0for instructions.<\/li>\n<li>Some basic knowledge managing <a href=\"https:\/\/www.ssdnodes.com\/blog\/vps-beginners-guide\/\">VPS servers<\/a>.<\/li>\n<li>If you're not familiar with nested virtualization, check out <a href=\"https:\/\/www.ssdnodes.com\/blog\/what-is-nested-virtualization\/\">What is Nested Virtualization?<\/a><\/li>\n<\/ul>\n<h2>Benefits of Installing Your Own ISO Image on a VPS<\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-13087 size-full\" style=\"border-radius: 25px;\" src=\"https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/Install-Your-Own-ISO-Image-on-a-VPS-Article-.jpg\" alt=\"Installing Your Own ISO image on a VPS\" width=\"600\" height=\"400\" srcset=\"https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/Install-Your-Own-ISO-Image-on-a-VPS-Article-.jpg 600w, https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/Install-Your-Own-ISO-Image-on-a-VPS-Article--300x200.jpg 300w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>You might be asking: Why go through the trouble of setting up nested virtualization?<\/p>\n<p>It's actually a game-changer for your <a href=\"https:\/\/www.ssdnodes.com\/blog\/what-is-a-vps-intro-to-virtual-private-servers\/\">VPS<\/a>!<\/p>\n<p>You'll enjoy incredible flexibility to run multiple operating systems at once, build perfectly isolated development environments, and test specialized software without compatibility headaches, among many <a href=\"https:\/\/www.ssdnodes.com\/blog\/what-to-do-with-a-vps\/\">other use cases<\/a>.<\/p>\n<h2>Step 1: Check if Nested Virtualization is Enabled<\/h2>\n<p>Let's first check if your VPS supports nested virtualization by running these commands.<\/p>\n<pre><code>$ grep -cw vmx \/proc\/cpuinfo<\/code><\/pre>\n<p>In the above command, any number above 0 means it's supported.<\/p>\n<pre><code>$ cat \/sys\/module\/kvm_intel\/parameters\/nested<\/code><\/pre>\n<p>This second command checks if the <code>nested<\/code> parameter is enabled in the KVM module. An output of <code>Y<\/code>\u00a0 or <code>1<\/code> confirms that it's on.<\/p>\n<p>I once spent hours debugging a VM setup before realizing nested virtualization wasn't enabled on my VPS, so always check this first! Some VPS providers disable this feature by default.<\/p>\n<p>Without nested virtualization, your VMs will either fail to start or run extremely slowly as they'll be using software emulation instead of hardware acceleration.<\/p>\n<p>At SSD Nodes, we offer nested virtualization as an add-on on our <a href=\"https:\/\/www.ssdnodes.com\/\">Performance VPS<\/a> servers.<\/p>\n<h2>Step 2: Install the Required Packages<\/h2>\n<p>Now we'll <a href=\"https:\/\/www.ssdnodes.com\/blog\/package-management-in-linux-use-apt-and-dnf\/\">install all the packages<\/a> needed to run virtual machines:<\/p>\n<pre><code>sudo apt update\r\nsudo apt install -y \\\r\n  qemu-kvm \\\r\n  libvirt-daemon-system \\\r\n  libvirt-clients \\\r\n  bridge-utils \\\r\n  virtinst \\\r\n  virt-manager<\/code><\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-12958\" src=\"https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/install-nested-virtualization-requirements.webp\" alt=\"install nested virtualization requirements\" width=\"600\" height=\"281\" srcset=\"https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/install-nested-virtualization-requirements.webp 1400w, https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/install-nested-virtualization-requirements-300x141.webp 300w, https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/install-nested-virtualization-requirements-1024x480.webp 1024w, https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/install-nested-virtualization-requirements-768x360.webp 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>This installs all the virtualization tools we need. <code>qemu-kvm<\/code> is the hypervisor itself, <code>libvirt<\/code> provides the API and daemon to manage VMs, <code>bridge-utils<\/code> helps with networking, <code>virtinst<\/code> gives us command-line tools like <code>virt-install<\/code>, and <code>virt-manager<\/code> is a GUI tool (though we won't need it for our console-based setup).<\/p>\n<p>These packages work together to create the complete virtualization stack.<\/p>\n<p>QEMU provides the emulation, KVM is the kernel module that allows direct access to CPU virtualization features, and libvirt gives us a consistent API to manage everything.<\/p>\n<h2>Step 3: Start the Virtualization Service<\/h2>\n<p>To start the virtualization process, we need to first enable and start the libvirt service to manage our VMs.<\/p>\n<pre><code>sudo systemctl enable --now libvirtd<\/code><\/pre>\n<p>Check the status:<\/p>\n<pre><code>sudo systemctl status libvirtd<\/code><\/pre>\n<p>Output:<\/p>\n<pre><code>\u25cf libvirtd.service - libvirt legacy monolithic daemon\r\n     **Loaded: loaded** (\/usr\/lib\/systemd\/syst\r\nem\/libvirtd.service; enabled; preset: enabled)\r\n     **Active: active (running)** since Wed 2025-05-14 12:09:45 UTC; 20s ago\r\nTriggeredBy: \u25cf libvirtd-ro.socket\r\n             \u25cf libvirtd-admin.socket\r\n             \u25cf libvirtd.socket\r\n       Docs: man:libvirtd(8)\r\n             https:\/\/libvirt.org\/\r\n   Main PID: 9397 (libvirtd)\r\n      Tasks: 22 (limit: 32768)\r\n     Memory: 11.2M (peak: 12.6M)\r\n        CPU: 788ms<\/code><\/pre>\n<p>From the output, we can see libvirtd is running properly. The service handles all VM operations and needs to be running before we can create or manage any VMs.<\/p>\n<h2>Step 4: Verify the Default Network<\/h2>\n<p>First, check if the default virtual network is active:<\/p>\n<pre><code>sudo virsh net-list --all<\/code><\/pre>\n<p>Output:<\/p>\n<pre><code> Name      State    Autostart   Persistent\r\n--------------------------------------------\r\n default   active   yes         yes\r\n<\/code><\/pre>\n<p>This command lists all defined virtual networks. The <code>virsh<\/code> command is your main interface to libvirt from the command line. You'll use it for most VM management tasks. The output shows the \"default\" network is <code>active<\/code>, set to start automatically, and is persistent (saved between reboots).<\/p>\n<p>This default network provides NAT (Network Address Translation) for your VMs, allowing them to access the internet through your VPS without needing their own public IPs.<\/p>\n<p>This creates a virtual bridge named <code>virbr0<\/code> that your VMs will connect to. Without this network, your VMs would be isolated. Every time I set up a new server, I check this because it saves a ton of networking headaches later.<\/p>\n<h2>Step 5: Download the Arch Linux ISO<\/h2>\n<p>Let's create a directory for boot images and download the latest Arch Linux ISO.<\/p>\n<p>First, we make a directory to store our ISO files:<\/p>\n<pre><code>sudo mkdir -p \/var\/lib\/libvirt\/boot<\/code><\/pre>\n<p>The <code>mkdir -p<\/code> command creates all necessary parent directories and doesn't error if the directory already exists. The libvirt convention is to use <code>\/var\/lib\/libvirt\/boot<\/code> for this. Move to this directory:<\/p>\n<pre><code>cd \/var\/lib\/libvirt\/boot<\/code><\/pre>\n<p>Download the Arch Linux installer ISO from one of the <a href=\"https:\/\/archlinux.org\/download\/\" target=\"_blank\" rel=\"noopener\">available mirrors<\/a>:<\/p>\n<pre><code>sudo wget https:\/\/mirror.rackspace.com\/archlinux\/iso\/2025.05.01\/archlinux-2025.05.01-x86_64.iso<\/code><\/pre>\n<p>This could take a few minutes depending on your VPS's download speed. The ISO contains everything needed to boot and install Arch Linux. I prefer keeping ISOs in this standardized location so I can easily find them later when setting up new VMs.<\/p>\n<p>You could technically store them anywhere, but sticking to the <code>\/var\/lib\/libvirt<\/code> hierarchy makes everything more organized.<\/p>\n<h2>Step 6: Create a Virtual Disk<\/h2>\n<p>Now we'll create a virtual disk for our VM to install on:<\/p>\n<pre><code>sudo mkdir -p \/var\/lib\/libvirt\/images\r\nsudo qemu-img create -f qcow2 \/var\/lib\/libvirt\/images\/arch-vm.qcow2 40G<\/code><\/pre>\n<p>These commands first create the standard directory for VM disk images, then create a 40GB virtual disk in <code>qcow2<\/code> format. The <code>qemu-img<\/code> tool is specifically designed for creating and managing disk images for QEMU\/KVM VMs.<\/p>\n<p>The <code>-f qcow2<\/code> specifies the format.<\/p>\n<p>The <code>qcow2<\/code> format is great because it uses thin provisioning. The file only grows as you use space in the VM, not immediately to 40GB.<\/p>\n<p>This means better disk space usage on your VPS. I've created many of these images, and qcow2 has been more reliable than raw format in my experience, especially when you need to take snapshots later.<\/p>\n<h2>Step 7: Launch the Arch Linux Installer<\/h2>\n<p>Start the VM installation process with <code>virt-install<\/code>:<\/p>\n<pre><code>sudo virt-install \\\r\n  --name arch-vm \\\r\n  --ram 4096 \\\r\n  --vcpus 2 \\\r\n  --os-variant archlinux \\\r\n  --disk path=\/var\/lib\/libvirt\/images\/arch-vm.qcow2,size=40 \\\r\n  --network network=default \\\r\n  --graphics none \\\r\n  --console pty,target_type=serial \\\r\n  --cdrom \/var\/lib\/libvirt\/boot\/archlinux-2025.05.01-x86_64.iso\r\n<\/code><\/pre>\n<p>This command creates and boots a new VM. Let's break down the parameters:<\/p>\n<ul>\n<li><code>-name arch-vm<\/code> gives our VM a name we can reference later<\/li>\n<li><code>-ram 4096<\/code> allocates 4GB of memory<\/li>\n<li><code>-vcpus 2<\/code> assigns 2 virtual CPUs<\/li>\n<li><code>-os-variant archlinux<\/code> helps libvirt optimize for Arch Linux<\/li>\n<li><code>-disk path=...<\/code> connects our virtual disk<\/li>\n<li><code>-network network=default<\/code> attaches to the default NAT network<\/li>\n<li><code>-graphics none<\/code> disables graphical console<\/li>\n<li><code>-console pty,target_type=serial<\/code> enables text-based console<\/li>\n<li><code>-cdrom<\/code> mounts our ISO file so we can boot from it<\/li>\n<\/ul>\n<p>When I run this on my own servers, I usually tweak the RAM based on what else is running - 4GB is plenty for a basic Arch install though.<\/p>\n<p>The VM will boot, and you'll see the Arch Linux boot menu:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-12959\" src=\"https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/Booting-an-ISO-in-a-VPS-with-Nested-Virtualization.webp\" alt=\"\" width=\"700\" height=\"316\" srcset=\"https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/Booting-an-ISO-in-a-VPS-with-Nested-Virtualization.webp 1179w, https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/Booting-an-ISO-in-a-VPS-with-Nested-Virtualization-300x136.webp 300w, https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/Booting-an-ISO-in-a-VPS-with-Nested-Virtualization-1024x463.webp 1024w, https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/Booting-an-ISO-in-a-VPS-with-Nested-Virtualization-768x347.webp 768w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/p>\n<p>When this boot menu appears, press <strong>Tab<\/strong> to edit the kernel parameters, hit <strong>SPACE<\/strong>, and add <code>console=ttyS0<\/code>, then press <strong>ENTER<\/strong>. This redirects the console output to the serial port so we can see it in our terminal.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-12960\" src=\"https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/Nested-Virtualization-Console.webp\" alt=\"Nested Virtualization Console\" width=\"700\" height=\"288\" srcset=\"https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/Nested-Virtualization-Console.webp 1352w, https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/Nested-Virtualization-Console-300x123.webp 300w, https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/Nested-Virtualization-Console-1024x421.webp 1024w, https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/Nested-Virtualization-Console-768x316.webp 768w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/p>\n<p><strong>Warning<\/strong><\/p>\n<blockquote><p>This parameter is <em>crucial<\/em>. Without it, you won't see any output once the kernel boots. The <code>console=ttyS0<\/code> tells Linux to send console output to the first serial port, which is mapped to your terminal session by KVM.<\/p><\/blockquote>\n<p>You'll then see the boot process:<\/p>\n<pre><code>Loading \/arch\/boot\/x86_64\/vmlinuz-linux... ok\r\nLoading \/arch\/boot\/x86_64\/initramfs-linux.img...ok<\/code><\/pre>\n<p>And finally the login prompt:<\/p>\n<pre><code>Arch Linux 6.14.4-arch1-2 (ttyS0)\r\n\r\narchiso login:\r\n<\/code><\/pre>\n<p>Login with username <code>root<\/code> (no password needed).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-12961\" src=\"https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/arch-on-a-vps.webp\" alt=\"Arch Linux on a VPS\" width=\"700\" height=\"357\" srcset=\"https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/arch-on-a-vps.webp 1148w, https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/arch-on-a-vps-300x153.webp 300w, https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/arch-on-a-vps-1024x522.webp 1024w, https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/arch-on-a-vps-768x391.webp 768w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/p>\n<p>With this, you are now inside the Arch Linux virtual machine <em>inside<\/em> your VPS!<\/p>\n<p>Let's check if the internet is working using <code>ping<\/code>:<\/p>\n<pre><code>root@archiso ~ # ping ssdnodes.com<\/code><\/pre>\n<p>The output should show successful ping:<\/p>\n<pre><code>PING ssdnodes.com (172.66.43.60) 56(84) bytes of data.\r\n64 bytes from 172.66.43.60: icmp_seq=1 ttl=57 time=1.79 ms\r\n64 bytes from 172.66.43.60: icmp_seq=2 ttl=57 time=1.82 ms\r\n64 bytes from 172.66.43.60: icmp_seq=3 ttl=57 time=1.80 ms\r\n64 bytes from 172.66.43.60: icmp_seq=4 ttl=57 time=2.20 ms\r\n64 bytes from 172.66.43.60: icmp_seq=5 ttl=57 time=2.03 ms\r\n64 bytes from 172.66.43.60: icmp_seq=6 ttl=57 time=2.14 ms\r\n\r\n--- ssdnodes.com ping statistics ---\r\n6 packets transmitted, 6 received, 0% packet loss, time 5009ms\r\n<\/code><\/pre>\n<p>This shows our VM has internet access through the NAT network we verified earlier. This connectivity is essential for installing packages during Arch setup. The low ping times (around 2ms) in SSD Nodes <a href=\"https:\/\/www.ssdnodes.com\/\">nested virtualization VPS<\/a> show the virtualization overhead is minimal.<\/p>\n<p>I always test connectivity right away. There is nothing worse than getting halfway through an install before discovering network issues!<\/p>\n<p>Now let's check what disks are available:<\/p>\n<pre><code>root@archiso ~ # fdisk -l<\/code><\/pre>\n<p>Output:<\/p>\n<pre><code>Disk \/dev\/vda: 40 GiB, 42949672960 bytes, 83886080 sectors\r\nUnits: sectors of 1 * 512 = 512 bytes\r\nSector size (logical\/physical): 512 bytes \/ 512 bytes\r\nI\/O size (minimum\/optimal): 512 bytes \/ 512 bytes\r\n\r\nDisk \/dev\/loop0: 846.72 MiB, 887848960 bytes, 1734080 sectors\r\nUnits: sectors of 1 * 512 = 512 bytes\r\nSector size (logical\/physical): 512 bytes \/ 512 bytes\r\nI\/O size (minimum\/optimal): 512 bytes \/ 512 bytes\r\n<\/code><\/pre>\n<p>This command lists all disk devices in the VM. We can see our 40GB virtual disk as <code>\/dev\/vda<\/code> - this is where we'll install Arch. The <code>loop0<\/code> device is part of the live ISO environment. Notice how the virtual disk appears just like a regular disk would. That's the beauty of virtualization.<\/p>\n<p>Let's verify our CPU configuration:<\/p>\n<pre><code>lscpu | grep -E '^CPU\\(s\\)'\r\n<\/code><\/pre>\n<p>Output:<\/p>\n<pre><code>CPU(s):          2<\/code><\/pre>\n<p>This confirms our VM has exactly 2 vCPUs as we configured with the <code>--vcpus 2<\/code> parameter.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-12962\" src=\"https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/Nested-Arch-Linux-VM-on-a-VPS-.webp\" alt=\"Nested Arch Linux VM on a VPS\" width=\"700\" height=\"392\" srcset=\"https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/Nested-Arch-Linux-VM-on-a-VPS-.webp 1400w, https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/Nested-Arch-Linux-VM-on-a-VPS--300x168.webp 300w, https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/Nested-Arch-Linux-VM-on-a-VPS--1024x573.webp 1024w, https:\/\/www.ssdnodes.com\/wp-content\/uploads\/2025\/05\/Nested-Arch-Linux-VM-on-a-VPS--768x430.webp 768w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/p>\n<p>The VM sees these as regular CPUs, but they're actually virtual cores allocated from your VPS's physical resources.<\/p>\n<p>If your VM workload needs more processing power, you can always shut down and reconfigure with more vCPUs.<\/p>\n<p>I typically match the number of vCPUs to what the workload needs. More isn't always better since excess vCPUs can cause scheduling overhead.<\/p>\n<h3>Warning<\/h3>\n<blockquote><p>When running <code>virt-install<\/code>, do not detach from the console or close the terminal until the installation is complete. Detaching before completing could leave you with an unbootable disk image.<\/p><\/blockquote>\n<p>With the VM running, you can now continue with your <a href=\"https:\/\/wiki.archlinux.org\/title\/Installation_guide\" target=\"_blank\" rel=\"noopener\">Arch Linux installation<\/a> process as usual.<\/p>\n<h2>Step 8: Disconnecting and Connecting to the VM Console<\/h2>\n<p>After you install your ISO image, you can detach from the VM console without shutting down the VM by pressing <code>Ctrl+]<\/code>.<\/p>\n<p>You'll then see this message:<\/p>\n<pre><code>Domain is still running. Installation may be in progress.\r\nYou can reconnect to the console to complete the installation process.<\/code><\/pre>\n<p>This message confirms the VM is still running in the background, and you've just disconnected from its console.<\/p>\n<p>This is super useful when you need to check something on your VPS or if your SSH connection is unstable.<\/p>\n<p>To reconnect to the VM console, use the followin:<\/p>\n<pre><code>sudo virsh console arch-vm<\/code><\/pre>\n<p>Wait briefly then press <strong>ENTER<\/strong>. This reconnects you to the VM's console so you can continue the installation.<\/p>\n<p>The VM has been running the whole time, you're just reattaching your terminal to it. Think of it like plugging a monitor back into a running computer.<\/p>\n<p>If you get this error:<\/p>\n<pre><code>error: operation failed: Active console session exists for this domain<\/code><\/pre>\n<p>It means your previous console session wasn't properly closed. This usually happens if your SSH connection dropped abnormally. To force a connection:<\/p>\n<pre><code>sudo virsh console --force arch-vm<\/code><\/pre>\n<p>Wait briefly then press\u00a0<strong>ENTER<\/strong>.<\/p>\n<p>If that doesn't work, you can restart the libvirt daemon:<\/p>\n<pre><code>sudo systemctl restart libvirtd\r\nsudo virsh console arch-vm<\/code><\/pre>\n<p>Or reset just your VM:<\/p>\n<pre><code>sudo virsh destroy arch-vm\r\nsudo virsh start arch-vm\r\nsudo virsh console arch-vm<\/code><\/pre>\n<p>This set of commands forces a proper reset of your VM and its console connection. The <code>destroy<\/code> command is misleadingly named - it just forces a power off, not an actual deletion.<\/p>\n<p>Be careful though, as it's like pulling the plug on a physical computer.<\/p>\n<p>I've had to use this approach a few times when my internet connection dropped during a long installation. It's a lifesaver, but you might lose unsaved work in the VM.<\/p>\n<h2>Step 9: Managing Your VM<\/h2>\n<p>You have several options for managing your VM from the VPS.<\/p>\n<p>To shut down the VM from inside:<\/p>\n<pre><code>shutdown -h now<\/code><\/pre>\n<p>This properly shuts down the VM from inside the guest OS. It's like pressing the power button and selecting shutdown. All services stop cleanly. This is the preferred method as it gives the guest operating system a chance to save data and shut down services properly.<\/p>\n<p>To list all the currently running virtual machines:<\/p>\n<pre><code>sudo virsh list<\/code><\/pre>\n<p>This command shows all running VMs managed by libvirt. you can use this to check if your VM is still running. It's a quick way to get a status report of all active VMs on your system. You can add the <code>--all<\/code> flag to see inactive VMs too.<\/p>\n<p>To gracefully shut down a VM:<\/p>\n<pre><code>sudo virsh shutdown arch-vm<\/code><\/pre>\n<p>This sends a signal to the VM's operating system to shut down properly. It's polite and prevents data loss. This is equivalent to pressing the power button on a physical machine that's configured to trigger a clean shutdown.<\/p>\n<p>To force power off a VM:<\/p>\n<pre><code>sudo virsh destroy arch-vm<\/code><\/pre>\n<p>This immediately cuts power to the VM - like unplugging a physical computer. Use this only when the VM is frozen or won't respond to a normal shutdown. Again, while the name <code>destroy<\/code> sounds scary, it only destroys the running instance, not the VM definition or storage.<\/p>\n<p>To start a VM:<\/p>\n<pre><code>sudo virsh start arch-vm<\/code><\/pre>\n<p>This powers on a stopped VM. If the VM was shut down previously, it will boot normally. It's the equivalent of pressing the power button on a physical machine that's turned off.<\/p>\n<p>To connect to the VM's console:<\/p>\n<pre><code>sudo virsh console arch-vm<\/code><\/pre>\n<p>This connects you to the VM's serial console, giving you a terminal interface to the VM. It's essential for headless setups without graphics. Remember to use <code>Ctrl+]<\/code> to disconnect when you're done.<\/p>\n<p>These commands give you complete control over your VM's lifecycle. I recommend using shutdown commands whenever possible rather than destroy, as sudden power loss can sometimes corrupt filesystems.<\/p>\n<h2>Important Tips for VM Management<\/h2>\n<ol>\n<li>Never close the SSH session by force closing your terminal when in a VM console. Always use <code>Ctrl+]<\/code> first to detach.<\/li>\n<li>If you're setting up the VM for the first time and want to exit temporarily, use <code>Ctrl+]<\/code> to detach. The VM installation will continue running in the background.<\/li>\n<li>If you get disconnected from SSH unexpectedly, you can reconnect and use <code>sudo virsh console --force arch-vm<\/code> to reattach.<\/li>\n<li>Take snapshots before making major changes to your VM. You can use <code>virsh snapshot-create-as<\/code> to create a point-in-time backup you can roll back to.<\/li>\n<li>Monitor your VM's resource usage with tools like <code>virt-top<\/code> (you may need to install it separately with <code>apt install virt-top<\/code>).<\/li>\n<li>For VMs you plan to use long-term, consider configuring them to autostart with your VPS by using <code>virsh autostart arch-vm<\/code>.<\/li>\n<\/ol>\n<h2>Conclusion<\/h2>\n<p>You've now successfully set up nested virtualization on your VPS and installed Arch Linux in a VM! This powerful setup opens up a world of possibilities - from creating isolated development environments to testing deployments across different OS configurations without needing multiple physical servers.<\/p>\n<p>The skills you've learned here apply to virtually any Linux distribution, not just Arch. You can use the same techniques to run Ubuntu, Debian, CentOS, or even Windows VMs inside your VPS.<\/p>\n<p>Ready to start with an affordable VPS? See our <a href=\"https:\/\/www.ssdnodes.com\/\">nested virtualization plans \u2192<\/a><\/p>\n<h2>FAQ<\/h2>\n<h3>What is the minimum VPS size needed for nested virtualization?<\/h3>\n<p>For a decent experience, I recommend at least 32GB RAM and 8 vCPUs on your host VPS. For running multiple nested VMs simultaneously, 48GB+ RAM is better.<\/p>\n<h3>Will nested virtualization affect my VPS performance?<\/h3>\n<p>Yes, there's some overhead. Nested VMs typically show about 10-15% performance degradation compared to direct VMs. CPU-intensive operations in nested VMs will use more resources than expected. I've found memory-heavy applications suffer the most performance impact.<\/p>\n<h3>Can I run Windows VMs with this setup?<\/h3>\n<p>Absolutely! Just substitute the Arch ISO with a Windows ISO. Windows VMs typically need more resources though - I'd allocate at least 4GB RAM and 40GB disk space for a Windows VM. You'll also need to use the <code>--graphics vnc<\/code> option instead of the console approach we used for Arch.<\/p>\n<h3>My VM console isn't showing any output after boot. What's wrong?<\/h3>\n<p>You probably missed adding the <code>console=ttyS0<\/code> parameter at the boot menu. You can shutdown the VM with <code>virsh destroy<\/code> and start again. I've made this mistake countless times when setting up new VMs.<\/p>\n<h3>Is nested virtualization secure?<\/h3>\n<p>Generally yes, but it does add another layer of complexity to <a href=\"https:\/\/www.ssdnodes.com\/blog\/vps-security-critical-steps-to-secure-vps-servers\/\">security<\/a>. Each layer of virtualization introduces potential new attack vectors. Always keep VMs updated and isolate critical VMs on separate networks. Never expose management interfaces directly to the internet.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Install your own ISO on a VPS? Easy. With nested virtualization, run full VMs inside your server\u2014Arch Linux and beyond.<\/p>\n","protected":false},"author":19,"featured_media":13136,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[18,30],"tags":[],"class_list":["post-12956","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops","category-tutorials"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/posts\/12956","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/users\/19"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/comments?post=12956"}],"version-history":[{"count":17,"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/posts\/12956\/revisions"}],"predecessor-version":[{"id":13130,"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/posts\/12956\/revisions\/13130"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/media\/13136"}],"wp:attachment":[{"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/media?parent=12956"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/categories?post=12956"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/tags?post=12956"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}