Product QVD 4.2 Virtual Deckard
QVD Docs Team <documentation@theqvd.com>
Legal notice

1. Introduction

The QVD provides demo desktop images for use with the product, but sooner or later the serious user will need to consider building their own desktops, tailored to the needs of their particular users. This guide aims to explain that process in its simplest form, and to give the administrator the basic building blocks for their own desktop images.

The process itself is fairly straightforward and entails the following steps to create KVM and LXC images:

  • Installing a clean build system in KVM

  • Installing inside that build system LXC userspace utils and creating a container (LXC only)

  • Configuring either the build system or the LXC container to run the QVD Virtual Machine Agent which manages the connections between the QVD client and the desktop

  • Customizing and branding the desktop to the needs of the user

  • Shutting down and zipping up the container or the KVM install itself

  • Deploying the zipped image to QVD using either the Web Administration Tool or the qvd admin command line tool

2. Building the Image

2.1. Install a Build System

To create a disk image for either KVM or LXC, you will need to install a base image to work from. This base image will form the basis of the KVM image if that is what you are creating, for LXC it will provide a system from which to build and zip an LXC image.

We will use the the lightweight Ubuntu variant Lubuntu to create the images as it is relatively small and comes with the minimal desktop LXDE as standard. We will use the the alternate download cd as it’s optimized for lower RAM installations and stick with the stable LTS release Bionic Beaver for purposes of stability, and for compatibility with LXC.

The iso can be found on the Lubuntu Bionic Alternate download page, or using this direct link. You can check the md5sum of the download here. Before we start, you will need to ensure that you have both qemu-kvm and qemu-utils installed.

$ sudo apt-get install qemu-kvm qemu-utils

Now, create a qcow2 disk image file, setting the maximum file size at 8GB which is the minimum required by Lubuntu. Note, however, that initially the file will be a fraction of this size as it will grow dynamically to accomodate needs. Indeed the final result should be considerably smaller and even less when compressed.

$ kvm-img create -f qcow2 qvd.img 8G

Now start the image with the lubuntu iso as your cdrom device to get the install underway and with a mere 2048MB RAM:

$ kvm -hda qvd.img -cdrom lubuntu-20.04-alternate-amd64.iso -m 2048

Obviously if your iso is in a different folder to this image, you will need to change your path accordingly. This will bring up the Lubuntu installer.

image

Select your language and in the next screen select Install Lubuntu.

image

Most of the install is pretty self explanatory, so we won’t cover it in too much depth. Work through the steps until you reach disk partitioning. As a rule we don’t want or need a swap partition within disk images in QVD, so let’s select the Manual option. Now scroll down to sda in the next screen and hit enter.

image

Yes to Create New Empty Partition Table On This Device? You’ll now be back in the main partition screen with a new, empty, partition table. Select this empty partition.

image

Next opt to create a new partition.

image

Agree to the partition size (it should be the full size of the disk).

image

Select Primary partition and you will be in the partition disks page with a bunch of sensible defaults. These look fine, so choose Done Setting Up The Partition.

image

Back in the main screen, select Finish and ignore the warning about lack of swap and writing changes to disk. Thus will begin the installing of the core packages of the OS. This will take a few minutes. Once that is finished you will get a question about proxy setup which you will need to answer (or just Continue) and this will be followed by apt setup and software install. At the end of the install, you will need to install GRUB to the MBR.

image

The install will prompt you for the details of an indiviudal user for your system. This user will be your administrative user for KVM and indeed inside the VDI as well as being the account you use to create LXC images if that is your aim.

Finally, set up the time zone to complete the installation.

image

Select Continue to boot into the new OS. and log in using the user credentials that you set during the install. At this point, the install process diverges depending on whether you want to create a KVM image, or an LXC one. If the former, continue on to the next section, for the latter, skip to the Create an LXC Disk Image section.

2.2. Create a KVM Disk Image

As stated previously, the KVM install we are working in is going to be the basis of the image that you create. That is to say, everything that is installed and customized inside this VM will be a part of the desktop environment you create for your users. The user you have created will not be a desktop user, rather the administrative user that you can use to maintain and install software on the image to make available for your users.

2.2.1. Install the QVD Virtual Machine Agent

The QVD Virtual Machine Agent (VMA) is responsible for accepting connections from the client via a QVD Server Node. It facilitates access to the desktop environment running within the virtual machine, including the ability to configure printer access and to configure the virtual machine to stream audio to the client.

  • Verify that the required ports (443 and 8443) are open

    root@qvdnode:~# firewall-cmd --list-all
    • If they are not listening, perform the following configuration:

      root@qvdnode:~# firewall-cmd --permanent --add-service https
      root@qvdnode:~# firewall-cmd --permanent --add-port 8443/tcp
      root@qvdnode:~# systemctl restart firewalld
      root@qvdnode:~# firewall-cmd --list-all
  • Add the public key of the QVD parcels to your trusted keys (like root):

    root@qvdnode:~# wget -qO - https://www.theqvd.com/packages/key/public.key | sudo apt-key add -
  • ANow, add the repository and get updates:

    root@qvdnode:~# echo "deb http://theqvd.com/packages/ubuntu-bionic QVD-4.2.0 main" > \
                     /etc/apt/sources.list.d/qvd.list
    root@qvdnode:~# apt-get update
    • For commercial packages:

      root@qvdnode:~#  echo "deb http://$USUARIO:$PASSWORD@theqvd.com/packages/ubuntu-bionic QVD-4.2.0 main" > \
                        /etc/apt/sources.list.d/qvd.list
      root@qvdnode:~#  apt-get update
      Note $USER and $PASSWORD are the credentials received when the suscription is purchased.

Finally, install the VMA:

# apt-get install perl-qvd-vma

It is essential that the Virtual Machine Agent starts on boot or the desktop will not be accessible. To do that, we enable the service.

# systemctl enable qvd-vma

The VMA is controlled through the file /etc/qvd/vma.conf. This file is not created on install, so let’s create the directory, and copy the sample VMA configuration file into place.

# mkdir /etc/qvd
# cp -v /usr/lib/qvd/config/sample-vma.conf /etc/qvd/vma.conf

If you take a look at the vma.conf file it has a couple of sensible presets:

vma.audio.enable = 1
vma.printing.enable = 1

Other settings are detailed in the QVD Administration Manual. One additional configuration option is needed to get the X session running under Lubuntu, although it should be noted that this requirement isn’t necessary with a stock Ubuntu install:

command.x-session: /usr/bin/startlubuntu

Assuming you want audio and printing, leave those as they are and start the VMA:

$ sudo service qvd-vma start
Important

At the time of writing, startlubuntu does not honour the /etc/default/locale settings, so if your locale needs to be changed from the default, create a wrapper script, for example in /usr/local/bin/startlubuntu. In there, we source the /etc/default/locale and export the variables, only then invoking startlubuntu:

#!/bin/bash
[ -r /etc/default/locale ] && . /etc/default/locale
export LANG LANGUAGE LC_MESSAGES LC_ALL
/usr/bin/startlubuntu

2.2.2. Install and Configure Secure Shell and Serial Access

To administer the image once it’s been installed, let’s also install the openssh server:

$ sudo apt-get install openssh-server

When the image has been deployed in QVD, this can be accessed using the QVD admin tool for administration / troubleshooting:

$ qa vm ssh -f id=<vm_id> -- -l <user>

If you wish to have serial access to your VM, that too is readily set up. Within the DI, run this command:

# systemctl enable serial-getty@ttyS0.service

2.2.3. Customize and Brand the Desktop

From here, it’s up to you. Install system updates and the packages that you would like available for your users. This may involve the packages available for your distro, it may be the custom software that your company uses. Ready the desktop for use as you would like your users to experience it, and once you are happy with your disk image, power it down and it’s ready for use with QVD.

2.2.4. Tar and Zip the Image

QVD accepts compressed tar archives and the image should compress substantially to make is quicker to transfer to other hosts, so you should tar and zip the KVM image as follows:

$ tar czf qvd.img.tar.gz qvd.img

And unzip it on the destination server when you are ready to move it to staging:

$ cd /var/lib/qvd/staging && sudo tar zxf /path/to/qvd.img.tar.gz

Once you’ve moved the image into staging, it will be available in the QVD Web Administration Tool. You can create a new set of runtime settings for the image (OSF) and add the disk image  to the database. Finally, you will need to create a new Virtual Machine for each user that will use this disk image and it’s ready to be used. And that concludes our little introduction to creating KVM images for use with QVD. It’s pretty simple really, and the beauty of the KVM image is that any time you want to tweak an image, you can open it up in kvm and administer it as though it were a real desktop, shut down, copy the image to staging and deploy.

2.3. Create an LXC Disk Image

LXC is a fairly recent but rapidly stabilising technology that allows for running multiple isolated Linux systems (containers) on a single host. Because these containers utilise the same kernel as the host, it’s an extremely efficient method of virtualisation that allows for a greater VM density than KVM. That said, it requires a that the host and the guests are compatible that with the same kernel, and for this reason it is strongly recommended that you use the same distro and version for your clients as for your node. Hence the requirement that we use Lubuntu 20.04 for this document.

As stated earlier, the KVM system you have just installed will not itself be the basis for the QVD image, but will be used to install LXC and create a suitable environment for your desktop users within the KVM image itself.

2.3.1. Install the LXC User Space Tools

Once logged into your kvm build environment, su to root, and install the LXC user space tools:

# apt-get install lxc lxc-templates

2.3.2. Create a Basic LXC Configuration

That done, create a file called lxc.conf somewhere convenient, and populate it with the following network settings:

lxc.net.0.type=veth
lxc.net.0.link=lxcbr0
lxc.net.0.flags=up

The first line will tell lxc that we wish to use a virtual ethernet device inside the container. The second line gives lxc the name of the network bridge that we want the container to utilise to connect to the network. Finally, we set the network as up.

2.3.3. Create and Run the LXC Container

Now let’s create a new Linux container:

# lxc-create -n qvd-vm -t ubuntu -f lxc.conf

The first time you do this it will take a little extra time compared to subsequent builds as it will pull down the core packages from the Ubuntu servers to install inside the container. The next time you create a container using the same template (in this case ubuntu), these packages will be reused so it will be quite a bit quicker.

Note As there is no explicit Lubuntu LXC template we use the Ubuntu one which contains the same basic core packages, and add the LXDE desktop at a later stage.

Once this is done, start the container:

# lxc-start -Fn qvd-vm

This will both start the contained and put you straight into the login prompt. Log in using ubuntu as both username and password.

2.3.4. Install the QVD Virtual Machine Agent

The QVD Virtual Machine Agent (VMA) is responsible for accepting connections from the client via a QVD Server Node. It facilitates access to the desktop environment running within the virtual machine, including the ability to configure printer access and to configure the virtual machine to stream audio to the client.

  • Verify that the required ports (443 and 8443) are open

    root@qvdnode:~# firewall-cmd --list-all
    • If they are not listening, perform the following configuration:

      root@qvdnode:~# firewall-cmd --permanent --add-service https
      root@qvdnode:~# firewall-cmd --permanent --add-port 8443/tcp
      root@qvdnode:~# systemctl restart firewalld
      root@qvdnode:~# firewall-cmd --list-all
  • Add the public key of the QVD parcels to your trusted keys (like root):

    root@qvdnode:~# wget -qO - https://www.theqvd.com/packages/key/public.key | sudo apt-key add -
  • ANow, add the repository and get updates:

    root@qvdnode:~# echo "deb http://theqvd.com/packages/ubuntu-bionic QVD-4.2.0 main" > \
                     /etc/apt/sources.list.d/qvd.list
    root@qvdnode:~# apt-get update
    • For commercial packages:

      root@qvdnode:~#  echo "deb http://$USUARIO:$PASSWORD@theqvd.com/packages/ubuntu-bionic QVD-4.2.0 main" > \
                        /etc/apt/sources.list.d/qvd.list
      root@qvdnode:~#  apt-get update
      Note $USER and $PASSWORD are the credentials received when the suscription is purchased.

Finally, install the VMA:

# apt-get install perl-qvd-vma

It is essential that the Virtual Machine Agent starts on boot or the desktop will not be accessible. To do that, we enable the service.

# systemctl enable qvd-vma

The VMA is controlled through the file /etc/qvd/vma.conf. This file is not created on install, so let’s create the directory, and copy the sample VMA configuration file into place.

# mkdir /etc/qvd
# cp -v /usr/lib/qvd/config/sample-vma.conf /etc/qvd/vma.conf

If you take a look at the vma.conf file it has a couple of sensible presets:

vma.audio.enable = 1
vma.printing.enable = 1

Other settings are detailed in the QVD Administration Manual. One additional configuration option is needed to get the X session running under Lubuntu, although it should be noted that this requirement isn’t necessary with a stock Ubuntu install:

command.x-session: /usr/bin/startlubuntu

Assuming you want audio and printing, leave those as they are and start the VMA:

$ sudo service qvd-vma start
Important

At the time of writing, startlubuntu does not honour the /etc/default/locale settings, so if your locale needs to be changed from the default, create a wrapper script, for example in /usr/local/bin/startlubuntu. In there, we source the /etc/default/locale and export the variables, only then invoking startlubuntu:

#!/bin/bash
[ -r /etc/default/locale ] && . /etc/default/locale
export LANG LANGUAGE LC_MESSAGES LC_ALL
/usr/bin/startlubuntu

2.3.5. Install and Configure Secure Shell and Serial Access

To administer the image once it’s been installed, let’s also install the openssh server:

$ sudo apt-get install openssh-server

When the image has been deployed in QVD, this can be accessed using the QVD admin tool for administration / troubleshooting:

$ qa vm ssh -f id=<vm_id> -- -l <user>

If you wish to have serial access to your VM, that too is readily set up. Within the DI, run this command:

# systemctl enable serial-getty@ttyS0.service

2.3.6. Customize and Brand the Desktop

Although LXC has copied the rudimentary system over to the container, the template does not allow for a desktop environment, so we will need to install that.

# apt-get install lubuntu-desktop

This would also be a good time to install any additional desktop software that your users might need, so go ahead and install any office software, graphics software and so on using apt as above.

You also need to create a group for QVD users. When QVD creates a new account for an user, they will be added to this group. This will be used to provide USBIP functionality, so make sure not to skip this step if you intend to connect USB devices.

The default name for this group is qvduser. The name can be changed via the vma.user.default.groups and createdevice.acl.group settings. Both values must be modified and agree with each other.

# groupadd qvduser

Before we log out, create a new administrative user for the disk image, and delete the default user and home directory:

# adduser qvd
# usermod -aG sudo qvd

Log out and back in with the new user and (as root) remove the default user and home directory:

# deluser ubuntu
# rm -rf /home/ubuntu
Note

At this point we could delete the user with the --remove-home switch but this requires the perl-modules package which brings, along with dependencies, another 32MB to the install. It’s up to to the use case and space constraints of course.

Branding and customization of the desktop environment is beyond the scope of this guide, but there is a list of resources at the end to assist with this. Once you have desktop that you want for your users, you can close down the container in preparation for zipping up the image.

# poweroff

2.3.7. Tar and Zip the Image

Back in your host machine tar and zip (as root) the root file system of the container for deployment in QVD:

# tar czf ubuntu-20.04.tar.gz -C /var/lib/lxc/qvd-vm/rootfs .

2.4. Create an LXC Disk Image using Docker

LXC is a fairly recent but rapidly stabilising technology that allows for running multiple isolated Linux systems (containers) on a single host. Around LXC some new technologies have appeared such as Docker that permit an easy creation of new containers based on templates of existing containers.

QVD has created some base templates that you can use to create new LXC images. Currently two templates are available:

  • theqvd/qvdimageubuntu:minimal. This is 155 MB image which only has an xterm and gives you the full power to install whatever you need

  • theqvd/qvdimageubuntu:basicdesktop. This a 800MB image with XFCE environment + some basic office application such as LibreOffice, Firefox, Thunderbird and Evince

The examples assume that you are using Ubuntu 14.04

2.4.1. Software

You need a base Ubuntu 20.04 system with docker installed

$ sudo apt-get install docker.io

2.4.2. Create a custom image from the basic desktop

Let’s add the gimp image manipulation tool to the basic desktop image. For that create in a new directory a file called Dockerfile with the following content:

FROM theqvd/qvdimageubuntu:basicdesktop
MAINTAINER Me <me@domain.com>

ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && apt-get install -y gimp

# Cleanup
RUN echo "" > /etc/udev/rules.d/70-persistent-net.rules
RUN apt-get autoremove -y
RUN apt-get clean

Then run from the terminal the following commands:

$ cd <directory where the Dockerfile is>
$ sudo docker build -t myimage .
$ vmid=$(sudo docker run -d -t -i myimage /bin/bash)
$ sudo docker export $vmid | gzip -c > qvd.img.tar.gz
$ sudo docker kill $vmid

Once you got the qvd.img.tar.gz file, please follow the instructions above to create the di in QVD either via command line (qa di add) or via the web administration tool (WAT)

Please see http://www.docker.com for more information on other syntax options for Docker.

2.4.3. Create a custom image from the minimal image

In this case we create a minimal desktop based on the minimal image where we want to create a lubuntu desktop.

Create a new directory and this directory we are going to create two files:

  • Dockerfile

  • vma.conf

This is the content of the Dockerfile:

FROM theqvd/qvdimageubuntu:minimal
MAINTAINER Me <me@domain.com>

LABEL version="1.0"
LABEL description="This is a basic desktop Ubuntu VM image installation for QVD. It  includes LibreOffice, Thunderbird, Firefox and Evince"

ENV DEBIAN_FRONTEND noninteractive
# packages
RUN echo "deb http://archive.canonical.com/ubuntu bionic partner" > /etc/apt/sources.list.d/partners.list
RUN apt-get update && apt-get install -y \
  lubuntu-desktop \
  adobe-flashplugin \
  cups \
  evince \
  firefox \
  libreoffice \
  icedtea-8-plugin \
  thunderbird
# Config
COPY vma.conf /etc/qvd/vma.conf

# Cleanup
RUN echo "" > /etc/udev/rules.d/70-persistent-net.rules
RUN apt-get autoremove -y
RUN apt-get clean

This is the content of the vma.conf file:

command.x-session: /usr/bin/startlubuntu
vma.audio.enable: 1
vma.printing.enable: 1

Then create the tar.gz file by running the following commands:

$ cd <directory where the Dockerfile is>
$ sudo docker build -t myimage .
$ vmid=$(sudo docker run -d -t -i myimage /bin/bash)
$ sudo docker export $vmid | gzip -c > qvd.img.tar.gz
$ sudo docker kill $vmid

Once you got the qvd.img.tar.gz file, please follow the instructions above to create the di in QVD either via command line (qa di add) or via the web administration tool (WAT)

Please see http://www.docker.com for more information on other syntax options for Docker.

3. Appendix A: Appendix

3.1. Logging Remotely

Logging remotely to a daemon supporting the syslog protocol can be desirable for a couple of reasons. Firstly, it keeps the logs for all the virtual machines that have been configured thus in one place which makes accessing the logs easier and more logical. Secondly, in a situation where the administrator may not be able to access a virtual machine’s log for some reason, for example if it is not starting up, logging remotely might help in identifying the problem.

To set up remote logging, you will need a configured remote logging server, and to make some changes within your disk image, both to QVD’s vma.conf file, and to the syslog settings to send any syslog messages on to the remote logging server.

To demonstrate we will use systemd-journal-remote. Journald has become the default logging utility for many of the major Linux distributions over recent years, including Ubuntu, SUSE, and Redhat, and is reliable and easy to set up. Because QVD uses Log4perl, it should be syslog server agnostic, so you should be able to use these instructions with syslog-ng amongst other alternatives if needs be.

Should systemd-journal-remote not be installed inside your VM, install it as follows:

# apt-get install systemd-journal-remote

That done, we will need to configure journald to log to a remote server.

First, edit /etc/systemd/journal-upload.conf and enter the following configuration:

[Upload]
URL=http://10.0.0.1:19532
# ServerKeyFile=/etc/ssl/private/journal-upload.pem
# ServerCertificateFile=/etc/ssl/certs/journal-upload.pem
# TrustedCertificateFile=/etc/ssl/ca/trusted.pem

The URL must be configured to the address of the server that will receive the logs. Both HTTP and HTTPS protocols are accepted, and SSL certificates can be used to secure the communication.

Make sure journal-upload is started on boot:

sudo systemctl enable --now systemd-journal-upload.service

To configure a server for receiving the logs, install the systemd-journal-remote package on the logging server:

# apt-get install systemd-journal-remote

Enable the server:

# systemctl enable --now systemd-journal-remote.socket

The default port is 19532. If you are satisfied with this default, nothing else needs to be done. You may need to open port 19532 in your firewall.

Finally, edit the file /etc/qvd/vma.conf on the virtual machine and enter the following to instruct QVD to log to syslog:

log4perl.appender.SYSLOG = Log::Dispatch::Syslog
log4perl.appender.SYSLOG.layout = Log::Log4perl::Layout::PatternLayout
log4perl.appender.SYSLOG.layout.ConversionPattern = %d %P %F %L %c - %m%n
log4perl.rootLogger = DEBUG, SYSLOG
log.level = DEBUG

Of course, having set journald itself to log remotely, this log data will get passed by journald to the remote server you have set up. To test this, simply use the logger command inside your image and the output should be in the logging server’s logs.

3.2. Software

3.2.1. Installing additional software

Any additional software installed inside your KVM image or within your LXC container prior to zipping and deployment will be available to your desktop users. For most software this can be done using your package manager.

To install LXDE after the initial install, invoke the apt-get command:

# apt-get install lubuntu-desktop

Similarly, office packages and other tools you would like made available to all your users by default can be install through apt:

# apt-get install gimp libreoffice thunderbird xul-ext-lightning icedtea-8-plugin

3.2.2. Application Optimization

Certain applications optimized for a remote connection. For example, preventing the caret from blinking in Firefox will deliver a smoother experience:

# echo 'pref("ui.caretBlinkTime", 0);' >>  /etc/firefox/syspref.js

3.2.3. Remove Unneeded Services and Disable udev

It is advisable to remove any unneeded services that may impact on performance within your disk image.

To remove and avahi:

# apt-get --purge remove avahi-daemon

Remove uneeded programs to keep your disk image smaller:

# apt-get --purge remove xscreensaver

Clean both repository metadata and package caches:

# apt-get clean

3.2.4. Optionally Disable udev

udev is a necessary component of the USBIP functionality

If you intend to share USB devices with your containers, do not follow this step.

If you are absolutely sure you won’t need it, then under LXC, disabling udev has been shown to increase performance, particularly with regards to larger installs.

Disable udev as follows:

# sh -c "echo 'manual' > /etc/init/udev.override"

Furthermore, prevent any network conflicts by emptying the /etc/udev/rules.d/70-persistent-net.rules file in your container which can delay boot times and prevent the network from functioning:

$ echo "" > /etc/udev/rules.d/70-persistent-net.rules