LXC container driver

The libvirt LXC driver manages "Linux Containers". Containers are sets of processes with private namespaces which can (but don't always) look like separate machines, but do not have their own OS. Here are two example configurations. The first is a very light-weight "application container" which does not have its own root image.

Project Links

Cgroups Requirements

The libvirt LXC driver requires that certain cgroups controllers are mounted on the host OS. The minimum required controllers are 'cpuacct', 'memory' and 'devices', while recommended extra controllers are 'cpu', 'freezer' and 'blkio'. The /etc/cgconfig.conf & cgconfig init service used to mount cgroups at host boot time. To manually mount them use:

 # mount -t cgroup cgroup /dev/cgroup -o cpuacct,memory,devices,cpu,freezer,blkio

NB, the blkio controller in some kernels will not allow creation of nested sub-directories which will prevent correct operation of the libvirt LXC driver. On such kernels, it may be necessary to unmount the blkio controller.

Environment setup for the container init

When the container "init" process is started, it will be given several useful environment variables.

LIBVIRT_LXC_NAME
The name assigned to the container by libvirt
LIBVIRT_LXC_UUID
The UUID assigned to the container by libvirt
LIBVIRT_LXC_CMDLINE
The unparsed command line arguments specified in the container configuration

Example config version 1

<domain type='lxc'>
  <name>vm1</name>
  <memory>500000</memory>
  <os>
    <type>exe</type>
    <init>/bin/sh</init>
  </os>
  <vcpu>1</vcpu>
  <clock offset='utc'/>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <devices>
    <emulator>/usr/libexec/libvirt_lxc</emulator>
    <interface type='network'>
      <source network='default'/>
    </interface>
    <console type='pty' />
  </devices>
</domain>

In the <emulator> element, be sure you specify the correct path to libvirt_lxc, if it does not live in /usr/libexec on your system.

The next example assumes there is a private root filesystem (perhaps hand-crafted using busybox, or installed from media, debootstrap, whatever) under /opt/vm-1-root:

<domain type='lxc'>
  <name>vm1</name>
  <memory>32768</memory>
  <os>
    <type>exe</type>
    <init>/init</init>
  </os>
  <vcpu>1</vcpu>
  <clock offset='utc'/>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <devices>
    <emulator>/usr/libexec/libvirt_lxc</emulator>
    <filesystem type='mount'>
      <source dir='/opt/vm-1-root'/>
      <target dir='/'/>
    </filesystem>
    <interface type='network'>
      <source network='default'/>
    </interface>
    <console type='pty' />
  </devices>
</domain>

In both cases, you can define and start a container using:

virsh --connect lxc:/// define v1.xml
virsh --connect lxc:/// start vm1
virsh --connect lxc:/// console vm1

Now doing 'ps -ef' will only show processes in the container, for instance. You can undefine it using

virsh --connect lxc:/// undefine vm1