KVM Virtualization

Kernel-based Virtual Machine (KVM) is a popular virtualization solution supported by modern Linux kernels. It takes advantage of the CPU support for virtualization (Intel VT and AMD-V). You can run unmodified operating systems such as Linux, FreeBSD, and Microsoft Windows using KVM. For more information, see the compatibility list.

For our Ubuntu 16.04 host, we have installed the following packages via apt (see https://help.ubuntu.com/lts/serverguide/libvirt.html):

  • libvirt-bin
  • qemu-kvm
  • virt-manager
  • virtinst
  • virt-viewer

For a CentOS 7 host, install the following packages via yum:

  • libvirt
  • qemu-kvm
  • qemu-img
  • virt-install
  • virt-manager
  • virt-client

For other Linux distributions, refer to their respective manuals.

You can create virtual machines using the command line as long as you have installed the proper packages. For example, the following creates a CentOS 7 guest with 2 virtual CPUs and 4GiB of RAM:

virt-install -n centos-test \
        --ram 4096 \
        --vcpus 2 \
        --metadata description='CentOS – test',title='CentOS - test' \
        --cdrom /usr/local/src/dists/CentOS/7/CentOS-7-x86_64-Everything-1511.iso \
        --os-variant centos7.0 \
        --disk path=/var/lib/libvirt/images/centos-test-storage0.qcow2,size=40,format=qcow2 \
        --network bridge=br0,model=virtio \
        --graphics spice

If you want to have a processor topology of 2 sockets and 2 cores each, you can specify that as:

        ....
        --vcpus sockets=2,cores=2
        ....

Verification of the processor topology can be done using the utility lscpu, part of util-linux.

The --cdrom parameter points to the installation disc image and the --disk parameter points to the final installed OS image. In this example, we also specify the use of a bridge (the network device br0 in this case) to make it appear on the local host’s network as a regular host. The parameter --graphics specifies Spice as the means of connecting to the VM console.

Naturally, you can also use a GUI (virt-manager) to create the VM, but the command line is more fun, isn’t it? 😉 The man page for virt-install has the requisite information on how to use it. More examples are also available in the man page.

 

Adding Custom Services With systemd

[vc_row][vc_column][vc_column_text]systemd is a system and service manager for Linux similar to SysV init. Several Linux distributions, notably Red Hat Enterprise Linux, SuSE, CentOS, Fedora, Debian and Ubuntu, are adopting it for their current or future releases. You can now experience systemd on Fedora and Red Hat Enterprise Linux 7 Beta.

We decided to install customized versions of Apache httpd and Percona Server, both of which must be started on boot.  systemd configurations had to be created for these.  We based our configuration files on existing ones for Apache httpd and MySQL. Furthermore, we made sure that necessary directories for these software are created at boot time.

The procedures described below were done on a VMware installation of Red Hat Enterprise Linux 7 Beta. These procedures should work on Fedora 20 as well (we’ll verify this in the future).

First, we compile and install Apache httpd version 2.4.9 (we’ll write an article about this in the future). Our installation of Apache httpd is in /opt/apache. The configuration files are in /etc/opt/apache while the logs are in /var/opt/apache.  Note that this layout of the installation is the opt layout for Apache httpd which is specified during configuration of the source.

Let us take a look at the systemd configuration file for the built-in Red Hat httpd daemon:

[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/httpd
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
ExecStop=/bin/kill -WINCH ${MAINPID}
# We want systemd to give httpd some time to finish gracefully, but still want
# it to kill httpd after TimeoutStopSec if something went wrong during the
# graceful stop. Normally, Systemd sends SIGTERM signal right after the
# ExecStop, which would kill httpd. We are sending useless SIGCONT here to give
# httpd time to finish.
KillSignal=SIGCONT
PrivateTmp=true
[Install]
WantedBy=multi-user.target

The above file, named httpd.service, is found in /usr/lib/systemd/system.

We now create another file which we name as apache-httpd.service and place in /etc/systemd/system. Note that we must make sure that httpd.service is disabled. Let us disable it using the command:

sudo systemctl disable httpd.service

To check the status of a service, we can type the following command:

sudo systemctl status httpd.service

Now, our apache-httpd.service file for the custom Apache httpd installation contains the following:

[Unit]
Description=The Apache HTTP Server (akumubuild)
After=network.target remote-fs.target nss-lookup.target percona-server.service
[Service]
#Type=notify
Type=forking
#Type=dbus
#BusName=com.redhat.apache-httpd
EnvironmentFile=/etc/sysconfig/apache-httpd
#ExecStart=/opt/apache/sbin/httpd $OPTIONS -DFOREGROUND
ExecStart=/opt/apache/sbin/httpd $OPTIONS 
ExecReload=/opt/apache/sbin/httpd $OPTIONS -k graceful
ExecStop=/bin/kill -WINCH ${MAINPID}
# We want systemd to give httpd some time to finish gracefully, but still want
# it to kill httpd after TimeoutStopSec if something went wrong during the
# graceful stop. Normally, Systemd sends SIGTERM signal right after the
# ExecStop, which would kill httpd. We are sending useless SIGCONT here to give
# httpd time to finish.
KillSignal=SIGCONT
PrivateTmp=true
PIDFile=/var/opt/apache/run/httpd.pid
[Install]
WantedBy=multi-user.target

The original httpd.service was used as a template. Note the differences. For apache-httpd.service, we allow httpd to fork. The Reload command does not use a kill command. Instead, '-k graceful' is passed to httpd.  Note that we also refer to the percona-server.service which we will discuss later.

We enable apache-httpd.service using ‘sudo systemctl enable apache-httpd.service‘.  Again, use the status command of systemctl to check on the service.  If it isn’t started, issue the command ‘sudo systemctl start apache-httpd.service‘.  The ‘enable‘ command makes sure that the service is started at boot time while ‘start‘ simply runs the service.

We should see the following by checking the status (‘sudo systemctl status apache-httpd’) of our custom installation of Apache httpd:

apache-httpd.service - The Apache HTTP Server (akumubuild)
   Loaded: loaded (/usr/lib/systemd/system/apache-httpd.service; enabled)
   Active: active (running) since Thu 2014-04-03 00:44:31 EDT; 1 day 17h ago
 Main PID: 1942 (httpd)
   CGroup: /system.slice/apache-httpd.service
           ├─1942 /opt/apache/sbin/httpd
           ├─1998 /opt/apache/sbin/httpd
           ├─1999 /opt/apache/sbin/httpd
           ├─2048 /opt/apache/sbin/httpd
           ├─2049 /opt/apache/sbin/httpd
           ├─2050 /opt/apache/sbin/httpd
           └─3237 /opt/apache/sbin/httpd
Apr 03 00:44:30 akumu.hq.linuxunbound.com systemd[1]: PID file /var/opt/apache/run/httpd.pid not re...rt.
Apr 03 00:44:31 akumu.hq.linuxunbound.com systemd[1]: Started The Apache HTTP Server (akumubuild).
Hint: Some lines were ellipsized, use -l to show in full.

Some things to consider:

  • Make sure the file /etc/sysconfig/apache-httpd exists.  This doesn’t have to contain anything though you can add some optional parameters to httpd by assigning them to the shell variable OPTIONS.
  • The directories /var/opt/apache/logs and /var/opt/apache/run must exist.

[GARD align=”center”]

Percona Server for MySQL

The MySQL-compatible Percona Server should have the following configuration file in /usr/lib/systemd/system named percona-server.service:

[Unit]
Description=The Percona Server (MySQL)
# See https://bugzilla.redhat.com/show_bug.cgi?id=714426
After=network.target remote-fs.target nss-lookup.target
Before=apache-httpd.service
[Service]
#Type=notify
#Type=forking
#Type=dbus
Type=simple
EnvironmentFile=/etc/sysconfig/percona-server
ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf --user=mysql $OPTIONS 
#ExecStop=/usr/local/mysql/bin/mysqladmin -u root -p shutdown
ExecStop=/bin/kill -TERM ${MAINPID}
ExecReload=/bin/kill -HUP ${MAINPID}
PrivateTmp=true
PIDFile=/var/run/mysqld/mysqld.pid
[Install]
WantedBy=multi-user.target

Again, we must make sure that certain files and directories exist:

  • the file /etc/sysconfig/percona-server
  • the directory /var/log/mysqld (or whatever is specified in /etc/my.cnf)
  • the directory /var/run/mysqld

Take note that /var/run/mysqld is a temporary directory that is created at boot time and deleted at shutdown.  We need to create a file called /etc/tmpfiles.d/percona.conf which contains the following:

d /run/mysqld 0755 mysql mysql -

This configuration file creates the directory /run/mysqld with mode 0755 and ownership by user ‘mysql‘ and group ‘mysql‘.

Enable the Percona Server service using systemctl as you did for Apache httpd.  Once it is running, you should see something like this status:

percona-server.service - The Percona Server (MySQL)
   Loaded: loaded (/usr/lib/systemd/system/percona-server.service; enabled)
   Active: active (running) since Thu 2014-04-03 00:44:28 EDT; 1 day 17h ago
 Main PID: 1842 (mysqld)
   CGroup: /system.slice/percona-server.service
           └─1842 /usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf --user=mysql
Apr 03 00:44:28 akumu.hq.linuxunbound.com systemd[1]: Started The Percona Server (MySQL).

More information on systemd can be found on their wiki.[/vc_column_text][/vc_column][/vc_row]