Run LXC Containers on Raspberry Pi with Raspbian Buster
I'm super excited today, as I discovered you can run LXC containers on the LXD hypervisor hosted on a Raspberry Pi 4.
I'm using Raspbian Buster as the Operating System
What are we doing today?
I was searching for "lightweight virtual machines on raspberry pi" and found a couple of projects, but felt a bit unstable at the point.
Then I started to move to system containers, lxc, which is not a virtual machine, but they "feel" like one.
So in this tutorial I will show you how to install LXD on Raspbian Buster and how to launch a Alpine LXC container, install OpenSSH Server and SSH from our host to our Alpine LXC Container.
Install LXD
First we need to install snapd and bridge-utils:
$ sudo apt update
$ sudo apt install snapd bridge-utils -y
Install LXD with Snap:
$ sudo snap install core lxd
If you log out and back in, and you don't find lxd in your path, have a look at this issue
You can set your path temporarily:
$ export PATH=$PATH:/snap/bin
Or for a permanent solution append to your ~/.bashrc
:
export PATH=$PATH:/snap/bin
You should be able to see the following output:
$ lxd -h
Description:
The LXD container manager (daemon)
This is the LXD daemon command line. It's typically started directly by your
init system and interacted with through a tool like `lxc`.
There are however a number of subcommands that let you interact directly with
the local LXD daemon and which may not be performed through the REST API alone.
Usage:
lxd [flags]
lxd [command]
If you are seeing ERROR: ld.so: object '/usr/lib/arm-linux-gnueabihf/libarmmem-${PLATFORM}.so' from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored.
I stumbled upon this post and removed /usr/lib/arm-linux-gnueabihf/libarmmem-${PLATFORM}.so
from /etc/ld.so.preload
Initialize LXD
Initialize LXD and answer questions on how you want your setup customized, such as IPv4, cluster, storage etc:
$ lxd init
To list all arm based images:
$ lxc image list images:armhf
(output edited for display reasons)
| ALIAS | DESCRIPTION | ARCHITECTURE | SIZE |
| alpine/3.11 (3 more) | Alpine 3.11 armhf | armv7l | 2.14MB |
| alpine/edge (3 more) | Alpine edge armhf | armv7l | 3.61MB |
| archlinux (5 more) | Archlinux armhf | armv7l | 143.72MB |
| centos/7 (3 more) | Centos 7 armhf | armv7l | 78.95MB |
| debian/10 (7 more) | Debian buster armhf | armv7l | 69.02MB |
...
Launch your first LXC Container
I will initialize a new container, called alpine-container
using the alpine 3.11 image:
$ lxc init images:alpine/3.11 alpine-container
Creating alpine-container
The image will now be pulled from the remote server then create the container and keep it in a stopped state, we can verify that by running:
$ lxc list
+-------------------+---------+---------------------+-----------+
| NAME | STATE | IPV4 | TYPE |
+-------------------+---------+---------------------+-----------+
| alpine-container | STOPPED | | CONTAINER |
+-------------------+---------+---------------------+-----------+
Let's start the container:
$ lxc start alpine-container
Let's list our containers:
$ lxc list
+-------------------+---------+---------------------+-----------+
| NAME | STATE | IPV4 | TYPE |
+-------------------+---------+---------------------+-----------+
| alpine-container | RUNNING | 10.6.192.196 (eth0) | CONTAINER |
+-------------------+---------+---------------------+-----------+
To exec into your LXC container:
$ lxc exec alpine-container -- sh
~ #
Install OpenSSH-Server on Alpine
Let's install the OpenSSH-Server on alpine:
$ apk update
$ apk add openssh-server
I'm creating a new user to test ssh:
$ adduser ruan
New password:
Retype password:
passwd: password for ruan changed by root
Now we want to ssh to our container with our newly created user, using a ssh key. If you don't have a SSH key, create one:
$ ssh-keygen -f ./test -t rsa -C "Test" -q -N ""
Copy the contents of the public key, so that we can include it in the container's authorized_keys file of the target user:
$ cat ./test.pub
Let's switch to that user and create the authorized_keys file:
$ su - ruan
$ cat 'copied contents of ssh public key' >> ~/.ssh/authorized_keys
$ exit
Enable the OpenSSH Server on boot as the root user:
$ rc-update add sshd
Start the SSH Server:
$ /etc/init.d/sshd restart
SSH to the LXC Container
From the host, ssh to the container:
$ ssh ruan@10.6.192.196
Welcome to Alpine!
The Alpine Wiki contains a large amount of how-to guides and general
information about administrating Alpine systems.
See <http://wiki.alpinelinux.org/>.
You can setup the system with the command: setup-alpine
You may change this message by editing /etc/motd.
alpine-container:~$
Pretty neat right?
Resources
Some resources I stumbled upon:
- https://discourse.pi64.win/t/woa-kvm-virtual-machine-on-raspberry-pi-or-any-sbc-or-arm-mobile-device/241
- https://blog.cloudkernels.net/posts/firecracker-rpi4/
- https://www.raspberrypi.org/forums/viewtopic.php?f=56&t=248345&p=1526221#p1526221
- https://wiki.alpinelinux.org/wiki/Settingupa_ssh-server
- http://www.makikiweb.com/Pi/lxconthe_pi.html
- http://www.makikiweb.com/Pi/lxc_openwrt.html
- https://snapcraft.io/install/lxd/raspbian