[ About | Licence | Contacts ]
Written by Oleksandr Gavenko (AKA gavenkoa), compiled on 2024-04-01 from rev 052223c22317.

LXC

LXC docs

https://linuxcontainers.org/lxc/getting-started/
Upstream "Getting Started".
https://help.ubuntu.com/lts/serverguide/lxc.html
Ubuntu Server Guide » Virtualization » LXC

LXC releases

https://discuss.linuxcontainers.org/tags/release
Announces of LXC & LXD releases.
https://discuss.linuxcontainers.org/t/lxc-3-0-0-has-been-released/1449
LXC 3.0.0 has been released.

Supported templates

https://github.com/lxc/lxc-templates
Old style template scripts for LXC (prefer distrobuilder).
https://github.com/lxc/distrobuilder
System container image builder for LXC and LXD.
https://brauner.github.io/2018/02/27/lxc-removes-legacy-template-build-system.html
Details about replacing template stripts.

Install LXC under Debian

Installation:

$ sudo apt install lxc

Verify that your host/kernel satisfies LXC requirements:

$ sudo lxc-checkconfig

To make network bridge install supplement packages:

$ sudo apt-get install bridge-utils dnsmasq

To bootstrap Debian dostro into container install:

$ sudo apt-get install debootstrap

To bring up network bridge create or edit /etc/default/lxc-net:

USE_LXC_BRIDGE="true"

LXC_ADDR="10.0.0.1"
LXC_NETMASK="255.255.255.0"
LXC_NETWORK="10.0.0.0/24"
LXC_DHCP_RANGE="10.0.0.2,10.0.0.254"
LXC_DHCP_MAX="253"
LXC_DHCP_CONFILE=""
LXC_DOMAIN=""

and start service:

$ sudo service lxc-net start
$ sudo systemctl restart lxc-net.service

Project file layout

Create new container in LXC

Create container from template:

$ sudo lxc-create -t $TMPL -n $NAME -- $EXTRA_ARGS

Note

  • -t defines distro name
  • -n gives name for container for further referencing
  • everything after -- is passed to template script

Template name is based on file name from /usr/share/lxc/templates directory without lxc- prefix.

List available templates with:

$ ls -alh /usr/share/lxc/templates/

Examples of container creation command:

$ sudo lxc-create -t debian -n deb-sid --  -r sid --enable-non-free
$ sudo lxc-create -t debian -n deb-testing --  -r testing
$ sudo lxc-create -t debian -n deb-stable --  -r stable -a amd64

$ sudo lxc-create -t alpine -n alpine-3.7 --  -r 3.7

Examples of destroying container:

$ sudo lxc-destroy --name $NAME

Each template has own options, which can be passed after --. To get help on template specific options run:

$ /usr/share/lxc/templates/lxc-ubuntu -h
$ /usr/share/lxc/templates/lxc-debian -h
$ /usr/share/lxc/templates/lxc-alpine -h
$ /usr/share/lxc/templates/lxc-download -h
...

For Debian in order to use another miror:

$ MIRROR=http://httpredir.debian.org/debian sudo lxc-create -t debian -n debtest -- -r sid

List of prebuild containers:

Creating container by downloading pre-built image:

sudo lxc-create -t download -n alpine-edge -- -d alpine -r edge -a amd64
sudo lxc-create -t download -n debian-sid -- -d debian -r sid -a amd64
sudo lxc-create -t download -n ubuntu-bio -- --dist ubuntu --release bionic --arch amd64

Since LXC v3.0 sh-templates moved to separate project and only 4 are left supported:

$ lxc-create my-busybox -t busybox
$ lxc-create my-x -t download
$ lxc-create c1 -t local -- --metadata /path/to/meta.tar.xz --fstree /path/to/rootfs.tar.xz
$ lxc-create c2 -t oci -- --url docker://alpine

Put veth network configuration into container config /var/lib/lxc/$NAME/config:

lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = lxcbr0
lxc.network.veth.pair = veth-stretch
lxc.network.name = veth-stretch
lxc.network.ipv4 = 192.168.99.12/24
lxc.network.ipv4.gateway = 192.168.99.1

Fix DNS resolution in container:

$ echo nameserver 8.8.8.8 | sudo tee /var/lib/lxc/$NAME/rootfs/etc/resolv.conf

Creating unpriviliged containers

Check if user has assigned ids for namespaces:

$ cat /etc/subuid
vagrant:100000:65536
$ cat /etc/subgid
vagrant:100000:65536

If not assign ranges with:

sudo usermod -v 100000-165536 -w 100000-165536  vagrant

or:

sudo usermod -add-subuids 100000-165536  vagrant
sudo usermod -add-subgids 100000-165536  vagrant

Create local config:

mkdir -p ~/.config/lxc
cat <<EOF >~/.config/lxc/default.conf
lxc.idmap = u 0 100000 65536
lxc.idmap = g 0 100000 65536
lxc.network.type = veth
lxc.network.link = lxcbr0
EOF
echo "$USER veth lxcbr0 2" | sudo tee -a /etc/lxc/lxc-usernet

LXC Container management

List available containers:

$ sudo lxc-ls
$ sudo lxc-ls -f
$ sudo lxc-ls --fancy

Show details about container:

$ sudo lxc-info --name $NAME

Start container:

$ sudo lxc-start -n $NAME

Show boot process output during container start with -F:

$ sudo lxc-start -n $NAME -F
$ sudo lxc-start -n $NAME --foreground

Safely stop container (by default sends SIGPWR signal to container init process and waits 60 sec and then send SIGKILL):

$ sudo lxc-stop -n $NAME

To signal reboot (by default sends SIGINT signal to container init process):

$ sudo lxc-stop -n $NAME -r
$ sudo lxc-stop -n $NAME --reboot

Urgently stop container (kills all processes):

$ sudo lxc-stop -n $NAME -k
$ sudo lxc-stop -n $NAME --kill

Mark container to start on boot in /var/lib/lxc/$NAME/config:

lxc.start.auto = 1

Other autostart params:

lxc.start.delay = 15 # delay in seconds
lxc.start.order = 50 # higher value means starts earlier

Limit memory usage:

lxc.cgroup.memory.limit_in_bytes = 256M

Apply memory limit on fly:

sudo lxc-cgroup -n $NAME memory.limit_in_bytes 100M

Link containers in non standard location to take them in account:

$ ln -s /opt/lxc/$NAME /var/lib/lxc/$NAME

Show container status/into:

$ sudo lxc-info -n $NAME

Print just state:

$ sudo lxc-info -n $NAME -s
$ sudo lxc-info -n $NAME --state

Print just pid:

$ sudo lxc-info -n $NAME -p
$ sudo lxc-info -n $NAME --pid

Print just IP addresses:

$ sudo lxc-info -n $NAME -i
$ sudo lxc-info -n $NAME --ips

Run command in running container:

$ sudo lxc-attach -n $NAME
$ sudo lxc-attach -n $NAME bash
$ sudo lxc-attach -n $NAME -- ls -a
$ sudo lxc-attach -n $NAME -- apk list

Open session in console (attaches container tty process to current terminal, prompt for user/password):

$ sudo lxc-console -n $NAME

Freeze/unfreeze:

$ sudo lxc-freeze -n $NAME
$ sudo lxc-unfreeze -n $NAME

Making snapshot

See lxc-snapshot(1).

List of snapshots:

$ sudo lxc-snapshot --list
$ sudo lxc-snapshot -n $NAME --list

Make a snapshot:

$ sudo lxc-halt -n $NAME
$ sudo lxc-snapshot -n $NAME

Restore from snapshot:

$ sudo lxc-halt -n $NAME
$ sudo lxc-snapshot -n $NAME -r $SNAPNAME