LXC: Getting started with Linux Containers

containers

If you keep up date, you probably know a great revolution is going on in the whole IT industry: containers. While Docker gets much of the attention, it isn’t the only player in the field. This post is entirely dedicated to LXC: Docker’s older brother.

What are containers?

The first thing to understand is the concept of container. Before starting I suggest you not to read if you’re not comfortable with virtualization. That said containers are similar to Virtual Machines but how are they different? The principal difference is that Virtual Machines are completely abstracted, the full stack starting from BIOS/UEFI up to the kernel is abstracted and different for each VM. Containers on the other side take advantage of the existing architecture and virtualize thereafter. Without the need of abstracting the hardware much less resources are used hence containers are more lightweight than VMs. Containers tend also to share as much as possible with each other (posing security problems) whilst VMs tend to lock the resources and share as less as possible.

LXC and Docker

As I was mentioning earlier Docker is the major player in the container world at the moment, but it isn’t the only one. Linux Containers are even older than Docker, and the Docker project itself has used LXC as base for a while (before switching to libcontainer). So we might say LXC is the older brother of Docker. However related they may be, they fundamentally differ in one thing: the scope. Being container technologies, both Docker and Linux Containers are Operating-System-level virtualization, but:

  • Docker specializes in deploying applications.
  • LXC tries to be as close as possible to virtual machines reducing the overhead.

While it is common to have a Docker container run a single application, LXC containers are similar to virtual machines and enable you to achieve higher density by reducing the overhead imposed by full-fledged virtual machines. Linux Containers are able to achieve this by taking advantage of Linux Kernel’s cgroups and namespaces.

LXC Requirements

Before starting let’s sum up the requirements (directly from linuxcontainers.org):

Hard dependencies:

  • One of glibc, musl libc, uclib or bionic as your C library
  • Linux kernel >= 2.6.32

Extra dependencies for lxc-attach:

  • Linux kernel >= 3.8

Extra dependencies for unprivileged containers:

  • cgmanager or another CGroup manager configuring your system for unprivileged CGroups operation
  • A recent version of shadow including newuidmap and newgidmap
  • Linux kernel >= 3.12

Getting started with LXC

The first thing you have to do is install lxc:

For Debian-based distro do:

# apt-get install lxc

For RedHat-based distro do (if you’re using Fedora>21 use dnf instead of yum):

# yum install lxc

After you have done that you’re ready to go: let’s download the first template for your first container. In this example I’m calling the container test and I’m specifying I want to download the template list.

$ sudo lxc-create -n test -t download
Setting up the GPG keyring
Downloading the image index

---
DIST	RELEASE	ARCH	VARIANT	BUILD
---
centos	7	amd64	default	20160524_02:16
debian	jessie	amd64	default	20160523_04:37
debian	jessie	arm64	default	20160517_22:42
debian	jessie	i386	default	20160523_04:37
debian	jessie	powerpc	default	20160523_04:37
fedora	23	amd64	default	20160524_01:27
fedora	23	i386	default	20160524_01:27
gentoo	current	amd64	default	20160524_14:12
gentoo	current	i386	default	20160524_14:12
opensuse	13.2	amd64	default	20160524_00:53
ubuntu	xenial	amd64	default	20160523_04:37
ubuntu	xenial	i386	default	20160523_04:37
# The output is actually truncated
---

Distribution: ubuntu
Release: xenial
Architecture: amd64

Downloading the image index
Downloading the rootfs
Downloading the metadata
The image cache is now ready
Unpacking the rootfs

---
You just created an Ubuntu container (release=xenial, arch=amd64, variant=default)

To enable sshd, run: apt-get install openssh-server

For security reason, container images ship without user accounts
and without a root password.

Use lxc-attach or chroot directly into the rootfs to set a root password
or create user accounts.

This was just to download the template on which the test container will be based. I also selected distributionrelease and architecture interactively. Let’s now run it and verify:

$ sudo lxc-start -n test -d
$ sudo lxc-info -n test
Name:           test
State:          RUNNING
PID:            4598
IP:             10.0.3.147
CPU use:        0.16 seconds
BlkIO use:      4.00 KiB
Memory use:     12.19 MiB
KMem use:       0 bytes
Link:           veth42SDVF
 TX bytes:      1.27 KiB
 RX bytes:      3.16 KiB
 Total bytes:   4.43 KiB

As you can see the container has been started! Let’s now log into it:

$ sudo lxc-attach -n test
root@test:/# cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04 LTS"

We’re now into the container and much like a virtual machine, we can execute commands and do things that are isolated from other containers. Let’s now delete the container:

root@test:/# exit
$ sudo lxc-stop -n test
$ sudo lxc-destroy -n test
Destroyed container test

Conclusions

You’re now aware of LXC, the older brother of Docker and one of the first modern container technologies for Linux. The whole tutorial was based on privileged containers which ran as root and were administered by root. But Linux Containers also supports unprivileged containers that can be run by any user and are more secure. Now that you understand how LXC works you might be interested in learning Docker too.

Image courtesy of mark | marksei
mark

You may also like...

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.