Introduction
Oracle Cloud Infrastructure (OCI) offers a robust and flexible platform for provisioning virtual machines (VMs) with customized configurations, including CPU, memory, operating system, network, and security settings. This is made possible by the powerful technology of nested virtualization, which enables bare metal machines to run multiple isolated environments, allowing for efficient resource utilization and shared access for services and users.
Nested virtualization opens up a wide range of possibilities for innovative use cases, such as:
- Testing and validating configurations before deploying them to production environments, ensuring seamless transitions from development to staging to production VMs.
- Creating isolated environments for sensitive workloads, such as secure data processing or compliance testing.
- Developing and testing complex applications that require multiple, interconnected VMs.
In this blog, we will provision a VM (Guest VM) inside an OCI VM (Host VM) using Oracle Linux 9.5. This will demonstrate the flexibility and power of nested virtualization, and provide a foundation for further experimentation and innovation.
Requirements
Already provisioned virtual machine (Host) in OCI with:
- Operating System:
- Image:
Oracle Linux 9
- Image build:
2025.02.28-0
(This build was available at the time this blog was written, choose the latest one available).
- Image:
- Shape:
AMD: VM.Standard.E5.Flex
orIntel: VM.Standard3.Flex
(Ampere VMs (ARM/aarch64) did not support nested virtualization)- CPU:
12 OCPUs
- Memory:
18 GBs
- Disk space:
Boot volume with 100 GBs
- CPU:
- Network:
Virtual Cloud Network (VCN)
Subnet
- Your
SSH public key
added to the host VM.
The specs above will satisfy Oracle Linux 9 requirements and it will allow to create additional VMs and/or increase/decrease VMs specs if needed:
- CPU: 2 logical CPUs minimum
- Memory: 1.5 GB minimum, 1.5 GB per logical CPU recommended
- Disk space: 10 GB minimum, 20 GB recommended
Guest VM Provisioning
-
Access the host VM (Example name: lab) using its IP address and your private SSH key:
[YOUR-USERNAME@YOUR-PERSONAL-COMPUTER ~]$ ssh -i ~/.ssh/id_rsa opc@<OCI_VM_IP_ADDRESS> The authenticity of host '<OCI_VM_IP_ADDRESS> (<OCI_VM_IP_ADDRESS>)' ... Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '<OCI_VM_IP_ADDRESS>' (ED25519) to the list of known hosts. [opc@lab ~]$
-
Verify which operating system and kernel the VM has:
[opc@lab ~]$ cat /etc/os-release NAME="Oracle Linux Server" VERSION="9.5" ID="ol" ID_LIKE="fedora" VARIANT="Server" VARIANT_ID="server" VERSION_ID="9.5" PLATFORM_ID="platform:el9" PRETTY_NAME="Oracle Linux Server 9.5" ANSI_COLOR="0;31" CPE_NAME="cpe:/o:oracle:linux:9:5:server" HOME_URL="https://linux.oracle.com/" BUG_REPORT_URL="https://github.com/oracle/oracle-linux" ORACLE_BUGZILLA_PRODUCT="Oracle Linux 9" ORACLE_BUGZILLA_PRODUCT_VERSION=9.5 ORACLE_SUPPORT_PRODUCT="Oracle Linux" ORACLE_SUPPORT_PRODUCT_VERSION=9.5
[opc@lab ~]$ uname -r 5.15.0-305.176.4.el9uek.x86_64
-
Check the host VM disk size (The sda3/ocivolume-root is our boot volume, but it still has the default boot volume size):
[opc@lab ~]$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8:0 0 100G 0 disk ├─sda1 8:1 0 100M 0 part /boot/efi ├─sda2 8:2 0 2G 0 part /boot └─sda3 8:3 0 44.5G 0 part ├─ocivolume-root 252:0 0 29.5G 0 lvm / └─ocivolume-oled 252:1 0 15G 0 lvm /var/oled
[opc@lab ~]$ df -h Filesystem Size Used Avail Use% Mounted on devtmpfs 4.0M 0 4.0M 0% /dev tmpfs 8.6G 0 8.6G 0% /dev/shm tmpfs 3.5G 8.8M 3.5G 1% /run /dev/mapper/ocivolume-root 30G 9.0G 21G 31% / /dev/mapper/ocivolume-oled 15G 156M 15G 2% /var/oled /dev/sda2 2.0G 384M 1.6G 20% /boot /dev/sda1 100M 6.3M 94M 7% /boot/efi tmpfs 1.8G 0 1.8G 0% /run/user/1000
-
Rescan the VM disks:
[opc@lab ~]$ sudo dd iflag=direct if=/dev/oracleoci/oraclevda of=/dev/null count=1 echo "1" | sudo tee /sys/class/block/`readlink /dev/oracleoci/oraclevda | cut -d'/' -f 2`/device/rescan 1+0 records in 1+0 records out 512 bytes copied, 0.000365637 s, 1.4 MB/s 1
-
Extend the partition of the disk (The available space in the filesystem will increase from 21 GBs to 74 GBs, which is enough to download the Oracle Linux 9.5 ISO, and provide the recommended disk space to the nested virtual machine):
[opc@lab ~]$ sudo /usr/libexec/oci-growfs -y Volume Group: ocivolume Volume Path: /dev/ocivolume/root Mountpoint Data --------------- mountpoint: / source: /dev/mapper/ocivolume-root filesystem type: xfs source size: 29.4G type: lvm size: 29.5G physical devices: ['/dev/sda3'] physical volumes: ['/dev/sda', '/dev/sda'] partition number: ['3'] volume group name: ocivolume volume group path: /dev/ocivolume/root Partition dry run expansion "/dev/sda3" succeeded. CHANGE: partition=3 start=4401152 old: size=93325312 end=97726463 new: size=205314015 end=209715166 Expanding partition /dev/sda3: Confirm? Partition expand expansion "/dev/sda3" succeeded. update-partition set to true FLOCK: try exec open fd 9, on failure exec exits this program FLOCK: /dev/sda: obtained exclusive lock resizing 3 on /dev/sda using resize_sfdisk_gpt 209715200 sectors of 512. total size=107374182400 bytes ## sfdisk --unit=S --dump /dev/sda label: gpt label-id: 93B50681-37AC-4C1A-A734-F34CF87629B1 device: /dev/sda unit: sectors first-lba: 34 last-lba: 97727250 sector-size: 512 /dev/sda1 : start= 2048, size= 204800, type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B, uuid=2A2320B9-AA64-48A8-8375-FEB666CACB28, name="EFI System Partition" /dev/sda2 : start= 206848, size= 4194304, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=3303D07F-1DA0-43A0-B5BE-C899DCBFFF84 /dev/sda3 : start= 4401152, size= 93325312, type=E6D6D379-F507-44C2-A23C-238F2A3DF928, uuid=89ED5A37-947F-4AA3-A865-7252EE54350A padding 33 sectors for gpt secondary header max_end=209715166 tot=209715200 pt_end=97726463 pt_start=4401152 pt_size=93325312 resize of /dev/sda returned 0. FLOCK: /dev/sda: releasing exclusive lock CHANGED: partition=3 start=4401152 old: size=93325312 end=97726463 new: size=205314015 end=209715166 Extending /dev/sda3 succeeded. Device /dev/sda3 extended successfully. Logical volume /dev/ocivolume/root extended successfully.
[opc@lab ~]$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8:0 0 100G 0 disk ├─sda1 8:1 0 100M 0 part /boot/efi ├─sda2 8:2 0 2G 0 part /boot └─sda3 8:3 0 97.9G 0 part ├─ocivolume-root 252:0 0 82.9G 0 lvm / └─ocivolume-oled 252:1 0 15G 0 lvm /var/oled
[opc@lab ~]$ df -h Filesystem Size Used Avail Use% Mounted on devtmpfs 4.0M 0 4.0M 0% /dev tmpfs 8.6G 0 8.6G 0% /dev/shm tmpfs 3.5G 8.8M 3.5G 1% /run /dev/mapper/ocivolume-root 83G 9.4G 74G 12% / /dev/mapper/ocivolume-oled 15G 172M 15G 2% /var/oled /dev/sda2 2.0G 384M 1.6G 20% /boot /dev/sda1 100M 6.3M 94M 7% /boot/efi tmpfs 1.8G 0 1.8G 0% /run/user/1000
-
Upgrade the packages in the system to get the latest features and fixes for the current installed packages:
[opc@lab ~]$ sudo dnf upgrade -y Ksplice for Oracle Linux 9 (x86_64) 1.4 MB/s | 3.4 MB 00:02 Oracle Linux 9 OCI Included Packages (x86_64) 39 MB/s | 141 MB 00:03 Oracle Linux 9 BaseOS Latest (x86_64) 22 MB/s | 50 MB 00:02 Oracle Linux 9 Application Stream Packages (x86_64) 68 MB/s | 50 MB 00:00 Oracle Linux 9 Addons (x86_64) 2.0 MB/s | 559 kB 00:00 Oracle Linux 9 UEK Release 7 (x86_64) 30 MB/s | 58 MB 00:01 ... =========================================================================================================================================== Package Architecture Version Repository Size =========================================================================================================================================== Installing: ... Upgrading: ... Complete!
-
Enable the Oracle Linux 9 KVM utils repository with dnf config-manager:
[opc@lab ~]$ sudo dnf config-manager --enable ol9_kvm_utils
[opc@lab ~]$ sudo dnf repolist enabled repo id repo name ol9_UEKR7 Oracle Linux 9 UEK Release 7 (x86_64) ol9_addons Oracle Linux 9 Addons (x86_64) ol9_appstream Oracle Linux 9 Application Stream Packages (x86_64) ol9_baseos_latest Oracle Linux 9 BaseOS Latest (x86_64) ol9_ksplice Ksplice for Oracle Linux 9 (x86_64) ol9_kvm_utils Oracle Linux 9 KVM Utilities (x86_64) ol9_oci_included Oracle Linux 9 OCI Included Packages (x86_64)
-
Install the virtualization packages:
For
x86_64
:[opc@lab ~]$ sudo dnf group install -y "Virtualization Host" # Only available for x86_64 [opc@lab ~]$ sudo dnf install -y virt-install virt-viewer
For
aarch64/arm
(In case you are using a host that supports virtualization):[opc@lab ~]$ sudo dnf install -y qemu-kvm libvirt virt-install virt-viewer
-
Check which package versions were installed:
[opc@lab ~]$ sudo dnf list installed qemu-kvm libvirt virt-install virt-viewer Installed Packages libvirt.x86_64 30:9.0.0-10.el9 @ol9_kvm_utils qemu-kvm.x86_64 30:7.2.0-18.el9 @ol9_kvm_utils virt-install.noarch 4.1.0-5.el9 @ol9_appstream virt-viewer.x86_64 11.0-1.el9 @ol9_appstream
-
Validate that the host supports virtualization:
[opc@lab ~]$ sudo virt-host-validate QEMU: Checking for hardware virtualization : PASS QEMU: Checking if device /dev/kvm exists : PASS QEMU: Checking if device /dev/kvm is accessible : PASS QEMU: Checking if device /dev/vhost-net exists : PASS QEMU: Checking if device /dev/net/tun exists : PASS QEMU: Checking for cgroup 'cpu' controller support : PASS QEMU: Checking for cgroup 'cpuacct' controller support : PASS QEMU: Checking for cgroup 'cpuset' controller support : PASS QEMU: Checking for cgroup 'memory' controller support : PASS QEMU: Checking for cgroup 'devices' controller support : PASS QEMU: Checking for cgroup 'blkio' controller support : PASS QEMU: Checking for device assignment IOMMU support : WARN (No ACPI DMAR table found, IOMMU either disabled in BIOS or not supported by this hardware platform) QEMU: Checking for secure guest support : WARN (Unknown if this platform has Secure Guest support)
-
Start the libvirtd service with full virtualization:
[opc@lab ~]$ for drv in qemu network nodedev nwfilter secret storage interface; do sudo systemctl enable virt${drv}d.service sudo systemctl enable virt${drv}d{,-ro,-admin}.socket; sudo systemctl start virt${drv}d{,-ro,-admin}.socket; done Created symlink /etc/systemd/system/multi-user.target.wants/virtnetworkd.service → /usr/lib/systemd/system/virtnetworkd.service. Created symlink /etc/systemd/system/sockets.target.wants/virtnetworkd-ro.socket → /usr/lib/systemd/system/virtnetworkd-ro.socket. Created symlink /etc/systemd/system/sockets.target.wants/virtnetworkd-admin.socket → /usr/lib/systemd/system/virtnetworkd-admin.socket. Created symlink /etc/systemd/system/multi-user.target.wants/virtnodedevd.service → /usr/lib/systemd/system/virtnodedevd.service. Created symlink /etc/systemd/system/sockets.target.wants/virtnodedevd-ro.socket → /usr/lib/systemd/system/virtnodedevd-ro.socket. Created symlink /etc/systemd/system/sockets.target.wants/virtnodedevd-admin.socket → /usr/lib/systemd/system/virtnodedevd-admin.socket. Created symlink /etc/systemd/system/multi-user.target.wants/virtnwfilterd.service → /usr/lib/systemd/system/virtnwfilterd.service. Created symlink /etc/systemd/system/sockets.target.wants/virtnwfilterd-ro.socket → /usr/lib/systemd/system/virtnwfilterd-ro.socket. Created symlink /etc/systemd/system/sockets.target.wants/virtnwfilterd-admin.socket → /usr/lib/systemd/system/virtnwfilterd-admin.socket. Created symlink /etc/systemd/system/multi-user.target.wants/virtsecretd.service → /usr/lib/systemd/system/virtsecretd.service. Created symlink /etc/systemd/system/sockets.target.wants/virtsecretd-ro.socket → /usr/lib/systemd/system/virtsecretd-ro.socket. Created symlink /etc/systemd/system/sockets.target.wants/virtsecretd-admin.socket → /usr/lib/systemd/system/virtsecretd-admin.socket. Created symlink /etc/systemd/system/multi-user.target.wants/virtstoraged.service → /usr/lib/systemd/system/virtstoraged.service. Created symlink /etc/systemd/system/sockets.target.wants/virtstoraged-ro.socket → /usr/lib/systemd/system/virtstoraged-ro.socket. Created symlink /etc/systemd/system/sockets.target.wants/virtstoraged-admin.socket → /usr/lib/systemd/system/virtstoraged-admin.socket. Created symlink /etc/systemd/system/multi-user.target.wants/virtinterfaced.service → /usr/lib/systemd/system/virtinterfaced.service. Created symlink /etc/systemd/system/sockets.target.wants/virtinterfaced-ro.socket → /usr/lib/systemd/system/virtinterfaced-ro.socket. Created symlink /etc/systemd/system/sockets.target.wants/virtinterfaced-admin.socket → /usr/lib/systemd/system/virtinterfaced-admin.socket.
-
Check libvirtd service status:
[opc@lab ~]$ sudo systemctl list-units --type=socket virt* UNIT LOAD ACTIVE SUB DESCRIPTION virtinterfaced-admin.socket loaded active listening Libvirt interface admin socket virtinterfaced-ro.socket loaded active listening Libvirt interface local read-only socket virtinterfaced.socket loaded active listening Libvirt interface local socket virtnetworkd-admin.socket loaded active listening Libvirt network admin socket virtnetworkd-ro.socket loaded active listening Libvirt network local read-only socket virtnetworkd.socket loaded active listening Libvirt network local socket virtnodedevd-admin.socket loaded active listening Libvirt nodedev admin socket virtnodedevd-ro.socket loaded active listening Libvirt nodedev local read-only socket virtnodedevd.socket loaded active listening Libvirt nodedev local socket virtnwfilterd-admin.socket loaded active listening Libvirt nwfilter admin socket virtnwfilterd-ro.socket loaded active listening Libvirt nwfilter local read-only socket virtnwfilterd.socket loaded active listening Libvirt nwfilter local socket virtqemud-admin.socket loaded active listening Libvirt qemu admin socket virtqemud-ro.socket loaded active listening Libvirt qemu local read-only socket virtqemud.socket loaded active listening Libvirt qemu local socket virtsecretd-admin.socket loaded active listening Libvirt secret admin socket virtsecretd-ro.socket loaded active listening Libvirt secret local read-only socket virtsecretd.socket loaded active listening Libvirt secret local socket virtstoraged-admin.socket loaded active listening Libvirt storage admin socket virtstoraged-ro.socket loaded active listening Libvirt storage local read-only socket virtstoraged.socket loaded active listening Libvirt storage local socket LOAD = Reflects whether the unit definition was properly loaded. ACTIVE = The high-level unit activation state, i.e. generalization of SUB. SUB = The low-level unit activation state, values depend on unit type. 21 loaded units listed. Pass --all to see loaded but inactive units, too. To show all installed unit files use 'systemctl list-unit-files'.
-
Download Oracle Linux 9.5 x86_64 ISO (~12 GB):
[opc@lab ~]$ mkdir -p isos
[opc@lab ~]$ wget -P isos https://yum.oracle.com/ISOS/OracleLinux/OL9/u5/x86_64/OracleLinux-R9-U5-x86_64-dvd.iso --2025-03-13 19:55:42-- https://yum.oracle.com/ISOS/OracleLinux/OL9/u5/x86_64/OracleLinux-R9-U5-x86_64-dvd.iso Resolving yum.oracle.com (yum.oracle.com)... 23.62.177.78 Connecting to yum.oracle.com (yum.oracle.com)|23.62.177.78|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 12600737792 (12G) [application/octet-stream] Saving to: ‘isos/OracleLinux-R9-U5-x86_64-dvd.iso’ OracleLinux-R9-U5-x86_64-dvd.iso 86%[=======================> ] 10.16G 48.8MB/s eta 25s
-
Create the virtual disk for the VM:
[opc@lab ~]$ mkdir -p disks
[opc@lab ~]$ qemu-img create -f qcow2 disks/vm1.qcow2 20G Formatting 'disks/vm1.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=21474836480 lazy_refcounts=off refcount_bits=16
Note: For this simpified KVM virtualization hands-on, the guest VM will be running in the same block volume as the host OS. This means that they will share the physical disk resources (Block volume performance (VPU) which indicates the amount of performance related resources, such as IOPS/GB and throughput/GB, that a block volume has). If both (Host VM and Guest VM) perform disk-intensive operations concurrently, this sharing can potentially lead to I/O contention.
Target Volume PerformanceVPUIOPSThroughput (MB/s)Balanced/Default (Min)10300024Ultra High Performance (Max)1201125090For scenarios with more demanding I/O requirements, create and attach new block volumes to the host VM using Logical Volume Manager (LVM) to store the guest VM’s disks.
-
Install the VM:
Important flags:
--network default
: Allows the nested VM to communicate using the host VM preconfigured libvirt default network to communicate with other hosts in the same network, and networks connected to the VM host.--extra-args "console=tty0 console=ttyS0,115200N8"
: Directs kernel messages to the primary virtual console (tty0). ttyS0 with a baud rate of 115200 bits per second allows you to interact with the VM using a serial console (Very helpful to debug and manage a VM without a graphical interface).
[opc@lab ~]$ virt-install --name vm1 \ --memory 2048 \ --vcpus 2 \ --location /home/opc/isos/OracleLinux-R9-U5-x86_64-dvd.iso \ --disk path=/home/opc/disks/vm1.img,size=20 \ --os-variant ol9.5 \ --arch x86_64 \ --virt-type kvm \ --graphics none \ --network default \ --extra-args "console=tty0 console=ttyS0,115200N8" \ --debug ... [ 5.782466] systemd[1]: Detected virtualization kvm. [ 5.782712] systemd[1]: Detected architecture x86-64. [ 5.782954] systemd[1]: Running in initrd. Welcome to Oracle Linux Server 9.5 dracut-057-70.git20240819.0.1.el9 (Initramfs)! [ 5.803070] systemd[1]: No hostname configured, using default hostname. [ 5.803327] systemd[1]: Hostname set to <localhost>. [ 5.803604] systemd[1]: Initializing machine ID from VM UUID. ... Starting installer, one moment... anaconda 34.25.5.9-1.0.3.el9 for Oracle Linux 9.5 started. * installation log files are stored in /tmp during the installation * shell is available on TTY2 * if the graphical installation interface fails to start, try again with the inst.text bootoption to start text installation * when reporting a bug add logs from /tmp as separate text/plain attachments ================================================================================ ================================================================================ Text mode provides a limited set of installation options. It does not offer custom partitioning for full control over the disk layout. Would you like to use VNC mode instead? 1) Start VNC 2) Use text mode Please make a selection from the above ['c' to continue, 'q' to quit, 'r' to refresh]:
-
Press number
2
, and pressenter
(Use text mode):Please make a selection from the above ['c' to continue, 'q' to quit, 'r' to refresh]: 2 ================================================================================ ================================================================================ Installation 1) [x] Language settings 2) [x] Time settings (English (United States)) (America/New_York timezone) 3) [!] Installation source 4) [!] Software selection (Processing...) (Processing...) 5) [!] Installation Destination 6) [x] Kdump (Processing...) (Kdump is enabled) 7) [x] Network configuration 8) [!] Root password (Connected: enp1s0) (Root account is disabled) 9) [!] User creation (No user will be created) Please make a selection from the above ['b' to begin installation, 'q' to quit, 'r' to refresh]:
-
Press letter
r
to refresh the text if you still see(Processing...)
in any of the numbered options. -
Once all options have been processed, press the number of any of the options that have a
[!]
(You will need to configure these until all numbered options have a[x]
after that press the letterb
to start the installation):Installation 1) [x] Language settings 2) [x] Time settings (English (United States)) (America/New_York timezone) 3) [x] Installation source 4) [x] Software selection (Local media) (Server with GUI) 5) [!] Installation Destination 6) [x] Kdump (Automatic partitioning (Kdump is enabled) selected) 7) [x] Network configuration 8) [!] Root password (Connected: enp1s0) (Root account is disabled) 9) [!] User creation (No user will be created) Please make a selection from the above ['b' to begin installation, 'q' to quit, 'r' to refresh]: 5
-
After you have pressed the installation, the OS will start to install the packages:
Please make a selection from the above ['b' to begin installation, 'q' to quit, 'r' to refresh]: b ================================================================================ ================================================================================ Progress . Setting up the installation environment Configuring storage Creating disklabel on /dev/vda Creating xfs on /dev/vda1 Creating lvmpv on /dev/vda2 Creating swap on /dev/mapper/ol-swap Creating xfs on /dev/mapper/ol-root ... Running pre-installation scripts . Running pre-installation tasks .... Installing. Starting package installation process Downloading packages Preparing transaction from installation source Installing libgcc.x86_64 (1/1209) Installing fonts-filesystem.noarch (2/1209) Installing linux-firmware-whence.noarch (3/1209) ... Installation complete Use of this product is subject to the license agreement found at: /usr/share/oraclelinux-release/EULA Installation complete. Press ENTER to quit:
-
Press
enter
, and wait until you see the following text in the terminal:... Oracle Linux Server 9.5 Kernel 5.15.0-302.167.6.el9uek.x86_64 on an x86_64 Activate the web console with: systemctl enable --now cockpit.socket localhost login:
-
Enter the username, and password that you configured:
Oracle Linux Server 9.5 Kernel 5.15.0-302.167.6.el9uek.x86_64 on an x86_64 Activate the web console with: systemctl enable --now cockpit.socket localhost login: <YOUR_USERNAME> Password: <YOUR_PASSWORD> [<YOUR_USERNAME>@localhost ~]$
-
To get out of the nested VM, you can press:
Ctrl
+Alt gr
++
[<YOUR_USERNAME>@localhost ~]$ ('Ctrl' + 'Alt gr' + '+') [opc@lab ~]$
-
To list the VMs running use:
[opc@lab ~]$ virsh list --all Id Name State ---------------------- 1 vm1 running
-
To get inside of the VM again use (Important: Press
enter
after the messageEscape character is ^] (Ctrl + ])
gets printed in the console):[opc@lab ~]$ virsh console vm1 --safe Connected to domain 'vm1' Escape character is ^] (Ctrl + ]) # PRESS ENTER HERE [<YOUR_USERNAME>@localhost ~]$
-
From the host VM you can manage this nested VM using virsh:
virsh shutdown <VM_NAME>
virsh start <VM_NAME>
virsh suspend <VM_NAME>
virsh resume <VM_NAME>
virsh edit <VM_NAME>
And many other options that can be found in the virsh libvirt documentation.
-
To install more VMs, first create additional disks by replacing
<VM_DISK>
:[opc@lab ~]$ qemu-img create -f qcow2 disks/<VM_DISK>.qcow2 20G
-
And finally replace
<VM_NAME>
and<VM_DISK>
:[opc@lab ~]$ virt-install --name <VM_NAME> \ --memory 2048 \ --vcpus 2 \ --location /home/opc/isos/OracleLinux-R9-U5-x86_64-dvd.iso \ # Reusing ISO --disk path=/home/opc/disks/<VM_DISK>.img,size=20 \ --os-variant ol9.5 \ --arch x86_64 \ --virt-type kvm \ --graphics none \ --network default \ --extra-args "console=tty0 console=ttyS0,115200N8" \ --debug
Once you have finished with this demo, you can destroy the VMs:
[opc@lab ~]$ virsh destroy <VM_NAME> Domain '<VM_NAME>' destroyed
Undefine the VMs:
[opc@lab ~]$ virsh undefine <VM_NAME> Domain '<VM_NAME>' has been undefined
And remove the qcow2 and ISO files:
[opc@lab ~]$ rm -rf /home/opc/{disks,isos}
Conclusion
Provisioning a VM inside another VM in OCI by using nested virtualization is just the beginning of unlocking more complex scenario for building and testing. By leveraging the power of code and automation, you can create, scale, and orchestrate clusters of VMs with ease, allowing you to run and test a wide range of programs in isolated environments. This virtual separation ensures that each VM operates independently, without affecting the others, making it an ideal solution for testing, development, and deployment of applications. Depending on your requirements, you may change the amount of CPU, memory, storage, etc. that the host machine or VM has configured to provision more nested VMs.