Installing LXC

At the time of writing this book, there are two long-term support versions of LXC: 1.0 and 2.0. The userspace tools that they provide have some minor differences in command-line flags and deprecations, which I'll be pointing out as we use them.

Installing LXC on Ubuntu with apt

Let's start by installing LXC 1.0 on Ubuntu 14.04.5 (Trusty Tahr):

  1. Install the main LXC package, tooling, and dependencies:
    root@ubuntu:~# lsb_release -dc
    Description: Ubuntu 14.04.5 LTS
    Codename: trusty 
    root@ubuntu:~# apt-get -y install -y lxc bridge-utils debootstrap libcap-dev cgroup-bin libpam-systemdbridge-utils
    root@ubuntu:~#
    
  2. The package version that Trusty Tahr provides at this time is 1.0.8:
    root@ubuntu:~# dpkg --list | grep lxc | awk '{print $2,$3}'
    liblxc1 1.0.8-0ubuntu0.3
    lxc 1.0.8-0ubuntu0.3
    lxc-templates 1.0.8-0ubuntu0.3
    python3-lxc 1.0.8-0ubuntu0.3
    root@ubuntu:~# 
    

To install LXC 2.0, we'll need the Backports repository:

  1. Add the following two lines in the apt sources file:
    root@ubuntu:~# vim /etc/apt/sources.list
    deb http://archive.ubuntu.com/ubuntu trusty-backports main restricted universe multiverse
    deb-src http://archive.ubuntu.com/ubuntu trusty-backports main restricted universe multiverse
    
  2. Resynchronize the package index files from their sources:
    root@ubuntu:~# apt-get update
    
  3. Install the main LXC package, tooling, and dependencies:
    root@ubuntu:~# apt-get -y install -y lxc=2.0.3-0ubuntu1~ubuntu14.04.1 lxc1=2.0.3-0ubuntu1~ubuntu14.04.1 liblxc1=2.0.3-0ubuntu1~ubuntu14.04.1 python3- lxc=2.0.3-0ubuntu1~ubuntu14.04.1 cgroup- lite=1.11~ubuntu14.04.2 lxc-templates=2.0.3-0ubuntu1~ubuntu14.04.1bridge-utils
    root@ubuntu:~#
    
  4. Ensure the package versions are on the 2.x branch, in this case 2.0.3:
    root@ubuntu:~# dpkg --list | grep lxc | awk '{print $2,$3}'
    liblxc1 2.0.3-0ubuntu1~ubuntu14.04.1
    lxc2.0.3-0ubuntu1~ubuntu14.04.1
    lxc-common 2.0.3-0ubuntu1~ubuntu14.04.1
    lxc-templates 2.0.3-0ubuntu1~ubuntu14.04.1
    lxc1 2.0.3-0ubuntu1~ubuntu14.04.1
    lxcfs 2.0.2-0ubuntu1~ubuntu14.04.1
    python3-lxc 2.0.3-0ubuntu1~ubuntu14.04.1
    root@ubuntu:~#
    

Installing LXC on Ubuntu from source

To use the latest version of LXC, you can download the source code from the upstream GitHub repository and compile it:

  1. First, let's install git and clone the repository:
    root@ubuntu:~# apt-get install git
    root@ubuntu:~# cd /usr/src
    root@ubuntu:/usr/src# git clone https://github.com/lxc/lxc.git
    Cloning into 'lxc'...
    remote: Counting objects: 29252, done.
    remote: Compressing objects: 100% (156/156), done.
    remote: Total 29252 (delta 101), reused 0 (delta 0), pack-reused 29096
    Receiving objects: 100% (29252/29252), 11.96 MiB | 12.62 MiB/s, done.
    Resolving deltas: 100% (21389/21389), done.
    root@ubuntu:/usr/src#
    
  2. Next, let's install the build tools and various dependencies:
    root@ubuntu:/usr/src# apt-get install -y dev-utils build-essential aclocal automake pkg-config git bridge-utils libcap-dev libcgmanager-dev cgmanager
    root@ubuntu:/usr/src#
    
  3. Now, generate the configure shell script, which will attempt to guess correct values for different system-dependent variables used during compilation:
    root@ubuntu:/usr/src# cd lxc
    root@ubuntu:/usr/src/lxc#./autogen.sh
    
  4. The configure script provides options that can be enabled or disabled based on what features you would like to be compiled. To learn what options are available and for a short description of each, run the following:
    root@ubuntu:/usr/src/lxc# ./configure -help
    
  5. Its time now to run configure. In this example, I'll enable Linux capabilities and cgmanager, which will manage the cgroups for each container:
    root@ubuntu:/usr/src/lxc# ./configure --enable-capabilities --enable-cgmanager
    ...
    ----------------------------
    Environment:
     - compiler: gcc
     - distribution: ubuntu
     - init script type(s): upstart,systemd
     - rpath: no
     - GnuTLS: no
     - Bash integration: yes
    Security features:
     - Apparmor: no
     - Linux capabilities: yes
     - seccomp: no
     - SELinux: no
     - cgmanager: yes
    Bindings:
     - lua: no
     - python3: no
    Documentation:
     - examples: yes
     - API documentation: no
     - user documentation: no
    Debugging:
     - tests: no
     - mutex debugging: no
    Paths:
    Logs in configpath: no
    root@ubuntu:/usr/src/lxc#
    

    From the preceding abbreviated output we can see what options are going to be available after compilation. Notice that we are not enabling any of the security features for now, such as Apparmor.

  6. Next, compile with make:
    root@ubuntu:/usr/src/lxc# make
    
  7. Finally, install the binaries, libraries, and templates:
    root@ubuntu:/usr/src/lxc# make install
    

    As of this writing, the LXC binaries look for their libraries in a different path than where they were installed. To fix this just copy them to the correct location:

    root@ubuntu:/usr/src/lxc# cp /usr/local/lib/liblxc.so* /usr/lib/x86_64-linux-gnu/
    
  8. To check the version that was compiled and installed, execute the following code:
    root@ubuntu:/usr/src/lxc# lxc-create --version
    2.0.0
    root@ubuntu:/usr/src/lxc# 
    

Installing LXC on CentOS with yum

CentOS 7 currently provides LXC version 1.0.8 in their upstream repositories. The following instructions should work on RHEL 7 and CentOS 7:

  1. Install the main package and distribution templates:
    root@centos:~# cat /etc/redhat-release
    CentOS Linux release 7.2.1511 (Core)
    root@centos:~# yum install -y lxc lxc-templates
    root@centos:~#
    
  2. Check the installed package versions:
    root@centos:~# rpm -qa | grep lxc
    lua-lxc-1.0.8-1.el7.x86_64
    lxc-templates-1.0.8-1.el7.x86_64
    lxc-libs-1.0.8-1.el7.x86_64
    lxc-1.0.8-1.el7.x86_64
    root@centos:~#
    

Installing LXC on CentOS from source

To install the latest version of LXC, we need to download it from GitHub and compile it, similar to what we did on Ubuntu:

  1. Install the build utilities, git, and various dependencies:
    root@centos:# cd /usr/src
    root@centos:/usr/src# yum install -y libcap-devel libcgroup bridge-utils git
    root@centos:/usr/src# yum groupinstall "Development tools"
    root@centos:/usr/src#
    
  2. Next, clone the repository:
    root@centos:/usr/src# git clone https://github.com/lxc/lxc.git
    root@centos:/usr/src# cd lxc/
    root@centos:/usr/src/lxc#
    
  3. Generate the config file:
    root@centos:/usr/src/lxc# ./autogen.sh
    root@centos:/usr/src#
    
  4. Prepare the software for compilation:
    root@centos:/usr/src/lxc# ./configure
    ...
    ----------------------------
    Environment:
     - compiler: gcc
     - distribution: centos
     - init script type(s): sysvinit
     - rpath: no
     - GnuTLS: no
     - Bash integration: yes
    Security features:
     - Apparmor: no
     - Linux capabilities: yes
     - seccomp: no
     - SELinux: no
     - cgmanager: no
    Bindings:
     - lua: no
     - python3: no
    Documentation:
     - examples: yes
     - API documentation: yes
     - user documentation: no
    Debugging:
     - tests: no
     - mutex debugging: no
    Paths:
    Logs in configpath: no
    root@centos:/usr/src/lxc#
    
  5. Compile and install the binaries, libraries, and distribution templates:
     root@centos:/usr/src/lxc# make && make install
    
  6. Copy the libraries to where the binaries are expecting them:
    root@centos:/usr/src/lxc# cp /usr/local/lib/liblxc.so* /usr/lib64/
    
  7. Finally, to check the version that was compiled and installed, execute the following code:
    root@centos:/usr/src/lxc# lxc-create --version
    2.0.0
    root@centos:/usr/src/lxc#
    

    CentOS 7 ships with systemd as its init system. To start the LXC service, run the following:

    root@centos:/usr/src/lxc# systemctl start lxc.service
    root@centos:/usr/src/lxc# systemctl status lxc.service
     * lxc.service - LXC Container Initialization and Autoboot Code
    Loaded: loaded (/usr/lib/systemd/system/lxc.service; disabled; vendor preset: disabled)
    Active: active (exited) since Tue 2016-08-30 20:03:58 UTC; 6min ago
    Process: 10645 ExecStart=/usr/libexec/lxc/lxc-autostart- helper start (code=exited, status=0/SUCCESS)
    Process: 10638 ExecStartPre=/usr/libexec/lxc/lxc-devsetup (code=exited, status=0/SUCCESS)
    Main PID: 10645 (code=exited, status=0/SUCCESS)
    CGroup: /system.slice/lxc.service
    Aug 30 20:03:28 centos systemd[1]: Starting LXC Container Initialization and Autoboot Code...
    Aug 30 20:03:28 centos lxc-devsetup[10638]: Creating /dev/.lxc
    Aug 30 20:03:28 centos lxc-devsetup[10638]: /dev is devtmpfs
    Aug 30 20:03:28 centos lxc-devsetup[10638]: Creating /dev/.lxc/user
    Aug 30 20:03:58 centos lxc-autostart-helper[10645]: Starting LXC autoboot containers: [ OK ]
    Aug 30 20:03:58 nova systemd[1]: Started LXC Container Initialization and Autoboot Code.
    root@centos:/usr/src/lxc#
    

    To ensure LXC was configured correctly during installation, run the following:

    root@centos:/usr/src/lxc# lxc-checkconfig
    Kernel configuration found at /boot/config- 3.10.0-327.28.2.el7.x86_64
    --- Namespaces ---
    Namespaces: enabled
    Utsname namespace: enabled
    Ipc namespace: enabled
    Pid namespace: enabled
    User namespace: enabled
    Network namespace: enabled
    Multiple /dev/pts instances: enabled
    --- Control groups ---
    Cgroup: enabled
    Cgroup clone_children flag: enabled
    Cgroup device: enabled
    Cgroup sched: enabled
    Cgroup cpu account: enabled
    Cgroup memory controller: enabled
    Cgroup cpuset: enabled
    --- Misc ---
    Veth pair device: enabled
    Macvlan: enabled
    Vlan: enabled
    Bridges: enabled
    Advanced netfilter: enabled
    CONFIG_NF_NAT_IPV4: enabled
    CONFIG_NF_NAT_IPV6: enabled
    CONFIG_IP_NF_TARGET_MASQUERADE: enabled
    CONFIG_IP6_NF_TARGET_MASQUERADE: enabled
    CONFIG_NETFILTER_XT_TARGET_CHECKSUM: enabled
    --- Checkpoint/Restore ---
    checkpoint restore: enabled
    CONFIG_FHANDLE: enabled
    CONFIG_EVENTFD: enabled
    CONFIG_EPOLL: enabled
    CONFIG_UNIX_DIAG: enabled
    CONFIG_INET_DIAG: enabled
    CONFIG_PACKET_DIAG: enabled
    CONFIG_NETLINK_DIAG: enabled
    File capabilities: enabled
     Note : Before booting a new kernel, you can check its 
     configuration:
    usage : CONFIG=/path/to/config /usr/bin/lxc-checkconfig
    root@centos:/usr/src/lxc#
    

LXC directory installation layout

The following table shows the directory layout of LXC that is created after package and source installation. The directories vary depending on the distribution and installation method:

We will explore most of the directories while building, starting, and terminating LXC containers.

Tip

You can change the default installation path when building LXC from source by passing arguments to the configuration script such as configure --prefix.