This blog is part of my ongoing series on Docker containers. In this blog, I will take a deviation from Docker and focus on LXC. LXC manages Containers like Docker, there are some differences, I will cover the differences in a later blog. LXC is an Opensource Linux container project from Linuxcontainers.org that provides an user space interface to manage Linux containers.There are other projects from linuxcontainers.org focusing on containers like LXD, LXCFS, CGManager etc. In this blog, I will cover some hands-on stuff I tried with LXC.
My environment:
Ubuntu 14.04 running in Virtuabox in Windows 7.
Hands-on:
To install lxc, I followed the below steps:
sudo apt-get update sudo apt-get install lxc
Following command creates a Ubuntu LXC container.
sudo lxc-create -t ubuntu -n cn-01
The above command will download all filesystems needed for base Ubuntu. Following is the status after the download is complete.
$ sudo lxc-info --name cn-01 Name: cn-01 State: STOPPED
All Container related data including filesystem is stored in /var/lib/lxc/
# ls config fstab rootfs # cd rootfs/ :/var/lib/lxc/cn-01/rootfs# ls bin dev home lib64 mnt proc run srv tmp var boot etc lib media opt root sbin sys usr
Now, lets start the container.
sudo lxc-start --name cn-01
Container details after starting:
$ sudo lxc-info --name cn-01 Name: cn-01 State: RUNNING PID: 17066 IP: 10.0.3.152 CPU use: 1.15 seconds BlkIO use: 128.00 KiB Memory use: 13.32 MiB KMem use: 0 bytes Link: vethKFJL02 TX bytes: 3.25 KiB RX bytes: 6.64 KiB Total bytes: 9.89 KiB
We can login to the container using username and password as “ubuntu”.
We can also attach to a running container as well as ssh into it.
sudo lxc-attach --name cn-01
From a Networking perspective, Containers connect to the Linux bridge using Veth interface on the host.
Default LXC configuration that controls basic networking is present in /etc/lxc/default.conf
$ cat default.conf lxc.network.type = veth lxc.network.link = lxcbr0 lxc.network.flags = up lxc.network.hwaddr = 00:16:3e:xx:xx:xx
Following output shows linux bridge output and ifconfig for Veth interface.
$ sudo brctl show
bridge name bridge id STP enabled interfaces
lxcbr0 8000.fe490d74c6a0 no vethKFJL02
$ ifconfig vethKFJL02
vethKFJL02 Link encap:Ethernet HWaddr fe:49:0d:74:c6:a0
inet6 addr: fe80::fc49:dff:fe74:c6a0/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:34 errors:0 dropped:0 overruns:0 frame:0
TX packets:52 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3332 (3.3 KB) TX bytes:7226 (7.2 KB)
Following is the ifconfig output on the Container cn-01:
$ ifconfig
eth0 Link encap:Ethernet HWaddr 00:16:3e:f5:bc:5d
inet addr:10.0.3.152 Bcast:10.0.3.255 Mask:255.255.255.0
inet6 addr: fe80::216:3eff:fef5:bc5d/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:54 errors:0 dropped:0 overruns:0 frame:0
TX packets:34 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:7420 (7.4 KB) TX bytes:3332 (3.3 KB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
I installed apache in the Ubuntu container and I was able to access the container using browser.
sudo apt-get install apache2
LXC provides options like “lxc-clone” and “lxc-snapshot” to clone and snapshot the container.
1 of the features that Docker provides is to be able to easily move Containers across hosts. With LXC, it seems like there is no straightforward approach. 1 of the approaches suggested in documentation is the following:
- Stop the container.
- Copy the filesystem in “/var/lib/lxc/<containername>” to new host under “/var/lib/lxc”
I tried the above approach to move container “cn-01” to a different host and it worked fine.
LXC also allows creation of User space containers so that sudo permissions are not needed to create and manage containers. First step is to look at UID range for the user.
$ cat /etc/subuid smakam14:100000:65536
Next step would be to create default LXC configuration file matching UID above.
mkdir -p ~/.config/lxc echo "lxc.id_map = u 0 100000 65536" > ~/.config/lxc/default.conf echo "lxc.id_map = g 0 100000 65536" >> ~/.config/lxc/default.conf echo "lxc.network.type = veth" >> ~/.config/lxc/default.conf echo "lxc.network.link = lxcbr0" >> ~/.config/lxc/default.conf echo "smakam14 veth lxcbr0 2" | sudo tee -a /etc/lxc/lxc-usernet
Now, we can create userspace container.
lxc-create -t download -n u1 -- -d ubuntu -r trusty -a amd64
When I tried to start Container using “lxc-start”, I got the following error:
$ lxc-start -n u1 lxc_container: cgmanager.c: lxc_cgmanager_create: 299 call to cgmanager_create_sync failed: invalid request lxc_container: cgmanager.c: lxc_cgmanager_create: 301 Failed to create cpuset:u1 lxc_container: cgmanager.c: cgm_create: 646 Error creating cgroup cpuset:u1 lxc_container: start.c: lxc_spawn: 861 failed creating cgroups lxc_container: start.c: __lxc_start: 1080 failed to spawn 'u1' lxc_container: lxc_start.c: main: 342 The container failed to start. lxc_container: lxc_start.c: main: 346 Additional information can be obtained by setting the --logfile and --logpriority options.
The issue was because of cgroup permission issue and I fixed it using the procedure here.
Following output shows the information about the running unprivileged container.
$ lxc-ls u1 $ lxc-info --name u1 Name: u1 State: RUNNING PID: 18587 IP: 10.0.3.197 CPU use: 0.93 seconds BlkIO use: 148.00 KiB Memory use: 7.63 MiB KMem use: 0 bytes Link: vethOJFTY0 TX bytes: 2.64 KiB RX bytes: 6.28 KiB Total bytes: 8.92 KiB
For unprivileged container, I had to manually set the password from “lxc-attach” before being able to login to the container.
To stop and destroy the container, I did the following:
$ sudo lxc-stop --name cn-01 $ sudo lxc-destroy --name cn-01
1 thought on “LXC Containers”