Getting started with Linux Containers

This is a very small article I wrote a couple years ago. In order to centralise all my personal publications I’m moving it here for Medium.

A user story

As a developer, choosing a right development environment can turn into a boring task. Considering multiple projects for multiple clients, it increases the need of having separated virtual hosts. Our first thought is to install a virtual machine software and put inside in all we need. This can turn into a bad choice because those virtual machine softwares emulates not only software (Operating system…) as long hardware. So with VirtualBox, VMWare or another one, you reserve a portion of your computer’s specs to work. I’m not saying that is totally bad, but if we had a lightweight way to do the same?

Are you running Linux?

If you are running Linux you can make use of Linux Containers. Let’s check: A container is your virtual host (nothing new here…) but running all over your physical machine hardware. This way you can create a container for each project you have, or even a virtual server structure. I can tell you too, that Docker is an “extension” from Linux Containers. So, if do you need to develop web applications and do you need to virtualise a webserver in a simple way, Linux Containers are your great way to do it!

Let’s do it then

For this presentation proposes I’ll use Linux Ubuntu so…

$ sudo apt-get install lxc

.. and from now on, you have all Linux Containers commands available and container templates as well. So what’s next?

Creating containers

A container can be created by 2 ways: privileged or unprivileged user. This means that as root you can create and use containers with all features provided, but as non-root there are limitations around device nodes, file system mounting and others. To get you started, I’ll run it as root, safer on localhosts for development. Let’s create a container then:

$ sudo lxc-create --template download --name myContainer

After you should see the fully list of Linux templates available (Debian, Fedora, OpenSuse,…) and just type your choices…

$ sudo lxc-create --template download --name myContainer
Setting up the GPG keyring
Downloading the image index

---
DIST RELEASE ARCH VARIANT BUILD
---
alpine 3.0 amd64 default 20160630_17:50
alpine 3.0 i386 default 20160630_17:50
alpine 3.1 amd64 default 20160723_17:50
...
ubuntu yakkety arm64 default 20160723_06:25
ubuntu yakkety armhf default 20160722_20:29
ubuntu yakkety i386 default 20160723_06:25
ubuntu yakkety powerpc default 20160722_20:29
ubuntu yakkety ppc64el default 20160723_06:25
ubuntu yakkety s390x default 20160723_06:25
---

Distribution: ubuntu #here you have to choose one of the list
Release: yakkety #here too
Architecture: amd64 # and don't forget the arch!

With all of this fields selected the O.S. image will be downloaded and installed.

...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=yakkety, 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.

Some usefull commands for now

There are from now some commands you need to know to work better.

$ sudo lxc-ls --fancy
NAME STATE AUTOSTART GROUPS IPV4 IPV6
myContainer STOPPED 0 - - -
$ sudo lxc-start --name myContainer
$ sudo lxc-info -n myContainer
Name: myContainer
State: RUNNING
PID: 15580
IP: 10.0.3.61
CPU use: 0.74 seconds
BlkIO use: 280.00 KiB
Memory use: 13.27 MiB
KMem use: 0 bytes
Link: vethEF15JM
TX bytes: 1.23 KiB
RX bytes: 3.42 KiB
Total bytes: 4.65 KiB
$ sudo lxc-stop --name myContainer
$ sudo lxc-destroy --name myContainer

What’s next? Work with your container…

Your container is now created and running. What’s next? Work with it! First we have to connect with the container like a remote host.

$ sudo lxc-attach --name myContainer
root@myContainer:/#

At this point you are inside the machine, do what you need. Since to installing Nginx/Apache, PHP, Redis… whatever…

root@myContainer:/# apt-get install nginx
...

At this point your machine is already configured and running, but there are more you can do.

File system sharing

Since your container is an emulation of operating system, you keep having to pull all project files to your virtual machine. For those developers that likes to have control about the files, it’s possible to share a folder between your host and the container. How to do it? This task is similar to any others you can do with this tool.

$ mkdir /media/my-container-share && chmod 777 /media/my-container-share
root@myContainer: mkdir /share

There are a config file for each container you have.

$ nano /var/lib/lxc/myContainer/config

Since network configurations to mounting points, all is configured in this config file. To bind this folder with container just add:

#/var/lib/lxc/myContainer/config
lxc.mount.entry = /media/my-container-share share none bind 0.0

Conclusion

It took around 30 minutes to get ready to develop with my container, since LXC install and configure to image download, all clean and easy. This way you can work with live server configurations, prepare server infrastructure and think about test it before getting it real. If does not convince you, consider the scenario of testing your application, leaving PHP5 and welcome PHP7, fully upgrade composer dependencies… Once more, you are getting the best way of using your host resources. You could use Vagrant, Docker… But in fact LXC is so simple that it could not justify thaving a real virtual machine to virtualise your web projects.

https://linuxcontainers.org/

Software Engineering Manager and Software Engineer | Server Side Trainer | Human stuff as a hobby.