Archive Caching For LXD

Saving bandwidth and time

Preface

I enjoy using LXD. It is feature-rich and convenient. I regularly use LXD to spin up system containers and virtual machines for a variety of tasks.

I try to be a good citizen of my network and the internet which means I find ways to reduce my bandwidth. I try to be efficient with my time, which often requires me to solve tangential problems to support the problem I'm working on for both now and the future.

In recent times there have been occasions where I have spun up a virtual machines several times in an evening to perform installations of Ubuntu and Kubuntu for experimentation purposes. Upgrading all of the packages and installing the packages I need to complete my mischief is constrained by my available bandwidth and the time taken to transport the data from the Ubuntu Archive to my machine.

Caching Apt Packages

After a few minutes of researching apt proxies, I decided to try apt-cacher-ng. I chanted the magical incantation to install the pacakge on the LXD host (my computer):

sudo apt install apt-cacher-ng

I followed the dpkg installation configuration screen and kept to the defaults. I retrospectively enabled http-tunnels to remedy some issues I experienced.

Apt-Cacher NG can be configured to allow users to create HTTP tunnels, which can be used to access remote servers that might otherwise be blocked by (for instance) a firewall filtering HTTPS connections.

This feature is usually disabled for security reasons; enable it only for trusted LAN environments.

Allow HTTP tunnels through Apt-Cacher NG?

Notice that this is a impediment upon your security posture. Don't do it unless you must.

By default apt-cacher-ng listens on port 3142, which is fine with me!

I proceeded to create a proxy config for apt

/etc/apt/apt.conf.d/proxy.conf

with the contents:

Acquire::http::Proxy "http://127.0.0.1:3142";

Instructing apt update/ apt upgrade on my computer now results in apt-cacher-ng transparently caching the downloaded data, and apt continuing to perform the work it does so well.

You can watch the cache in action when performing an update or upgrade:

tail -f /var/log/apt-cacher-ng/apt-cacher.log

Nice.

Configuring apt-cacher-ng

Remember, the goal was to set up package caching for LXD to reuse that data. Therefore I needed to enable my containers/ VMs to reach the proxy. To do so, I obtained the IP address that my computer was assigned by LXD on the lxdbr0 NIC.

lxc network list

My other NICs have been omitted for conciseness.

+-----------+----------+---------+-----------------+---------------------------+-------------+---------+---------+
|   NAME    |   TYPE   | MANAGED |      IPV4       |           IPV6            | DESCRIPTION | USED BY |  STATE  |
+-----------+----------+---------+-----------------+---------------------------+-------------+---------+---------+
| lxdbr0    | bridge   | YES     | 10.169.240.1/24 | fd42:a1aa:6705:dc07::1/64 |             | 13      | CREATED |
+-----------+----------+---------+-----------------+---------------------------+-------------+---------+---------+

Armed with this information, I opened the apt-cacher-ng configuration file

sudo -E "${EDITOR}" /etc/apt-cacher-ng/acng.conf

and updated the BindAddress to listen on both my computer's localhost and the lxdbr0 address, 10.169.240.1:

BindAddress: localhost 10.169.240.1

and restarted the service:

sudo systemctl restart apt-cacher-ng

At this point, a firewall rule to allow traffic from the containers to the proxy was required.

Configuring LXD Containers and VMs

I pushed a new proxy file into my existing containers/ VMs, which was

/etc/apt/apt.conf.d/proxy.conf

with the contents:

Acquire::http::Proxy "http://10.169.240.1:3142";

however, I've subsequently learned of the DNS name LXD associates my computer with: _gateway.lxd, so I will be altering the proxy.conf files to:

Acquire::http::Proxy "http://_gateway.lxd:3142";

It works a treat on the host I've already reconfigured.

Automated Deployment

LXD Profiles are wonderful. We can use them to provision hosts using existing configuration, including an apt proxy. Oh yeah!

I cloned my default profile, naming it Homelab, and configured it as follows:

name: Homelab
description: Homelab integrated containers. Beware, has dependencies on existing infrastructure!
config:
  user.vendor-data: |
    #cloud-config
    package_update: true
    package_upgrade: true
    package_reboot_if_required: true
    timezone: Etc/UTC
    apt:
      http_proxy: http://_gateway.lxd:3142

# The device config goes here

which enables me to be extra efficient in my spinning up of new hosts. Now I merely issue:

lxc launch ubuntu:jammy --profile Homelab

in order to provision a host which uses my cache!

The cached data from updating one host should then be available for all subsequent hosts of the same OS, e.g if the first host runs Ubuntu Jammy (22.04), all subsequent hosts running Jammy will have the cached data at their disposal.

Roundup

I haven't invested much, if any, time refining the operation of apt-cacher-ng. I do plan to though, and I'll report back with anything worth sharing. I have seen the webpage hosted on port 3142, for those of us who own a magnifying glass, which hosts a few useful tips and URLs.

Is that it? Yes, for now. There's a trivial optimization I have for the container/ VM images too which I'll write about soon.

Resources

Here are a few resources to help you on your way: