Installing LXD as a Snap with Ubuntu Core 16.04 on a Raspberry Pi 3

I have for a long time experimented with LXC/LXD and I’ve got a server running 24/7 in my household to do (among others) DHCP and NS, not because I need but just because I can.

This is of course costing me way too much electricity so I’m exploring the idea to run these services as Linux Containers on a Raspberry Pi 3.

Set-up/prerequisites

  • 1 Raspberry Pi 3
  • A good quality MicroSD card (8GB is used for this proof-of-concept)
  • Ubuntu Core 16.04
  • An account with https://login.ubuntu.com/

 

How I did it

Download Ubuntu Core 16.04

Head over to https://developer.ubuntu.com/core/get-started/raspberry-pi-2-3 and download the Ubuntu Core 16 image for Raspberry Pi 3 (stable) image.

Copy the image to your MicroSD card

Copy the Ubuntu Core image on the SD card by following the installation media instructions.

Boot the Raspbery Pi 3

You’ll be presented with the question to press enter to configure the device and then the networking.

Configured your public key

Make sure you have configured your public key on https://login.ubuntu.com/ so that it’ll be configured on your Ubuntu Core system.

Connect Ubuntu Core to your e-mail address

Ubuntu Core will ask you to enter an e-mail address, enter the e-mail address you use for your account with https://login.ubuntu.com/

Log in on Ubuntu Core

After all is well you’ll be presented with instructions on how to log in to your Ubuntu Core environment.

Install LXD Snap

LXD is available as a Snap since October 2016 (https://stgraber.org/2016/10/17/lxd-snap-available/) so let’s use that.

Create the LXD group

$ sudo -i
# groupadd --system --extrausers lxd

Install LXD

# snap install lxd

Run LXD in debug mode

# lxd --group lxd --debug

You’ll get some output and you’ll have to wait for a couple of minutes for it to go through, remember it’s Pi.

INFO[10–19|20:35:01] LXD 2.19 is starting in normal mode path=/var/snap/lxd/common/lxd 
WARN[10–19|20:35:01] Couldn’t find the CGroup CPUset controller, CPU pinning will be ignored. 
WARN[10–19|20:35:01] Couldn’t find the CGroup pids controller, process limits will be ignored. 
INFO[10–19|20:35:01] Kernel uid/gid map: 
INFO[10–19|20:35:01] — u 0 0 4294967295 
INFO[10–19|20:35:01] — g 0 0 4294967295 
INFO[10–19|20:35:01] Configured LXD uid/gid map: 
INFO[10–19|20:35:01] — u 0 1000000 1000000000 
INFO[10–19|20:35:01] — g 0 1000000 1000000000 
DBUG[10–19|20:35:01] No existing storage pools detected. 
INFO[10–19|20:35:01] Expiring log files 
INFO[10–19|20:35:01] Done expiring log files 
INFO[10–19|20:35:01] Starting /dev/lxd handler 
DBUG[10–19|20:35:01] Looking for existing certificates cert=/var/snap/lxd/common/lxd/server.crt key=/var/snap/lxd/common/lxd/server.key 
INFO[10–19|20:39:59] LXD isn’t socket activated 
DBUG[10–19|20:39:59] Connecting to a local LXD over a Unix socket 
DBUG[10–19|20:39:59] Sending request to LXD etag= method=GET url=http://unix.socket/1.0 
DBUG[10–19|20:39:59] Got response struct from LXD 
DBUG[10–19|20:39:59] 
 { 
 “config”: {}, 
 “api_extensions”: [ 
 “storage_zfs_remove_snapshots”, 
 “container_host_shutdown_timeout”, 
 “container_syscall_filtering”, 
 “auth_pki”, 
 “container_last_used_at”, 
 “etag”, 
 “patch”, 
 “usb_devices”, 
 “https_allowed_credentials”, 
 “image_compression_algorithm”, 
 “directory_manipulation”, 
 “container_cpu_time”, 
 “storage_zfs_use_refquota”, 
 “storage_lvm_mount_options”, 
 “network”, 
 “profile_usedby”, 
 “container_push”, 
 “container_exec_recording”, 
 “certificate_update”, 
 “container_exec_signal_handling”, 
 “gpu_devices”, 
 “container_image_properties”, 
 “migration_progress”, 
 “id_map”, 
 “network_firewall_filtering”, 
 “network_routes”, 
 “storage”, 
 “file_delete”, 
 “file_append”, 
 “network_dhcp_expiry”, 
 “storage_lvm_vg_rename”, 
 “storage_lvm_thinpool_rename”, 
 “network_vlan”, 
 “image_create_aliases”, 
 “container_stateless_copy”, 
 “container_only_migration”, 
 “storage_zfs_clone_copy”, 
 “unix_device_rename”, 
 “storage_lvm_use_thinpool”, 
 “storage_rsync_bwlimit”, 
 “network_vxlan_interface”, 
 “storage_btrfs_mount_options”, 
 “entity_description”, 
 “image_force_refresh”, 
 “storage_lvm_lv_resizing”, 
 “id_map_base”, 
 “file_symlinks”, 
 “container_push_target”, 
 “network_vlan_physical”, 
 “storage_images_delete”, 
 “container_edit_metadata”, 
 “container_snapshot_stateful_migration”, 
 “storage_driver_ceph”, 
 “storage_ceph_user_name”, 
 “resource_limits”, 
 “storage_volatile_initial_source”, 
 “storage_ceph_force_osd_reuse”, 
 “storage_block_filesystem_btrfs”, 
 “resources”, 
 “kernel_limits”, 
 “storage_api_volume_rename” 
 ], 
 “api_status”: “stable”, 
 “api_version”: “1.0”, 
 “auth”: “trusted”, 
 “public”: false, 
 “environment”: { 
 “addresses”: [], 
 “architectures”: [ 
 “armv7l” 
 ], 
 “certificate”: “***********”, 
 “certificate_fingerprint”: “***********”, 
 “driver”: “lxc”, 
 “driver_version”: “2.1.1”, 
 “kernel”: “Linux”, 
 “kernel_architecture”: “armv7l”, 
 “kernel_version”: “4.4.0–1030-raspi2”, 
 “server”: “lxd”, 
 “server_pid”: 2680, 
 “server_version”: “2.19”, 
 “storage”: “”, 
 “storage_version”: “” 
 } 
 } 
error: LXD is already running.

Initialize LXD

# lxd init

Answer questions

Do you want to configure a new storage pool (yes/no) [default=yes]? 
Name of the new storage pool [default=default]: 
Name of the storage backend to use (dir, btrfs, ceph, lvm) [default=btrfs]: 
Create a new BTRFS pool (yes/no) [default=yes]? 
Would you like to use an existing block device (yes/no) [default=no]? no
Size in GB of the new loop device (1GB minimum) [default=15GB]: 4 
Would you like LXD to be available over the network (yes/no) [default=no]? yes 
Address to bind LXD to (not including port) [default=all]: 
Port to bind LXD to [default=8443]: 
Trust password for new clients: ***********
Again: ***********
Would you like stale cached images to be updated automatically (yes/no) [default=yes]? 
Would you like to create a new network bridge (yes/no) [default=yes]? no 
LXD has been successfully configured.

Configure MacVLAN

In my setup I like my containers to get fed IP addresses from my DHCP server.

# lxd.lxc profile device add default eth0 nic nictype=macvlan parent=eth0
Device eth0 added to default

Test it

For some reason it wants to be called like lxd.lxc

# lxd.lxc launch ubuntu:16.04 test
Creating test 
Starting test

This will take quite some time, remember, it’s a Pi.

# lxc list
+------+---------+----------------------+------+------------+-------
| NAME |  STATE  |         IPV4         | IPV6 |    TYPE    | SNAPSH
+------+---------+----------------------+------+------------+-------
| test | RUNNING | 192.168.1.121 (eth0) |      | PERSISTENT | 0         
+------+---------+----------------------+------+------------+-------

My newly created container now has a nice fresh IP address from my DHCP server.

Leave a comment

Your email address will not be published. Required fields are marked *