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 ornano
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 environmentuser-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
- How to install KVM on CentOS 7 / RHEL 7 Headless Server
- Howto use centos cloud images with cloud-init on KVM/libvirtd
- Cloud-init example using a Generic Cloud CentOS-7 on a libvirtd qmu/kvm lab
- How to create VM using the qcow2 image file in KVM
- VM with cloud-init
- Resize and manage cloud-init on kvm with centos cloud images
- run CentOS Atomic under KVM
- Virtual Laboratory with Linux, KVM, etc.
- A Quick Start With The Oracle Linux Templates For KVM
- How To Provision VMs on KVM with Terraform
- Tester vos scripts cloud-init en local
- Cloud config examples
- Creating a VM using Libvirt, Cloud Image and Cloud-Init
- kcli
- kvm-install-vm
Last updated: 2022-02-19