Your web hosting partners since 2004.
Buy now »

FAQ » Servers

How do I install Linux KVM on CentOS 7?

So you want to install and setup the Linux KVM on a CentOS 7 or RHEL (Red Hat Enterprise Linux) 7 server?

Well, let's get started...

Kernel-based Virtual Machine (KVM) is virtualisation software available on CentOS 7 and RHEL 7.

In this tutorial you will learn how to install the latest version of KVM on CentOS 7, it should be the same as on RHEL

7.

Prerequisites

You need to be sure that the server you're about to install on has the capability.

You'll need to check that your server has Virtualization Technology (VT) enabled.

You can also run the following command to test if CPU Support Intel VT and AMD-V Virtualization:

# lscpu | grep Virtualization
Virtualization:        VT-x

Install KVM

We can install the software from the default CentOS repository using the following command.

# yum install qemu-kvm libvirt libvirt-python libguestfs-tools virt-install

When you get prompted, just press 'y':

Is this ok [y/d/N]: y

When it's done, you'll see a message that says Complete!.

Start

Once you have installed KVM, start and enable it using the following commands.

# systemctl enable --now libvirtd

Verify

You can check that the KVM module is loaded by using the lsmod command:

# lsmod | grep -i kvm
kvm_intel             188740  0 
kvm                   637515  1 kvm_intel
irqbypass              13503  1 kvm

Configure bridged networking

By default, the dhcpd based network bridge is configured by libvirtd.

You can verify that with the following commands:

# brctl show
bridge name bridge id       STP enabled interfaces
virbr0      8000.525400c003ea   yes     virbr0-nic

# virsh net-list
 Name                 State      Autostart     Persistent
----------------------------------------------------------
 default              active     yes           yes

Verify the private network

A private network 192.168.122.0/24 will have been created, so the virtual servers only have network access to themselves.

# virsh net-dumpxml default
<network>
  <name>default</name>
  <uuid>2ec8eb57-7a10-4675-a6e8-2d6da5879475</uuid>
  <forward mode='nat'>
    <nat>
      <port start='1024' end='65535'/>
    </nat>
  </forward>
  <bridge name='virbr0' stp='on' delay='0'/>
  <mac address='52:54:00:c0:03:ea'/>
  <ip address='192.168.122.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.122.2' end='192.168.122.254'/>
    </dhcp>
  </ip>
</network>

Bridge

To make the virtual servers available to the Internet, we need to bridge from our network interface.

If you want the virtual servers available to the LAN, you'll need to ensure you have a bridge on your network interface card (NIC).

# brctl show
bridge name bridge id       STP enabled interfaces
br0     8000.002590aa9c6e   no      eth0
virbr0      8000.525400c003ea   yes     virbr0-nic

If you don't have a br0, you'll need to set one up.

Add a bridge

To make the virtual servers available to the Internet, we need to bridge from our network interface.

If you want the virtual servers available to the LAN, you'll need to set a bridge on your network interface card (NIC).

Create the bridge

First, lets set up the bridge:

cat > /etc/sysconfig/network-scripts/ifcfg-br0 <<EOF
DEVICE=br0
BOOTPROTO=dhcp
DELAY="0"
IPV6_AUTOCONF="yes"
IPV6INIT="yes"
ONBOOT="yes"
TYPE="Bridge"
EOF
  • Note: Ensure you've added enough available IP addresses to your server from your LAN at this point.

Bring the bridge up by doing:

ifup br0

If you get Determining IP information for br0... failed. You might need to set the IP Address instead of using DHCP.

cat > /etc/sysconfig/network-scripts/ifcfg-br0 <<EOF
DEVICE=br0
DELAY="0"
IPV6_AUTOCONF="yes"
IPV6INIT="yes"
ONBOOT="yes"
TYPE="Bridge"
IPV6INIT="yes"
ONBOOT="yes"
BOOTPROTO="static"
IPADDR="123.123.123.100"
NETMASK="255.255.255.0"
GATEWAY="123.123.123.1"
EOF

When it works you'll be able to see something like this:

# ifconfig br0
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 123.123.123.100  netmask 255.255.255.0  broadcast 123.123.123.255
        inet6 fe80::c2c:7bff:fe56:5e75  prefixlen 64  scopeid 0x20<link>
        ether 0e:2c:7b:56:5e:75  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 23  bytes 3986 (3.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Add the bridge

Let's add the bridge to our nic.

You'll find your nic in the /etc/sysconfig/network-scripts/ directory, it's usually ifcfg-eth0.

You can see how it's currently setup by using the cat command: # cat /etc/sysconfig/network-scripts/ifcfg-eth0

You can add the bridge line by running the following command: # echo "BRIDGE=br0" >> /etc/sysconfig/network-scripts/ifcfg-eth0

Validate it's been added by doing a cat:

# cat /etc/sysconfig/network-scripts/ifcfg-eth0
...
BRIDGE=br0
  • Note: You can use vi if you're confident or nano if it's installed to edit the file instead if you prefer.

Restart network

  • Warning: This command will disconnect your server from the Internet and SSH may disconnect. If you aren't sure at this point, ensure you have an alternative way to access your server in case the network does not reconnect.

Now we've added the bridge to the nic, we'll need to restart it.

You can restart the networking service using the following command:

# /etc/init.d/network restart

Create the first virtual machine

We'll be using the virt-install command to setup a virtual machine instance.

KVM provides hardware-assisted virtualization for a wide variety of guest operating systems including Linux, BSD, Solaris, Windows, Haiku, ReactOS, Plan 9, AROS Research Operating System and macOS.

You can get the list of available os variants with:

# osinfo-query os

Get the ISO image

We're going to get started with a CentOS 7 Minimal install, so we'll use that ISO, so we can mount it as a CD-ROM:

cd /var/lib/libvirt/boot/
wget https://mirrors.edge.kernel.org/centos/7.9.2009/isos/x86_64/CentOS-7-x86_64-Minimal-2009.iso
wget https://mirrors.edge.kernel.org/centos/7.9.2009/isos/x86_64/sha256sum.txt
sha256sum -c sha256sum.txt | grep CentOS-7-x86_64-Minimal-2009.iso

You can use the --location command, but it's better to store the install media so you can use them again later.

  • WARNING: CDROM media does not print to the text console by default, so you likely will not see text install output. You might want to use --location. See the man page for examples of using --location with CDROM media.

Create a VM using ISO images

In this example, we'll be creating a CentOS 7 virtual machine with 2GB of RAM, 1 CPU, 1 NIC and 20GB of disk space:

virt-install \
    --virt-type kvm \
    --name guest1-centos7 \
    --ram 2048 \
    --vcpus 1 \
    --os-variant centos7.0 \
    --location https://mirrors.edge.kernel.org/centos/7.9.2009/isos/x86_64/CentOS-7-x86_64-Minimal-2009.iso \
    --network br0 \
    --graphics none \
    --disk size=20 \
    --wait 0
  • Note: This method of installing is not very fast or repeatable, so instead it's best to use "Cloud Images".

To remove this you can do:

# virsh shutdown guest1-centos7
# virsh undefine guest1-centos7
# virsh pool-destroy guest1-centos7
# rm -ri /var/lib/libvirt/images/guest1-centos7.qcow2

Bridged network with a static IP address

Bridged networking can also be used to configure the guest to use a static IP address. To configure a bridged network with a static IP address for the guest virtual machine, use the following options:

    --network br0 \
    --extra-args "ip=192.168.1.2::192.168.1.1:255.255.255.0:test.example.com:eth0:none"

Create a VM using a Cloud Image

There's a number of sources for Cloud Images depending on what operating system you want to run.

In this example, we'll be using CentOS 7.

Get the Cloud Image

# cd /var/lib/libvirt/boot
# wget http://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud.qcow2

Copy

# cp /var/lib/libvirt/boot/CentOS-7-x86_64-GenericCloud.qcow2 /var/lib/libvirt/images/vm-01.qcow2

Resize

# chown qemu:qemu /var/lib/libvirt/images/vm-01.qcow2
# chmod a-rwx,u+rw /var/lib/libvirt/images/vm-01.qcow2
# qemu-img resize /var/lib/libvirt/images/vm-01.qcow2 20G

Cloud-init

The cloud-init package is installed in the Linux KVM templates and is responsible for the initial setup of the image using instance data.

Instance data is mainly composed of:

  • meta-data.yml: cloud provided metadata: metadata for the cloud environment
  • user-data.yml: configuration provided by the user

For the KVM environment the NoCloud datasource is used to provide the metadata and user data. We need to create an ISO image with two YAML files: meta-data and user-data.

You'll find an example of the cloud init config.

We'll create one by running the command:

# { echo instance-id: iid-local01; echo local-hostname: vm-01; } > meta-data.yml
# cat meta-data.yml
instance-id: iid-local01
local-hostname: vm-01

The instance id can be anything, and is used to determine if it is the first boot. If you change the instance id, cloud-init will attempt to re-provision the image.

Although the hostname could alternatively be specified in the user data, it is better to have it in the metadata as it is set earlier in the boot process.

The user-data file allows you to customize the instance to great extends – see Cloud config examples. The file must start with the #cloud-config stanza.

We can set a password for the centos user:

%  openssl passwd -1 -salt Salt secret    
$1$Salt$RunSwBmbUPEKPtMT9.bOJ.
cat > user-data.yml <<EOF
#cloud-config
users:
  - name: centos
    groups: wheel
    lock_passwd: false
    passwd: '$1$Salt$RunSwBmbUPEKPtMT9.bOJ.'
    shell: /bin/bash
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
EOF

The password is secret.

Generate ISO

Generate an ISO image with the two files:

# genisoimage -output /var/lib/libvirt/boot/vm-01.iso -volid cidata -joliet -rock user-data.yml meta-data.yml
I: -input-charset not specified, using utf-8 (detected in locale settings)
Total translation table size: 0
Total rockridge attributes bytes: 339
Total directory bytes: 0
Path table size(bytes): 10
Max brk space used 0
183 extents written (0 MB)

Create the instance

Launch using virt-install by passing both disks as parameters, the actual image and the cloud-init iso we created.

sudo virt-install --name vm-01 \
    --memory 2048 \
    --vcpus 2 \
    --disk /var/lib/libvirt/images/vm-01.qcow2,device=disk,bus=virtio \
    --disk /var/lib/libvirt/boot/vm-01.iso,device=cdrom \
    --os-variant centos7.0 \
    --virt-type kvm \
    --graphics none \
    --network network=default,model=virtio \
    --noautoconsole \
    --import
  • Note: on using the --noautoconsole argument, virt-install doesn’t open a console to the guest VM after creation, it just exits. This is essential for automation.

To destroy this instance:

virsh shutdown vm-01
virsh undefine vm-01
virsh pool-destroy vm-01

Accessing the console

Access the console and start installation:

virsh console vm-01

Troubleshooting

Domain installation still in progress

It looks like you're trying to install using graphics over the console, this won't work. Use --graphics none and --wait 0.

Check the logs: tail -f ~/.cache/virt-manager/virt-install.log

Also see

Last updated: 2022-02-19

« Go Back

Order now »

No problems