Update Nov 2021: I have written a newer article that deploys ESXi 7.0U1.
If you are running KVM on an Ubuntu server, you already have an excellent Type 1 virtualization engine. Luckily, if you need to test something specific to VMware you can always run ESXi 6.7 nested inside a KVM virtual machine.
In this article, I’ll be using a bare metal server running Ubuntu and KVM as a type 1 hypervisor.
I will then provide instructions for how to create a KVM virtual machine that runs VMware ESXi 6.7, and then smoke test by deploying a guest OS on top of the ESXi hypervisor.
Install KVM
I am assuming you are running Ubuntu and have already installed and smoke tested KVM as described in my previous article.
Enable VT-x
You need to make sure your CPU is capable of VT-x (virtualization acceleration), and then that your BIOS has VT-x enabled. Many computers have it disabled by default in the BIOS.
The easiest way to check is kmv-ok.
$ sudo apt-get install cpu-checker $ kvm-ok INFO: /dev/kvm exists KVM acceleration can be used
Then check using virt-host-validate.
$ 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 : PASS QEMU: Checking if IOMMU is enabled by kernel : PASS QEMU: Checking for secure guest support : WARN (Unknown if this platform has Secure Guest support) LXC: Checking for Linux >= 2.6.26 : PASS LXC: Checking for namespace ipc : PASS LXC: Checking for namespace mnt : PASS LXC: Checking for namespace pid : PASS LXC: Checking for namespace uts : PASS LXC: Checking for namespace net : PASS LXC: Checking for namespace user : PASS LXC: Checking for cgroup 'cpu' controller support : PASS LXC: Checking for cgroup 'cpuacct' controller support : PASS LXC: Checking for cgroup 'cpuset' controller support : PASS LXC: Checking for cgroup 'memory' controller support : PASS LXC: Checking for cgroup 'devices' controller support : PASS LXC: Checking for cgroup 'freezer' controller support : PASS LXC: Checking for cgroup 'blkio' controller support : PASS LXC: Checking if device /sys/fs/fuse/connections exists : PASS
And lastly, you should see a number greater than 0 coming back from cpuinfo.
egrep -c '(vmx|svm|ept)' /proc/cpuinfo
If you do not have this enabled, reboot your machine and press the special function key (F1|F2|F10|DEL|ESC|alt-S) that takes you into the BIOS. Each BIOS is different but look for “Virtualization Technology” or “VT-x”.
We cannot created a nested virtualization solution without this support.
Configure VT-x in OS
In addition to enabling VT-x at the BIOS level, you will also need to configure it at the Ubuntu OS level. In the file “/etc/modprobe.d/qemu-system-x86.conf”, set the following lines.
options kvm ignore_msrs=1 report_ignored_msrs=0 options kvm_intel nested=1 enable_apicv=0 ept=1
Then in order to workaround an issue with Ubuntu, force the value for ignore_msrs
echo 1 | sudo tee /sys/module/kvm/parameters/ignore_msrs
Reboot the host, then login and run the following commands.
# want Y to be returned cat /sys/module/kvm/parameters/ignore_msrs # want N to be returned cat /sys/module/kvm_intel/parameters/enable_apicv # want Y to be returned cat /sys/module/kvm_intel/parameters/nested # want Y to be returned cat /sys/module/kvm_intel/parameters/ept
Download vSphere Hypervisor
The VMware vSphere Hypervisor ESXi is a commercial product, but when you create an account you can download a 60 day trial.
Go to this page, scroll down the “Standard” version and click on “VMware vSphere Hypervisor (ESXi) 6.7 U3b” and then download the “VMWare vSphere Hypervisor (ESXI ISO) Image (Includes VMware Tools)”. It is about 335Mb.
Download Ubuntu Network installer
Since we are on an Ubuntu host, let’s download the mini.iso for the network installer of Ubuntu Focal. This file is only 75Mb, so it is perfect for testing. When complete, you should have a local file named “~/Downloads/mini.iso”.
Create KVM Virtual Machine
Now we are ready to create a KVM virtual machine capable of running ESXi. Run the ‘virt-install’ command below, tailoring it to any specific cpu/disk/ram requirements.
virt-install --virt-type=kvm --name=esxi1 --cpu host-passthrough --ram 4096 --vcpus=4 --virt-type=kvm --hvm --cdrom ~/Downloads/VMware-VMvisor-Installer-201912001-15160138.x86_64.iso --network network:default,model=e1000 --graphics vnc --video qxl --disk pool=default,size=80,sparse=true,bus=ide,format=qcow2 --boot cdrom,hd --noautoconsole --force
Then validate this virtualized guest will inherit the host cpu virtualization enablement.
# need host passthrough of cpu virtualization features $ virsh dumpxml esxi1 | grep '<cpu' <cpu mode='host-passthrough' check='partial'/>
You need to have the CDROM connected after power up. Depending on the domain xml, you may have to attach it as device “hdb” or “hdc” so look at the <target dev=”hd?“> label of the cdrom device.
cdrom=`virsh domblklist esxi1 --details | grep cdrom | awk {'print $3'}` virsh change-media esxi1 $cdrom ~/Downloads/VMware-VMvisor-Installer-6.7.0-8169922.x86_64.iso --insert
With this connection to the CDROM, go ahead and reset the machine so it can use it for booting.
virsh reset esxi1
NOTE: The parameters I used in the virt-install command above are intentional, and I tried steer you around several issues that you could run into. The video type of qxl is intentional (cirrus made the initial setup screen loop), the disk is IDE purposely to avoid errors during the install, and the network is using a generic e1000 type which can be detected by the installer.
The supported hardware list of ESXi is narrow, so if you can get installation to work properly using other driver types, that is fine. Just know that it took me a while to get the combination above to work.
Installing ESXi
The initial ESXi boot menu should now come up.
And then just like a normal ESXi install as described in many places on the web already [1,2,3,4].
At the welcome screen, press <ENTER>
<F11> to accept the license
<ENTER> to select the single disk as the default install drive
<ENTER> on the default US keyboard
input the initial password for root (my future vCenter articles assume ‘ExamplePass@456’)
<ENTER> if you receive CPU future support warning
<F11> to validate install on disk
…installing…
message to disconnect the CDROM before rebooting
virsh change-media esxi1 ~/Downloads/VMware-VMvisor-Installer-6.7.0-8169922.x86_64.iso --eject
<ENTER> to reboot
After rebooting, you should see the screen below giving you the 192.168.122.x address of the ESXi server (192.168.122.0/24 is the default NAT network used by KVM).
Press <F2> and then enter in the root password you typed during the install. You will want to go to “Troubleshooting Options”, and enable the ESXi shell and SSH before pressing <ESC> twice to go back to the main screen.
ESXi Embedded Host Client
Using a web browser, go to the URL specified in the ESXi startup screen (https://<server>/ui/).
You should get the login page, use your “root” credentials to login and you should see a screen similar to below which is the Embedded Host Client.
This HTML/Javascript application is a lightweight management interface served directly from the ESXi host. Note that it cannot be used to manage vCenter (like /vsphere-client).
Creating a Virtual Machine
Remember at this point, that we are multiple layers down in virtualization engines. ESXi is running nested inside KVM. So now let’s create a guest VM inside ESXi to ensure this works.
First press “Create/Register VM”.
Then choose to “Create a new virtual machine” and press Next.
Type a name of “esxchild1” for the guest OS and select a Linux host, Ubuntu Linux (64-bit).
We only created a single 80Gb disk for the ESXi host, so allow the default datastore1 and press Next
Then the customize settings come up, and you can leave the default 1 vcpu and 1024M memory.
But the one thing you should change is the CD/DVD drive. We want to use the Ubuntu network installer ISO on your local system at “~/Downloads/mini.iso”. Select “Datastore ISO file” from the pulldown instead of “Host device” and a datastore browser will show.
Press “Upload” and select the mini.iso file from your local drive. Then click on the file in the middle column, and press “Select”. This will take you back to the main settings window and just make sure “Connect” is checked beside the CDROM.
You are now at the finish screen, review your choices and press Finish.
Now navigate using the tree on the left to “esxchild1” and notice the power is still off. Go ahead and press the power button.
You should see the preview screen change and the Ubuntu logo will be visible. Press “Console” and then “Open browser console” to get an interactive screen.
We will stop this exercise here, but this OS could be installed and this host could be used exactly the same as a guest OS created under KVM.
Stability Issues
If you find that your ESXi host often experiences the VMware “Purple Screen of Death”, remember the supported hardware list for VMware is narrow, and you are probably experiencing incompatibility with host hardware or drivers.
I saw a great deal of improvement by having KVM use the newest OVMF UEFI firmware for the virtual machine instead as well as the latest SeaBIOS. The version of SeaBIOS distributed with KVM is very old.
The firmware is easily set for a KVM host by adding a <loader> element to the <os> section of the xml. But this must be done before ESXi is installed, so it takes a rebuild if you want to switch.
Here is my article on building the latest OVMF image. Here is my article on building the latest SeaBIOS image if you want to stick with the legacy firmware standard. And here is my article on how to set the <loader> element so that your KVM virtual machine uses the updated firmware.
Further ESXi configuration steps
Here are a few more optional steps that can help in managing this ESXi host. If you are going to install vCenter next, you need to consider the static IP and hostname change mandatory – full DNS and reverse IP resolution is mandatory during the vCenter installation.
Setting a static IP is easier especially when manually managing DNS entries. This can be done from an ssh session and web GUI as well, but let’s do it directly from the ESX host console.
Choose “Configure Management Network>IPv4 Configuration” and set the IP, subnet, and default gateway as shown below.
The default name is “localhost”, so that is something you must change if you are going to address this server by DNS or from vCenter. Choose “Configure Management Network>DNS Configuration” and set the full hostname and primary DNS server.
In the above screenshot I have set the hostname to “esxi1”, if you want the certificate to have a fully qualified domain name, then provide the full value (e.g. “esxi1.home.lab”).
If you are using fully qualified hostname, choose Choose “Configure Management Network>Custom DNS Suffixes” and enter in the domain name that should be appended on searches.
Certificate Regeneration [1,2,3,4]
The initial certificate delivered on the ESXi is CN=localhost.localdomain. To change this to a self-signed cert that reflects the true name use the ‘generate-certificates’ utility from an ssh session to the ESXi host.
# check current cert cd /etc/vmware/ssl hostname # full host should reflect FQDN for cert generation hostname -f openssl x509 -in rui.crt -text -noout | grep Subject # backup certs tar cvfz /etc-vmware-ssl.tgz * # generate new certs /sbin/generate-certificates openssl x509 -in rui.crt -text -noout | grep Subject # restart services /etc/init.d/hostd restart /etc/init.d/vpxa restart
If you now refresh your browser on the ESXi Embedded Host Client and look at the certificate, it will show your hostname for the CN. Note that it is still a self-signed certificate (and therefore untrusted by default).
SSH/SCP access
Enabling ssh access earlier at the console did enable ssh when ESXi is the target host, but ssh/scp initiated from the ESXi host to another host is still not enabled. All you will see is “FIPS mode initialized” and a timeout.
To make this work, you need to disable a firewall rule. Run the following commands to check the firewall rule, then disable it.
esxcli network firewall ruleset list --ruleset-id sshClient esxcli network firewall ruleset set --ruleset-id sshClient --enabled=true
At that point, scp initiated from the ESXi host will work.
MOB enablement
Although it is disabled by default for security reasons, on a lab or non-production system you may need to use the MOB (Managed Object Browser). For example, to view the VT-x and EPT features passed through to your nested ESXi server using a URL like below:
https://esxi1.home.lab/mob/?moid=ha-host&doPath=capability
But first it must be enabled, and this can be done via vCenter or from the console of the ESX server using ‘vim-cmd’:
# set value vim-cmd hostsvc/advopt/update Config.HostAgent.plugins.solo.enableMob bool true # check value vim-cmd hostsvc/advopt/settings | grep -A1 Mob
Next steps
The next logical step is to install vCenter, which I describe in this article.
REFERENCES
https://docs.vmware.com/en/VMware-vSphere/6.7/rn/vsphere-esxi-vcenter-server-67-release-notes.html#compatibility (HW support list for 6.7)
https://www.pluralsight.com/blog/it-ops/top-vmware-compatibility-issues (top compat issues)
https://www.thehumblelab.com/vsphere-67-homelabs-unsupported-cpu/ (working around incompat)
https://tinkertry.com/patch-esxi-6-manually (upgrade keeping vib)
https://xenserver.org/blog/entry/vga-over-cirrus-in-xenserver-6-2.html (using cirrus)
https://www.redhat.com/archives/libvirt-users/2015-April/msg00067.html (try to use raw disk not qcow2)
https://haveyoutriedreinstalling.com/2017/07/17/vsphere-6-x-certificates-just-because-you-can-doesnt-mean-you-should/ (list of certs in vsphere 6)
https://rwmj.wordpress.com/2014/05/19/notes-on-getting-vmware-esxi-to-run-under-kvm/
boxofcables.dev, kvm intel ept parameter for EPT and list of qemu cpu flags
ahelpme.com, Ubuntu get cpu flags for qemu
kernel.org, nested kernel kvm support
kernel.org, running nested guests with KVM
stackoverflow, checking for IOMMU using comgen and dmesg
golinuxhub, check guest Hyperthreading using dmidecode, lscpu, /proc/cpuinfo
virtualizationhowto, cpu mem bios on esxi host
rotelok.com, enabling KSM on Ubuntu
NOTES
If ESXi complaining about not supporting virtualization [1], from esxi host
cat /etc/vmware/config, add two keys:
vhv.enable = "TRUE" vmx.allowNested = "TRUE"
esx config info, HV Support enabled if value is 3 ; number of core/threads
esxcfg-info | grep "HV Support" -C10 vim-cmd hostsvc/hostsummary | grep cpuModel
get cpu and core results
esxcli hardware cpu global get
dmesg | grep -E “vmx|iommu”
Checking host VT-d virtualization for IO, IOMMU (different from cpu VT-x)
dmesg | grep -iE “dmar|iommu|aspm”
cat /var/log/kern.log | grep IOMMU
# another way for checking using Ubuntu 'compgen' utility if compgen -G "/sys/kernel/iommu_groups/*/devices/*" > /dev/null; then echo "IOMMU is enabled"; else echo "IOMMU is NOT enabled!"; fi
==add to /etc/default/grub (for VT-d) bug in 18.04
GRUB_CMDLINE_LINUX_DEFAULT=”intel_iommu=on”
$ grub-install –version
$ sudo update-grub (equiv to grub2-mkconfig)
dnsmasq keep from forwarding local addresses [1]
# /etc/dnsmasq.conf local=/home.lab/ address=/esxi1.home.lab/192.168.122.133
list of esxi software components [1]
esxcli software vib list
Direct ESXi host modes
<ALT>-<F1> goes to shell <ALT>-<F11> goes to status <ALT>-<F2> back to GUI
maintenance mode [1],
vim-cmd hostsvc/maintenance_mode_enter vim-cmd hostsvc/maintenance_mode_exit
mount cdrom from inside esxi [1,2]
vmkload_mod iso9660 esxcfg-mpath -b | grep "CD-ROM" cd /vmfs/volumes ls (should see mpx.*) vsish -e set /vmkModules/iso9660/mount $(esxcfg-mpath -b | grep "CD-ROM" | awk '{print $1}') vsish -e set /vmkModules/iso9660/umount $(esxcfg-mpath -b | grep "CD-ROM" | awk '{print $1}')
ESXi software repository and installs
Add-EsxSoftwareDepot, Get-EsxSoftwarePackage, Add-EsxSoftwarePackage
Get list of valid cpu flags for qemu
qemu-system-x86_64 -cpu help # used like qemu-system-x86_64 -enable-kvm \ -cpu qemu64,+sse3,+ss34.1,-sse4.2,+x2apic \ ... # if you want to emulate host qemu-system-x86_64 -enable-kvm \ -cpu host \ ...
List cpu model feature flag capabilities
virsh capabilities | grep -i sandy -C40
View qemu details for vm guest startup
ls -latr /var/log/libvirt/qemu
Use change-media instead of attach disk with empty string
# don't use this, use change-media $ virsh attach-disk esxi1 "" hdc --type cdrom --mode readonly
Exact VMware versions used for this article
esxi iso: VMware-VMvisor-Installer-201912001-15160138.x86_64.iso (6.7 u3b)
vcenter iso: VMware-VCSA-all-6.7.0-16708996.iso (6.7 u3j)
seabios used on esxi: rel-1.14.0-13-g94f0510