LXC (Linux Containers) is an OS-level Virtualization method, used to run separated linux containers on the same machine without hardware emulation layer between the containers and the OS.

LXC uses some kernel features to create an isolated containers much like the ordinary virtual machines, the main kernel features that lxc relies on are: cgroups and namespaces. LXC also called lightweight virtualization that’s because LXC creates an isolated environment  on the same kernel as the host which means creating  a container can be made in a matter of seconds.

In this post we will create lxc container on Ubuntu 14.04 host, we will explore how to  use cgroups to limit the resources to this container.

Creating LXC container

Installing lxc using apt:

$sudo apt-get install lxc
[email protected]:~$ sudo lxc-create -n container1 -t ubuntu

So this command will create an ubuntu container named container1 and place its rootfs in /var/lib/lxc/container1/rootfs/ .

Creating lxc container with lxc-create require at least the name of the container using (–name|-n) and the template using -t option, more on templates later.

rootfs is the / directory which is mapped to the (/var/lib/lxc/container-name/rootfs/) on the host.

$sudo tree -L 1 /var/lib/lxc/container1/rootfs/
├── bin
├── boot
├── dev
├── etc
├── home
├── lib
├── lib64
├── media
├── mnt
├── opt
......

The default backing store for lxc is simple directory backing store, other backing stores that  available are btrfs, zfs, overlayfs, and lvm, using -B option will specify different backing store systems while creating the container, or using “none” to skip creating rootfs at all.

After creating the Ubuntu container, a message appear with the username and the password of the default created user.

lxc-info or lxc-ls with –fancy option will show the status of container1:

[email protected]:~$sudo lxc-info --name container1
Name: container1
State: STOPPED
[email protected]:~$sudo lxc-start --name container1 --daemon
[email protected]:~$sudo lxc-info --name container1
Name:           container1
State:          RUNNING
PID:            24240
IP:             10.0.3.87
CPU use:        1.09 seconds
BlkIO use:      11.09 MiB
Memory use:     19.17 MiB
KMem use:       0 bytes
Link:           veth8E8JOX
 TX bytes:      1.86 KiB
 RX bytes:      2.08 KiB
 Total bytes:   3.94 KiB

using ssh, lxc-attach, or lxc-console to connect to the container.

[email protected]:~$ssh [email protected]
[email protected]:~$

Control Groups

Cgroups can limit and account the resources for set of processes (process groups). each cgroup has subsystems (or controllers) , each subsystem is controlling a resource, the available controllers are memory, cpu, cpuset, and blkio.

By default each container is assigned to a control group, changes to the cgroups can be made temporary using lxc-cgroups or permanently by editing the configuration file for the container located in /var/lib/lxc/container-name/config.

Example

Specify the hard limit of memory usage to the container to 256M:

[email protected]:~$sudo lxc-cgroup --name  container1\
memory.limit_in_bytes 268435456

or permanently:

lxc.cgroup.memory.limit_in_bytes=268435456

You should shutdown the container and start it again , in order for the changes to take effect.

Networking in LXC

Networking in containers is done using net namespace which ensures that each container will have its own loopback (lo) interface plus a virtual interface named typically eth0 which bridged (using bridge net interface) to the other end  interface on the original host.

[email protected]:~$sudo ifconfig
......
lxcbr0    Link encap:Ethernet  HWaddr fe:25:61:f1:d1:fd  
          inet addr:10.0.3.1  Bcast:10.0.3.255  Mask:255.255.255.0
......
veth8E8JOX Link encap:Ethernet  HWaddr fe:69:d2:e9:54:ae  
          inet6 addr: fe80::fc69:d2ff:fee9:54ae/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
......

Templates

Template files  are  scripts located in /usr/share/lxc/templates/lxc-* and used to configure the rootfs (the root directory) and other options to the container.

$sudo ls /usr/share/lxc/templates/
lxc-alpine lxc-centos lxc-fedora lxc-oracle lxc-ubuntu-cloud lxc-altlinux lxc-cirros lxc-gentoo lxc-plamo lxc-archlinux lxc-debian lxc-openmandriva lxc-sshd lxc-busybox lxc-download lxc-opensuse lxc-ubuntu

By some shell script skills you can simply create or edit the existing templates. For example by adding this simple  code to the existing Ubuntu template will edit the template to install and start nginx.

install_nginx()
{
 local rootfs="$1"
 if [ -z $update ]
 then
 chroot $rootfs apt-get update
 update=true
 fi
 chroot $rootfs apt-get install --force-yes -y --no-install-recommends nginx
}

and then calling the function with:

install_nginx $rootfs
[email protected]:~$ sudo lxc-create -n nginxcont -t ubuntu-nginx
[email protected]:~$ sudo service nginx status
 * nginx is running

References: