How to install KVM on Ubuntu 14.04 LTS Headless Server

Kernel-based Virtual Machine (KVM) is a virtualization module for the Linux kernel that turns it into a hypervisor. How can I install KVM, setup guest operating system as the back-end virtualization technology for non-graphic Ubuntu Linux 14.04 LTS server?

You can use KVM to run multiple operating systems such as Windows, *BSD, Linux distro using virtual machines. Each virtual machine has its private disk, graphics card, a network card and more.

What is a hypervisor?

KVM is a hypervisor that creates and run virtual machines. A server on which a hypervisor is running is called as a host machine. Each virtual machine is referred to as a guest machine. Using KVM, you can run multiple operating systems such as CentOS, OpenBSD, FreeBSD, MS-Windows running unmodified.

Fig.01: What is KVM hypervisor?

Fig.01: What is KVM hypervisor?

Steps for installing KVM on Ubuntu Linux 14.04 LTS

  1. The host server located in the remote data center and it is a headless server.
  2. All commands in this tutorial typed over the ssh based session.
  3. You need a vnc client to install the guest operating system.
  4. In this tutorial, you will learn how to install KVM software on Ubuntu and use KVM to setup your first guest VM.

Find out if server is capable of running hardware accelerated KVM vm

You need to use the kvm-ok command to determine if the server can host hardware accelerated KVM virtual machines. First install cpu-checker package using the following apt-get command:
$ sudo apt-get install cpu-checker
Sample outputs:

Fig.02: Installing cpu-checker on Ubuntu Linux

Next, run the following command:
$ sudo kvm-ok
Sample outputs:
INFO: /dev/kvm exists
KVM acceleration can be used

Install kvm on Ubuntu Linux

Type the following apt-get command to install kvm and related software:
$ sudo apt-get install qemu-kvm libvirt-bin virtinst bridge-utils
Sample outputs:

Fig.03: Installing kvm on Ubuntu Linux using apt-get

Default configuration locations

  1. Default directory: /var/lib/libvirt/
  2. ISO images for installation: /var/lib/libvirt/boot/
  3. VM installation directory: /var/lib/libvirt/images/
  4. Libvirt configuration directory for LVM/LXC/qemu: /etc/libvirt/

More about the default networking for VM

The default networking is called ‘default’. To list networks, enter:
$ sudo virsh net-list
Sample outputs:

 Name                 State      Autostart     Persistent
 default              active     yes           yes

For network information, enter:
$ sudo virsh net-info default
Sample outputs:

Name:           default
UUID:           1c0abaa3-8d17-45b5-85e9-c0d48cec94f9
Active:         yes
Persistent:     yes
Autostart:      yes
Bridge:         virbr0

To dump network information in XML format, enter:
$ sudo virsh net-dumpxml default
Sample outputs:

<network connections='1'>
  <forward mode='nat'>
      <port start='1024' end='65535'/>
  <bridge name='virbr0' stp='on' delay='0'/>
  <ip address='' netmask=''>
      <range start='' end=''/>

Create a CentOS Linux VM

First, grab the CentOS Linux 7.x DVD ISO file:
$ cd /var/lib/libvirt/boot/
$ sudo wget
$ ls

Sample outputs:

CentOS-7-x86_64-Minimal-1511.iso  install58.iso

To provision new virtual machines use virt-install command. In this example, I’m creating a CentOS 7.x VM with 1GB RAM, 1 CPU core, and 20GB disk space, enter:
$ sudo virt-install \
--virt-type=kvm \
--name centos7 \
--ram 1024 \
--vcpus=1 \
--os-variant=rhel7 \
--hvm \
--cdrom=/var/lib/libvirt/boot/CentOS-7-x86_64-Minimal-1511.iso \
--network network=default,model=virtio \
--graphics vnc \
--disk path=/var/lib/libvirt/images/centos7.img,size=20,bus=virtio

Sample outputs:

Starting install...
Allocating 'centos7.img'                                                                     |  20 GB     00:00     
Creating domain...                                                                           |    0 B     00:00     
WARNING  Unable to connect to graphical console: virt-viewer not installed. Please install the 'virt-viewer' package.
Domain installation still in progress. You can reconnect to 
the console to complete the installation process.

Understanding virt-install options

  1. --virt-type=kvm : Use kvm as the hypervisor to install CentOS7 guest.
  2. --name centos7 : Name of the new guest virtual machine instance.
  3. --ram 1024 : Memory to allocate for guest instance in megabytes.
  4. --vcpus=1 : Number of virtual cpus to configure for the guest.
  5. --os-variant=rhel7 : Optimize the guest configuration for a specific operating system variant. Use ‘virt-install --os-variant list‘ to see the full OS list.
  6. --hvm : Request the use of full virtualization.
  7. --cdrom=/var/lib/libvirt/boot/CentOS-7-x86_64-Minimal-1511.iso : File or device use as a virtual CD-ROM device for fully virtualized guests. It can be path to an ISO image, or to a CDROM device.
  8. --network network=default,model=virtio : Connect the guest to the host network. In this example, connect to a virtual network in the host called “default” with nic model called virtio.
  9. --graphics vnc : Setup a virtual console in the guest and export it as a VNC server in the host. This is useful for our headless server (see below).
  10. --disk path=/var/lib/libvirt/images/centos7.img,size=20,bus=virtio : Specifies media to use as storage for the guest. A path to /var/lib/libvirt/images/centos7.img storage media to use with size (20 GB) to use if creating new storage and disk bus type set to virtio.

A note about VNC and a headless server

This is a headless server i.e. a server without a local interface or GUI. There is no monitor or peripherals, such as a keyboard and mouse attached to this server. To continue installation you need to use the vnc client from your own laptop or desktop. To find out information about the vnc server port, enter:
$ sudo virsh dumpxml centos7 | grep vnc
Sample outputs:

    <graphics type='vnc' port='5901' autoport='yes' listen=''>

Please note down the port value (i.e. 5901). You need to use an SSH client to setup tunnel and a VNC client to access the remote vnc server.

To access guest domain’s VNC console

Type the following SSH port forwarding command:
$ ssh -L 5901:

  1. ssh – Establishes the SSH session to the remote KVM host at host.
  2. -L – Start local port forwarding.
  3. 5901: – Setup tunnel i.e. pass traffic over the internet to access remote server and port 5901. See “Setup SSH To Tunnel VNC Traffic Though Internet” for more information.

Once you have ssh tunnel established, you can point your VNC client at your own (localhost) address and port 5901 as follows:

Fig.04: Accessing VNC consoles of KVM guests via SSH

You should see CentOS Linux 7 guest installation screen as follows:

Fig.05: CentOS 7 guest vm installation

Just follow on screen instructions to install CentOS 7. After some time CentOS 7 installed successfully on my server and ready to use. Go ahead and click reboot button. The remote server closed the connection to our VNC client. Type the following command to boot up VM for the first time:
$ sudo virsh start centos7
Sample outputs:
Domain centos7 started

Verify it:
$ sudo virsh list
Sample outputs:

 Id    Name                           State
 3     puffy                          running
 5     centos7                        running

Again use an SSH client to setup tunnel and a VNC client to access CentOS 7 vm via the vnc server:

Fig.07: Sample CentOS 7 vm session using VNC

And, there you have it a CentOS 7 vm running KVM on top of the Ubuntu Linux 14.04 LTS server. In the default configuration, the CentOS 7 guest operating system will have access to network services, but will not be visible to other machines on the network or from the Internets. The CentOS VM will not be able to host an accessible web server. In next part of this tutorial I will talk about port forwarding and setting up bridged networking to connect to the outside network transparently.
🐧 Get the latest tutorials on Linux, Open Source & DevOps via RSS feed or Weekly email newsletter.

🐧 12 comments so far... add one

CategoryList of Unix and Linux commands
Disk space analyzersdf ncdu pydf
File Managementcat cp mkdir tree
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network UtilitiesNetHogs dig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
12 comments… add one
  • tomas teman Jan 27, 2016 @ 20:44

    Excellent, excellent. Thx.
    I’m not an admin, but I needed to understand what kind of complexity is involved in this. I appreciate you effort!
    All the best.


  • karlo Jan 27, 2016 @ 21:05

    Hi, thx for your post. I have a case:
    1. Laptop (Elementary OS (Ubuntu 14.04) with kvm) with two graphic cards
    2. Create Windows VM.

    I’d like to run Elementary OS on Intel HD graphics (OK it’s working), but add second card (ATI Radeon) via KVM to Windows VM (no as graphic memory, but as phisical video card). Is there any possobility to run this like I want?

  • Davor Jan 27, 2016 @ 21:39

    Good tutorial. Thnx.

  • Ahem Jan 28, 2016 @ 2:03

    Thanks for the post, can share the similar thing for RHEL

  • Bill s. Jan 28, 2016 @ 3:17

    Great compact tutorial!

  • Jesusguevarautomotriz Jan 29, 2016 @ 7:00

    Same case that

    @tomas teman
    Excellent, excellent. Thx.
    I’m not an admin, but I needed to understand what kind of complexity is involved in this. I appreciate you effort!
    All the best.

    As explained Impressively, well explained, that we the noobs, we can understand it.

    • Puneet Feb 2, 2016 @ 13:18

      Got an error tried with ubuntu 14.04

      root@semt-Latitude-E5440:/home/sgd# ls -la /var/run/libvirt/libvirt-sock
      srwxrwx--- 1 root libvirtd 0 Jan 18 12:35 /var/run/libvirt/libvirt-sock
      root@semt-Latitude-E5440:/home/sgd# sudo virt-install \
      > --virt-type=kvm \
      > --name ubuntuserveredition \
      > --ram 1024 \
      > --vcpus=1 \
      > --os-variant=rhel7 \
      > --hvm \
      > --cdrom=/var/lib/libvirt/boot/ubuntu-14.04-server-amd64.iso \
      > --network network=default,model=virtio \
      > --graphics vnc \
      > --disk path=/var/lib/libvirt/images/ubuntu1404server.img,size=8,bus=virtio

      Starting install…
      ERROR internal error: Cannot find suitable CPU model for given data
      Domain installation does not appear to have been successful.
      If it was, you can restart your domain by running:
      virsh –connect qemu:///system start ubuntuserveredition
      otherwise, please restart your installation.

  • starcasm Apr 28, 2016 @ 18:04

    Now what is
    Where did this come from?
    what do i need to do if I am going to run the vnc client from a Windows desktop?

    • adam May 10, 2016 @ 3:26

      i am also curious about both of these things

    • stv Jul 1, 2016 @ 16:39

      Yeah, I am stuck on the same thing. If you have to initiate the VNC session in order to complete the CentOS installation, how is it that you already have given it a hostname (server1) as well as added a user account (vivek)?

    • stv Jul 1, 2016 @ 16:54

      To share what I did that worked:
      From the host’s CLI, using the host’s username and password, use
      user@hostmachine:~$ ssh user@hostmachine -L 5901:

      This will begin the ssh tunnel so you can move to the next step. I think the author intended on this being the case, but it took some interpretation.

  • Michael Cooper Jun 21, 2016 @ 10:14

    Excellent article however I don;t see the network bridge addressed. You would need that for the VMs to communicate with in the network correct?

    # This file describes the network interfaces available on your system
    # and how to activate them. For more information, see interfaces(5).
    # The loopback network interface
    auto lo
    iface lo inet loopback
    # The primary network interface
    auto eth0
    iface eth0 inet manual
    # Bridged Network Interface #
    auto br0
    iface br0 inet static
            bridge_ports eth0
            bridge_fd 9
            bridge_hello 2
            bridge_maxage 12
            bridge_stp off

    I was just wondering why it wasn’t mentioned,

    Thanks for the great article.

Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre> for code samples. Still have questions? Post it on our forum