Lxc

From Void Linux Wiki
Jump to: navigation, search

LXC is a userspace interface for the Linux kernel containment features. Through a powerful API and simple tools, it lets Linux users easily create and manage system or application containers.

Installation

To install the core tools and container templates, run:

# xbps-install -S lxc

To be able to use the OCI template, which downloads and configures app containers from dockerhub or other registries, one must install some additional packages:

# xbps-install -S jq skopeo umoci

Configuration

You may wish to familiarize yourself with the configuration options, or use the configuration provided here as is. The file /etc/lxc/default.conf stores the global default configuration for system containers. For containers run as unprivileged user, the ~/.config/lxc/default.conf file is used. In addition, each container has its own configuration file.

Networking

To create a bridge for connecting from guest containers to the host, run:

# ip link add dev BRIDGE type bridge
# ip link set dev BRIDGE up
# ip link set dev NIC master BRIDGE

Fill in the bridge name and network device name as necessary.

Add the following configuration for single containers, or in the global configuration to connect all containers to the network created above.

lxc.network.type = veth
lxc.network.link = BRIDGE
lxc.network.flags = up
lxc.network.hwaddr = 00:16:3e:xx:xx:xx

Also consider using lxc-net or brmgr to manage the bridge device and a subnet for the containers.

Unprivileged Containers

To enable unprivileged containers, one must create a uidgid map:

$ echo root:1000000:65536 | sudo tee -a /etc/subuid 
$ echo root:1000000:65536 | sudo tee -a /etc/subgid

This creates a uid and gid map for the root user starting at 1000000 with a size of 65536.

To configure containers to use this mapping, add the following lines to the configuration:

lxc.idmap = u 0 1000000 65536
lxc.idmap = g 0 1000000 65536

This can be in the global or container-specific configuration.

Running containers as an unprivileged user

Unprivileged containers can easily be run by the root user, but to allow unprivileged users to run containers there are some extra configuration steps for networking, user namespaces, and cgroups.

First, a quota must be set for the number of interface devices that can be created by an unprivileged user. To set the quota for the user USER to N interfaces connected to the bridge BRIDGE, add the following line to /etc/lxc/lxc-usernet:

USER veth BRIDGE N

This will limit the number of containers each user can run that have network devices created with the veth type.

Next, a new uidgidmap must be created for the target user.

$ echo USER:2000000:65536 | sudo tee -a /etc/subuid 
$ echo USER:2000000:65536 | sudo tee -a /etc/subgid

Configure the users containers to use this new mapping by adding the following two lines to ~/.config/lxc/default.conf:

lxc.idmap = u 0 2000000 65536
lxc.idmap = g 0 2000000 65536

Finally, ensure that the target user can place the containers within a cgroup owned by the user.

An example on how to configure this using cgmanager is provided below, however there are other methods including manually creating and chown'ing the cgroups as well as using cgrulesengd.

cgmanager

cgmanager is a dbus daemon to manage cgroups. Importantly, it facilitates running containers for unprivileged users.

To use cgmanager, first install the cgmanager package and enable the dbus and cgmanager services:

# xbps-install -S cgmanager
# ln -s /etc/sv/dbus /var/service/dbus
# ln -s /etc/sv/cgmanager /var/service/cgmanager

Next, for each target unprivileged user, run the following commands:

# cgm create all USER
# cgm chown all USER $(id -u USER) $(id -g USER)

You may wish to run the above two commands as a runit service at boot.

Finally, to start an unprivileged container, run:

$ cgm movepid all USER $$
$ lxc-start CONTAINER [...]

You can verify that the cgroups are configured correctly using lxc-checkconfig.

Refer to the cgm manpage for more options.

Manual cgroups configuration

# mkdir /sys/fs/cgroup/{freezer,memory}/USER
# chown -R USER:GROUP /sys/fs/cgroup/{freezer,memory}/USER
$ echo $$ | tee /sys/fs/cgroup/{freezer,memory}/USER/tasks

Refer to the this bug report for additional information.

Usage

You can create a void container by running:

lxc-create -t void -n ct1 -B lvm --vgname=vg1 --lvname=ct1_lv --fssize=20G

where

ct1 => the name of the container that is created
vg1 => the name of an existing volume group
ctl_lv => the name that lxc will create as logical volume name for your container

Then you can start the container with

lxc-start -n ct1

You log-in with

lxc-console -n ct1

login is root/root

You can stop the container with

lxc-stop -n ct1

IMPORTANT: you detach from the container with

CNTL-a q

Misc

Void-linux container on non-Void-linux host

Use the template provided here.

distinction between privileged/unprivileged container

TODO: you may see the following error message when attempting to use an unprivileged container.

lxc-start: tools/lxc_start.c: main: 317 Executing '/sbin/init' with no configuration file may crash the host