Intro

Containers are insulated areas inside a system, which have their own namespace for filesystem, network, PID, IPC, CPU and memory allocation and which can be created using the Control Group and Namespace features included in the Linux kernel.

Docker vs. LXC

The idea behind Docker is to reduce a container as much as possible to a single process and then manage that through Docker. This adds significant complexity. The main problem with this approach is you can’t wish the OS away and the vast majority of apps and tools expect a multi process environment and support for things like cron, logging, ssh, daemons and with Docker since you have none of this you have do everything via Docker from basic app configuration to deployment, networking, storage and orchestration.

LXC sidesteps that with a normal OS environment and is thus immediately and cleanly compatible all the apps and tools and any management and orchestration layers and be a drop in replacement for VMs.

Beyond that Docker uses layers and disables storage persistence. LXC supports layers with aufs, overlayfs and has wide support for COW cloning and snapshots with btrfs, ZFS, LVM Thin and leaves their use of these to user choice. Separating storage is a simple bind mount to the host or another container for users who choose to do so.

— source: flockport.com

Install lxc

apt-get install lxc

Sudo

To be able to execute lxc commands as root without password, you need to configure sudo.

echo "$USER  ALL=(root) NOPASSWD: /usr/bin/lxc-*" >> /etc/sudoers.d/${USER}

Setup network

NAT

Probably best option when you are using laptop and moving between various networks.

First install bridge-utils and DHCP server (optional)
apt-get install bridge-utils isc-dhcp-server
Configure /etc/network/interfaces
auto br0
iface br0 inet static
   address 172.20.0.1
   netmask 255.255.255.0
   bridge_stp off
   bridge_maxwait 5
   pre-up  /sbin/brctl addbr br0
   post-up /sbin/brctl setfd br0 0
   post-down /sbin/brctl delbr br0
   post-up /sbin/iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
   post-up /sbin/iptables -A FORWARD -i br0 -o wlan0 -j ACCEPT
   post-up /sbin/iptables -A FORWARD -i wlan0 -o br0 -j ACCEPT
   post-down /sbin/iptables -t nat -D POSTROUTING -o wlan0 -j MASQUERADE
   post-down /sbin/iptables -D FORWARD -i br0 -o wlan0 -j ACCEPT
   post-down /sbin/iptables -D FORWARD -i wlan0 -o br0 -j ACCEPT

That was a little bit longer, replace wlan0 by your network primary interface. Address and netmask defines your new network. Choose something that won’t be in collision with real networks that you use.

You also need to enable IP forwarding, ensure you have following line in /etc/sysctl.conf:

net.ipv4.ip_forward=1
And reload sysctl
sysctl -p
Bring up network interface
ifup br0

You also need to setup DHCP server so your containers will get IP address automatically.

Edit /etc/default/isc-dhcp-server and set interfaces to listen on
INTERFACES="br0"
Edit /etc/dhcp/dhcpd.conf and setup your subnet
subnet 172.20.0.0 netmask 255.255.255.0 {
    range 172.20.0.10 172.20.0.100;
    option routers 172.20.0.1;
    option domain-name "lxc.hydra";
    option domain-name-servers 8.8.4.4, 8.8.8.8;
}
Finally start dhcpd
service isc-dhcp-server restart
And last step, edit /etc/lxc/default.conf
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0

Create container

Debian

sudo lxc-create -n my_container -t debian

Ubuntu

To bootstrap Ubuntu container on Debian, you need to install ubuntu keyring first.

apt-get install ubuntu-archive-keyring
sudo lxc-create -n ubuntu_container -t ubuntu

Container management

List containers
sudo lxc-ls -f
Get container informations
sudo lxc-info --name my_container
Start container (add -d parameter to run as daemon)
sudo lxc-start --name my_container
Stop running container
sudo lxc-stop --name my_container
Destroy container
sudo lxc-destroy --name my_container
Enter root shell within container
sudo lxc-attach --name ubuntu
# Or enter console
sudo lxc-console --name ubuntu
Execute command inside container
sudo lxc-attach --name ubuntu -- hostname

Advanced usage

Create container on LVM (without --lvname LV name will be same as container)
lxc-create -n debian -t debian -B lvm --vgname vg0 --lvname lxc_debian