Running LXD containers in Macpine
Overview
LXD is a next generation system container manager with support for a wide number of Linux distributions. It provides a simple way to build, test, and run multiple Linux environments across a single machine or multiple compute clusters.
Under the hood, LXD uses LXC, through liblxc and its Go binding, to create and manage the containers. However, LXD relies on a number of Linux kernel features, such as CGroups and kernel namespaces, which aren't natively available on MacOS.
Macpine makes it possible to run LXD/LXC containers on MacOS with support for both amd64 and arm64 processors, through its lightweight virtualisation layer. This workflow makes it easy to develop and test LXD containers locally.
Prerequisites
- Install QEMU and macpine
brew install qemu macpine
- Install the LXD client
brew install lxc
Launch an LXD instance
Now that that the system is ready, we can create a lightweight Macpine instance, which has been pre-configured to run LXD. In your terminal run:
alpine launch --image alpine_3.16.0_lxd --name lxd --port 8443 --ssh 2222 --mount $(pwd)
This will create a new instance called lxd
and forward port 8443
(the default port that LXD client uses to communicate with the LXD server) of the instance to host. Macpine will attempt to match the native CPU architecture of your host to the correct instance image. However, if you can explicitly specify the architecture by adding either --arch aarch64
or --arch x86_64
to the above command. This will mount your current working directory to /root/mnt
inside of the lxd
instance.
Configure LXD
Before you can create an instance, you need to configure LXD.
Run the following command to accept all automatic defaults:
alpine exec lxd "lxd init --auto"
For the purposes of this tutorial, it is recommended to accept default settings.
NOTE: the above command is executed inside your
lxd
instance and is sandboxed from your host.
Configure LXD remote
Set up your LXD remote to communicate with the LXD client on your host.
alpine exec lxd "lxc config set core.https_address 0.0.0.0"
alpine exec lxd "lxc config set core.trust_password root"
NOTE: for the purposes of this demonstration, the remote password is configured as
root
. This password can be configured withlxc config set core.trust_password
above
Add the remote to your LXD host:
lxc remote add macpine 127.0.0.1 --accept-certificate --password root
NOTE: if you create an alpine lxd instance, then destroy it, then try to reconfigure another on later on your host, you may need to delete
macpine
remote from~/.config/lxc/config.yml
due to new certificates each time?
Finally, set this remote as the default:
lxc remote switch macpine
That's it - you can now run LXD containers through Macpine at nearly-native speeds!
Launching your first LXD container
LXD containers can now be launched and manipulated through the lxc
client:
lxc launch images:debian/bullseye debian
Mounting host directory -> lxd Macpine instance -> lxd container
lxc config device add debian share disk source=/root/mnt path=/root/mnt
Connecting to your first LXD container
lxc exec debian -- bash
Cleanup
lxc stop debian
lxc delete debian
alpine stop lxd
alpine delete lxd