For most modern Linux distributions, the kernel is enabled with cgroups, but you most likely still will need to install the LXC utilities.
If you’re using Red Hat or CentOS, you’ll need to install the EPEL repositories first. For other distributions, such as Ubuntu or Debian, simply type:
$ sudo apt-get install lxc
Now, before you start tinkering with those utilities, you need to configure your environment. And before doing that, you need to verify that your current user has
both a uid and gid entry defined in /etc/subuid and /etc/subgid:
$ cat /etc/subuid petros:100000:65536
$ cat /etc/subgid petros:100000:65536
Create the ~/.config/lxc directory if it doesn’t already exist, and copy the /etc/lxc/
default.conf configuration file to ~/.config/lxc/default.conf. Append the following two lines to the end of the file:
lxc.id_map = u 0 100000 65536 lxc.id_map = g 0 100000 65536
It should look something like this:
$ cat ~/.config/lxc/default.conf lxc.network.type = veth
lxc.network.link = lxcbr0 lxc.network.flags = up
lxc.network.hwaddr = 00:16:3e:xx:xx:xx lxc.id_map = u 0 100000 65536
lxc.id_map = g 0 100000 65536
Append the following to the /etc/lxc/lxc-usernet file (replace the first column with your user name):
petros veth lxcbr0 10
The quickest way for these settings to take effect is either to reboot the node or log the user out and then log back in.
Once logged back in, verify that the veth networking driver is currently loaded:
$ lsmod|grep veth
veth 16384 0
If it isn’t, type:
$ sudo modprobe veth
You now can use the LXC utilities to download, run and manage Linux containers.
Next, download a container image and name it “example-container”. When you type the following command, you’ll see a long list of supported containers under many Linux distributions and versions:
$ sudo lxc-create -t download -n example-container
You’ll be given three prompts to pick the distribution, release and architecture. I chose the following:
Distribution: ubuntu Release: xenial
Architecture: amd64
Once you make a decision and press Enter, the rootfs will be downloaded locally and configured. For security reasons, each container does not ship with an OpenSSH server or user accounts. A default root password also is not provided. In order to change the root password and log in, you must run either an lxc-attach or chroot into the container directory path (after it has been started).
Start the container:
$ sudo lxc-start -n example-container -d
The -d option dæmonizes the container, and it will run in the background. If you want
to observe the boot process, replace the -d with -F, and it will run in the foreground, ending at a login prompt.
You may experience an error similar to the following:
$ sudo lxc-start -n example-container -d
lxc-start: tools/lxc_start.c: main: 366 The container failed to start.
lxc-start: tools/lxc_start.c: main: 368 To get more details, run the container in foreground mode.
lxc-start: tools/lxc_start.c: main: 370 Additional information can be obtained by setting the --logfile and --logpriority options.
If you do, you’ll need to debug it by running the lxc-start service in the foreground:
$ sudo lxc-start -n example-container -F
lxc-start: conf.c: instantiate_veth: 2685 failed to create veth pair (vethQ4NS0B and vethJMHON2): Operation not supported
lxc-start: conf.c: lxc_create_network: 3029 failed to create netdev
lxc-start: start.c: lxc_spawn: 1103 Failed to create the network.
lxc-start: start.c: __lxc_start: 1358 Failed to spawn container "example-container".
lxc-start: tools/lxc_start.c: main: 366 The container failed to start.
lxc-start: tools/lxc_start.c: main: 370 Additional information can be obtained by setting the --logfile and --logpriority options.
From the example above, you can see that the veth module probably isn’t inserted.
After inserting it, it resolved the issue.
Anyway, open up a second terminal window and verify the status of the container:
$ sudo lxc-info -n example-container Name: example-container State: RUNNING
PID: 1356
IP: 10.0.3.28 CPU use: 0.29 seconds BlkIO use: 16.80 MiB Memory use: 29.02 MiB KMem use: 0 bytes Link: vethPRK7YU TX bytes: 1.34 KiB RX bytes: 2.09 KiB Total bytes: 3.43 KiB
Another way to do this is by running the following command to list all installed containers:
$ sudo lxc-ls -f
NAME STATE AUTOSTART GROUPS IPV4 IPV6 examplecontainer RUNNING 0 10.0.3.28
-But there’s a problem; you still can’t log in! Attach directly to the running container, create your users and change all relevant passwords using the passwd command:
$ sudo lxc-attach -n example-container root@example-container:/#
root@example-container:/# useradd petros root@example-container:/# passwd petros Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Once the passwords are changed, you’ll be able to log in directly to the container from a console and without the lxc-attach command:
$ sudo lxc-console -n example-container
If you want to connect to this running container over the network, install the OpenSSH server:
root@example-container:/# apt-get install openssh-server
Grab the container’s local IP address:
root@example-container:/# ip addr show eth0|grep inet inet 10.0.3.25/24 brd 10.0.3.255 scope global eth0 inet6 fe80::216:3eff:fed8:53b4/64 scope link
Then from the host machine and in a new console window, type:
$ ssh 10.0.3.25
Voilà! You now can ssh in to the running container and type your user name and password.
On the host system, and not within the container, it’s interesting to observe which LXC processes are initiated and running after launching a container:
$ ps aux|grep lxc|grep -v grep
root 861 0.0 0.0 234772 1368 ? Ssl 11:01 ↪0:00 /usr/bin/lxcfs /var/lib/lxcfs/
lxc-dns+ 1155 0.0 0.1 52868 2908 ? S 11:01 ↪0:00 dnsmasq -u lxc-dnsmasq --strict-order
↪--bind-interfaces --pid-file=/run/lxc/dnsmasq.pid
↪--listen-address 10.0.3.1 --dhcp-range 10.0.3.2,10.0.3.254
↪--dhcp-lease-max=253 --dhcp-no-override ↪--except-interface=lo --interface=lxcbr0
↪--dhcp-leasefile=/var/lib/misc/dnsmasq.lxcbr0.leases ↪--dhcp-authoritative
root 1196 0.0 0.1 54484 3928 ? Ss 11:01 ↪0:00 [lxc monitor] /var/lib/lxc example-container
root 1658 0.0 0.1 54780 3960 pts/1 S+ 11:02 ↪0:00 sudo lxc-attach -n example-container
root 1660 0.0 0.2 54464 4900 pts/1 S+ 11:02 ↪0:00 lxc-attach -n example-container
To stop a container, type (from the host machine):
$ sudo lxc-stop -n example-container
Once stopped, verify the state of the container:
$ sudo lxc-ls -f
NAME STATE AUTOSTART GROUPS IPV4 IPV6 examplecontainer STOPPED 0
-$ sudo lxc-info -n example-container Name: example-container State: STOPPED
To destroy a container completely—that is, purge it from the host system—type:
$ sudo lxc-destroy -n example-container Destroyed container example-container
Once destroyed, verify that it has been removed:
$ sudo lxc-info -n example-container
example-container doesn't exist
$ sudo lxc-ls -f
$
Note: if you attempt to destroy a running container, the command will fail and inform you that the container is still running:
$ sudo lxc-destroy -n example-container example-container is running
A container must be stopped before it is destroyed.