Using Distrobuilder to Create a LXD Image

30 minutes
  • 8 Learning Objectives

About this Hands-on Lab

While base LXD images are ideal for the majority of LXD use cases, there are times when we’ll want to roll a container image from scratch to precisely suite our needs. For this, we can use Distrobuilder, which lets us configure LXC and LXD images using YAML.

Learning Objectives

Successfully complete this lab by achieving the following learning objectives:

Copy the Base Image Configuration

Create a new buster directory under the existing images directory in the cloud_user‘s home directory:

mkdir images/buster

Copy the existing images/eoan/eoan.yaml file to the new directory to work from:

cp images/eoan/eoan.yaml images/buster/buster.yaml
cd images/buster
Update the Architecture

Open the buster.yaml file and update the image section to reflect Debian 10 (Buster):

vim buster.yaml
image:
 distribution: debian
 release: buster
 description: |-
   Debian {{ image.release }}
 architecture: x86_64
Update the Source

Update the source section to reflect Debian’s download servers and keys:

source:
  downloader: debootstrap
  url: http://deb.debian.org/debian
  keyserver: hkp://keyserver.ubuntu.com:80
  keys:
    - 0x126C0D24BD8A2942CC7DF8AC7638D0442B90D010
    - 0xA1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553
    - 0x6D33866EDD8FFA41C0143AEDDCC9EFBF77E11517
    - 0x80D15823B7FD1561F9F7BCDDDC30D7C23CBBABEE
Remove netplan and Any Ubuntu References

For the next two sections, we want to eliminate any references to Ubuntu, and also fully remove the netplan portion of the configuration:

targets:
  lxc:
    create-message: |-
      You just created an {{ image.description }} container.

      To enable SSH, run: apt install openssh-server
      No default root or user password are set by LXC.

    config:
      - type: all
        before: 5
        content: |-
          lxc.include = LXC_TEMPLATE_CONFIG/ubuntu.common.conf

      - type: user
        before: 5
        content: |-
          lxc.include = LXC_TEMPLATE_CONFIG/ubuntu.userns.conf

      - type: all
        after: 4
        content: |-
          lxc.include = LXC_TEMPLATE_CONFIG/common.conf

      - type: user
        after: 4
        content: |-
          lxc.include = LXC_TEMPLATE_CONFIG/userns.conf

      - type: all
        content: |-
          lxc.arch = {{ image.architecture_personality }}

files:
 - path: /etc/hostname
   generator: hostname

 - path: /etc/hosts
   generator: hosts

 - path: /etc/resolvconf/resolv.conf.d/original
   generator: remove

 - path: /etc/resolvconf/resolv.conf.d/tail
   generator: remove

 - path: /etc/machine-id
   generator: remove

 - path: /etc/network/interfaces
   generator: dump
   content: |-
     # This file describes the network interfaces available on your system
     # and how to activate them. For more information, see interfaces(5).

     # The loopback network interface
     auto lo
     iface lo inet loopback

     auto eth0
     iface eth0 inet dhcp

 - path: /etc/init/lxc-tty.conf
   generator: upstart-tty
   releases:
    - trusty

 - name: meta-data
   generator: cloud-init
   variants:
    - cloud

 - name: network-config
   generator: cloud-init
   variants:
    - cloud

 - name: user-data
   generator: cloud-init
   variants:
    - cloud

 - name: vendor-data
   generator: cloud-init
   variants:
    - cloud
Update the packages Section

Update the packages section of the configuration so that it uses the appropriate Debian repositories and installs the correct packages:

packages:
  manager: apt
  update: true
  cleanup: true

  repositories:
    - name: sources.list
      url: |-
        deb http://deb.debian.org/debian {{ image.release }} main
        deb http://security.debian.org/debian-security {{ image.release }}/updates main

  sets:
    - packages:
      - dialog
      - ifupdown
      - init
      - iproute2
      - isc-dhcp-client
      - locales
      - netbase
      - net-tools
      - openssh-client
      - vim
      action: install

    - packages:
      - cloud-init
      action: install
      variants:
       - cloud
Update the actions Section

Remove any Ubuntu-specific commands from the actions section of the file:

actions:
  - trigger: post-packages
    action: |-
      #!/bin/sh
      set -eux

      # Cleanup underlying /run
      mount -o bind / /mnt
      rm -rf /mnt/run/*
      umount /mnt

      # Cleanup temporary shadow paths
      rm /etc/*-
Create the Image

Use Distrobuilder to generate a packaged image:

sudo distrobuilder build-lxd buster.yaml

Add the image:

lxc image import lxd.tar.xz rootfs.squashfs --alias buster
Test the Image

Create a container based on the new image:

lxc launch buster buster

Additional Resources

Up until now, you have been successfully working on your LXD build without needing to create any base images from scratch. However, one particular application requires the use of a Debian container, and you will need to roll that image yourself.

Using the provided eoan.yaml file as a base, update the Distrobuilder file so that instead of configuring Ubuntu 19.10, it will create a Debian 10 (Buster) image that meets the following requirements:

  • The image section is updated to reflect a Debian Buster release.
  • The sources section uses http://deb.debian.org/debian as the URL, and the following keys:
    • 0x126C0D24BD8A2942CC7DF8AC7638D0442B90D010
    • 0xA1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553
    • 0x6D33866EDD8FFA41C0143AEDDCC9EFBF77E11517
    • 0x80D15823B7FD1561F9F7BCDDDC30D7C23CBBABEE
  • Remove the /etc/netplan/10-lxc.yaml configuration under files, and any references to Ubuntu.
  • Under packages, update the repository to use the following repositories:
    • deb http://deb.debian.org/debian {{ image.release }} main
    • deb http://security.debian.org/debian-security {{ image.release }}/updates main
  • Also ensure the following packages are installed:
    • dialog
    • ifupdown
    • init
    • iproute2
    • isc-dhcp-client
    • locales
    • netbase
    • net-tools
    • openssh-client
    • vim
  • Remove any actions except the post-packages trigger.
  • Remove any locale-related commands from the post-packages trigger.

When finished, create an image. Launch a container based on that image to confirm that it works.

What are Hands-on Labs

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Get Started
Who’s going to be learning?

How many seats do you need?

  • $499 USD per seat per year
  • Billed Annually
  • Renews in 12 months

Ready to accelerate learning?

For over 25 licenses, a member of our sales team will walk you through a custom tailored solution for your business.


$2,495.00

Checkout
Sign In
Welcome Back!

Psst…this one if you’ve been moved to ACG!