Evgeni's notes about LXC

Sources

General

# grep cgroup /etc/default/grub 
GRUB_CMDLINE_LINUX_DEFAULT="quiet cgroup_enable=memory swapaccount=1"
# apt install lxc
# lxc-create -n lxc1 -t debian
# lxc-start -n lxc1 -d
# lxc-attach -n lxc1

Network

default DHCP bridge

LXC ships with a script to create a NAT'ed bridge with DHCP. If that's what you want:

apt install dnsmasq-base iptables bridge-utils # all in Recommends of lxc
echo USE_LXC_BRIDGE=true > /etc/default/lxc-net
systemctl restart lxc-net

this should give you a lxcbr0 with DHCP from 10.0.3.0/24.

You'll need the following in your container config:

lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = lxcbr0

custom bridge

I have a slightly more manual setup, which is also a bridge that I NAT to the world.

# apt install bridge-utils
# cat <<EOF >>/etc/network/interfaces
auto vmbr0
iface vmbr0 inet static
        address         192.168.233.1
        netmask         255.255.255.0
        pre-up          brctl addbr vmbr0
        post-down       brctl delbr vmbr0
        bridge_fd       0
        bridge_maxwait  0
EOF
# ifup vmbr0
# do something to have NAT ;-)

Remove lxc.network.type = emtpy from the container config, add the following:

lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = vmbr0
lxc.network.ipv4 = 192.168.233.101/24
lxc.network.ipv4.gateway = auto

lxc.cap.drop = net_admin

This will add an eth0 inside the container, link it to the previously defined vmbr0, assign an IP address and a gateway and drop the NET_ADMIN capability, because it is not needed inside the container.

unprivileged

# apt install uidmap lxcfs libpam-cgfs # TODO: add to Recommends of lxc
# sysctl -w kernel.unprivileged_userns_clone=1

$ cat .config/lxc/default.conf 
lxc.include = /etc/lxc/default.conf
lxc.id_map = u 0 886432 65536
lxc.id_map = g 0 886432 65536
(numbers from grep $USER /etc/sub*id)

$ lxc-create -t download -n user1
$ lxc-start -n user1 -d
$ lxc-attach -n user1

unprivileged Network

Add your user and the bridge you want to connect to to /etc/lxc/lxc-usernet like this:

$USER   veth    vmbr0   10

This will allow $USER to link up to 10 veth devices to the vmbr0 bridge.

Downloading images

lxc-create -t download will download a list of images from https://images.linuxcontainers.org/meta/1.0/ and let the user select one of these. when called as $USER, the list downloaded is https://images.linuxcontainers.org/meta/1.0/index-user.1 which contains only a few images, whereas download as root yields https://images.linuxcontainers.org/meta/1.0/index-system.1. This is the reason why one only gets "wheezy" images for unprivileged containers.

Self create images

Everyone wants to download images from images.l.o, which I prefer not to trust (the images are being buil using git master lxc and do not look reproducible at all). So let's dig into https://jenkins.linuxcontainers.org/view/LXC/view/LXC%20Templates/job/lxc-template-debian/ and try to understand what happens there.

CI Script: https://github.com/lxc/lxc-ci/blob/master/bin/build-image CI Config: https://github.com/lxc/lxc-ci/blob/master/templates/debian.json

First guess:

mkdir -p /build/containers/LXC_NAME/rootfs
touch /build/containers/LXC_NAME/config
env /usr/share/lxc/templates/lxc-debian --path /build/containers/LXC_NAME --rootfs /build/containers/LXC_NAME/rootfs --name LXC_NAME -r wheezy -a amd64
chroot /build/containers/LXC_NAME/rootfs sh -c passwd -dl root
chroot /build/containers/LXC_NAME/rootfs sh -c apt-get remove --purge openssh-server -y
tar -Jcf /build/rootfs.tar.xz -C /build/containers/LXC_NAME/rootfs . --numeric-owner

TODO

Capabilities

this is just a braindump, don't use

lxc.cap.drop = audit_control audit_read audit_write mknod net_admin sys_admin sys_boot