C²S Consulting logo
C²S Consulting | Primers | LXC/LXD

Linux Container Hypervisor (LXD)

Diarmuid O'Briain, diarmuid@obriain.com
11/12/2017, version 1.0

Last updated: 11-12-2017 21:12


Introduction

LinuX Containers (LXC)

LXC have been around for some time and were the original base for container products like Docker. LXC provides operating system-level virtualisation through a virtual environment that has its own process and network space, instead of creating a full-fledged Vrtual Machine (VM) like with Kernel Vrtual Machine (KVM). LXC relies on the Linux kernel cgroups functionality that was released in version 2.6.24. It also relies on other kinds of namespace isolation functionality, which were developed and integrated into the mainline Linux kernel.

Linux Container Hypervisor (LXD)

LXD is a system container manager which manages LXC Containers. It offers a user experience similar to a VM manager like virsh with KVM but using LXC instead. It's image based with pre-made images available for a wide number of Linux distributions and is built around a very powerful, yet pretty simple, REST API. It offers [2]:

  • Security by design
  • Scalability
  • Intuitive
  • Image based
  • Support for Cross-host container and image transfer
  • Advanced resource control
  • Device passthrough
  • Network management
  • Storage management

LXD [3]:

  • Achieves 14.5 times greater density than KVM
  • Launches instances 94% faster than KVM
  • Provides 57% less latency than KVM

Installing the software

Install LXD and the LXD Client.

  alovelace@lxd1:~$ sudo apt install lxd lxd-client
  
  alovelace@lxd1:~$ sudo sed 's/GRUB_CMDLINE_LINUX_DEFAULT=""/GRUB_CMDLINE_LINUX_DEFAULT="swapaccount=1"/' /etc/default/grub
  
  alovelace@lxd1:~$ lxc --version && lxd --version
  2.18
  2.18
  

Groups and Users

Check that an lxd group was created and the user alovelace was added to it.

  alovelace@lxd1:~$ cat /etc/group | grep lxd
  lxd:x:111:alovelace
  

If not add the group and add the user to the group. The id -un command simply inserts the current user into the group.

  alovelace@lxd1:~$ groupadd lxd
  alovelace@lxd1:~$ usermod --append --groups lxd `id -un`
  

Confirm.

  alovelace@lxd1:~$ cat /etc/group | grep lxd
  lxd:x:111:alovelace
  

Reboot.

  alovelace@lxd1:~$ sudo shutdown --reboot now
  

Login after reboot and confirm the LXD Container service is running.

  alovelace@lxd1:~$ systemctl status lxd-containers.service
  ● lxd-containers.service - LXD - container startup/shutdown
     Loaded: loaded (/lib/systemd/system/lxd-containers.service; enabled; vendor p
     Active: active (exited) since Mon 2017-11-20 11:21:44 EAT; 10min ago
       Docs: man:lxd(1)
    Process: 890 ExecStart=/usr/bin/lxd activateifneeded (code=exited, status=0/SU
   Main PID: 890 (code=exited, status=0/SUCCESS)
      Tasks: 0 (limit: 4915)
     Memory: 0B
        CPU: 0
     CGroup: /system.slice/lxd-containers.service
  
  Nov 20 11:21:42 lxd1 systemd[1]: Starting LXD - container startup/shutdown...
  Nov 20 11:21:44 lxd1 systemd[1]: Started LXD - container startup/shutdown.
  

Create template containers

Initialise LXD as root before creating any containers.

  alovelace@lxd1:~$ sudo lxd init
  Do you want to configure a new storage pool (yes/no) [default=yes]? <CR>
  Name of the new storage pool [default=default]: <CR>
  Name of the storage backend to use (dir, btrfs, lvm) [default=btrfs]: <CR>
  Create a new BTRFS pool (yes/no) [default=yes]? <CR>
  Would you like to use an existing block device (yes/no) [default=no]? <CR>
  Size in GB of the new loop device (1GB minimum) [default=100GB]: <CR>
  Would you like LXD to be available over the network (yes/no) [default=no]? yes <CR>
  Address to bind LXD to (not including port) [default=all]: <CR>
  Port to bind LXD to [default=8443]: <CR>
  Trust password for new clients: alovelace <CR>
  Again: alovelace <CR>
  Would you like stale cached images to be updated automatically (yes/no) [default=yes]? <CR>
  Would you like to create a new network bridge (yes/no) [default=yes]? no <CR>
  LXD has been successfully configured.
  
  Would you like to create a new network bridge (yes/no) [default=yes]? <CR>
  What should the new bridge be called [default=lxdbr0]? <CR>
  What IPv4 address should be used (CIDR subnet notation, “auto” or “none”) [default=auto]? <CR>
  What IPv6 address should be used (CIDR subnet notation, “auto” or “none”) [default=auto]? <CR>
  LXD has been successfully configured.
  

Create a container for 17.10 Artful Ardvark.

  alovelace@lxd1:~$ lxc init ubuntu:17.10 ub-17-10
  Creating ub-17-10
  Retrieving image: rootfs: 82% (93.94kB/s)
  Starting ub-17-10
  

List the containers.

  alovelace@lxd1:~$ lxc list
  +----------+---------+------+------+------------+-----------+
  |   NAME   |  STATE  | IPV4 | IPV6 |    TYPE    | SNAPSHOTS |
  +----------+---------+------+------+------------+-----------+
  | ub-17-10 | STOPPED |      |      | PERSISTENT | 0         |
  +----------+---------+------+------+------------+-----------+
  

For the purpose of learning it is assumed that the containers will have two virtual Network Interface Cards (NIC), one in a Virtual Local Area Network (VLAN) 10 and the second in a VLAN 20. Create a new profile that incorporates both VLANs.

  alovelace@lxd1:~$ lxc profile copy default dualnic
  
  alovelace@lxd1:~$ lxc profile edit dualnic
  ### This is a yaml representation of the profile.
  # Added for DualNIC configuration.
  
  config: {}
  description: LXD Dual NIC profile
  devices:
    ens3:
      name: ens3
      nictype: bridged
      parent: vlan10
      type: nic
    ens4:
      name: ens4
      nictype: bridged
      parent: vlan20
      type: nic
    root:
      path: /
      pool: default
      type: disk
  name: dualnic
  used_by: []
  

Edit the container configuratios with the new dualnic network profile.

  alovelace@lxd1:~$ lxc config edit ub-17-10
  
  profiles:
  - dualnic
  

Update images and install common software.

  alovelace@lxd1:~$ lxc start ub-17-10
  

Give the image a temporary IP address, update and install common tools. Also setup password support in SSH as well as set DNS default precedence to IPv4 over IPv6.

  alovelace@lxd1:~$ lxc exec ub-17-10 /bin/bash
  root@ub-17-10:~# ip address add 192.168.92.150/24 dev ens3
  root@ub-17-10:~# ip route add 0.0.0.0/0 via 192.168.10.1
  root@ub-17-10:~# echo -e "\nnameserver 8.8.8.8" | tee -a /etc/resolv.conf
  root@ub-17-10:~# apt -y update && apt -y dist-upgrade
  

Allow SSH access via password.

  root@ub-17-10:~# sed -i.bak 's/PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config
  

Allow SSH access and sudo rights for user alovelace.

  root@ub-17-10:~# usermod --append --groups ssh,sudo alovelace
  

Allow SSH with passwords for user alovelace.

  root@ub-17-10:~# passwd alovelace
  Enter new UNIX password: babbage
  Retype new UNIX password: babbage
  passwd: password updated successfully
  

Set DNS default precedence to IPv4 over IPv6.

  root@ub-17-10:~# cat <<EOM | tee -a /etc/gai.conf
  
  # Prioritise IPv4 over IPv6 for DNS requests
  # (No IPv6 public address for testbed lab)
  
  scopev4 ::ffff:169.254.0.0/112  2
  scopev4 ::ffff:127.0.0.0/104    2
  scopev4 ::ffff:0.0.0.0/96       14
  precedence ::ffff:0:0/96  100
  
  EOM
  

Set locale as required.

  
  alovelace@ub-17-10:~$ sudo locale-gen en_IE.UTF-8
  Generating locales (this might take a while)...
    en_IE.UTF-8... done
  Generation complete.
  
  alovelace@ub-17-10:~$ sudo dpkg-reconfigure locales
  Generating locales (this might take a while)...
    en_AG.UTF-8... done
    en_AU.UTF-8... done
    en_BW.UTF-8... done
    en_CA.UTF-8... done
    en_DK.UTF-8... done
    en_GB.UTF-8... done
    en_HK.UTF-8... done
    en_IE.UTF-8... done
    en_IL.UTF-8... done
    en_IN.UTF-8... done
    en_NG.UTF-8... done
    en_NZ.UTF-8... done
    en_PH.UTF-8... done
    en_SG.UTF-8... done
    en_US.UTF-8... done
    en_ZA.UTF-8... done
    en_ZM.UTF-8... done
    en_ZW.UTF-8... done
  Generation complete.
  
  alovelace@ub-17-10:~$ sudo update-locale LC_ALL=en_IE.UTF-8
  
  alovelace@ub-17-10:~$ sudo locale
  LANG=en_IE.UTF-8
  LANGUAGE=en_IE:en
  LC_CTYPE="en_IE.UTF-8"
  LC_NUMERIC="en_IE.UTF-8"
  LC_TIME="en_IE.UTF-8"
  LC_COLLATE="en_IE.UTF-8"
  LC_MONETARY="en_IE.UTF-8"
  LC_MESSAGES="en_IE.UTF-8"
  LC_PAPER="en_IE.UTF-8"
  LC_NAME="en_IE.UTF-8"
  LC_ADDRESS="en_IE.UTF-8"
  LC_TELEPHONE="en_IE.UTF-8"
  LC_MEASUREMENT="en_IE.UTF-8"
  LC_IDENTIFICATION="en_IE.UTF-8"
  LC_ALL=en_IE.UTF-8
  

Stop the container.

  alovelace@lxd1:~$ lxc stop ub-17-10
  

Copy template to working containers

Copy template container to create new containers based on it.

  alovelace@lxd1:~$ lxc copy ub-17-10 art1
  alovelace@lxd1:~$ lxc copy ub-17-10 art2
  
  

Check the containers.

  alovelace@lxd1:~$ lxc list
  +----------+---------+------+------+------------+-----------+
  |   NAME   |  STATE  | IPV4 | IPV6 |    TYPE    | SNAPSHOTS |
  +----------+---------+------+------+------------+-----------+
  | art1     | STOPPED |      |      | PERSISTENT | 0         |
  +----------+---------+------+------+------------+-----------+
  | art2     | STOPPED |      |      | PERSISTENT | 0         |
  +----------+---------+------+------+------------+-----------+
  | ub-17-10 | STOPPED |      |      | PERSISTENT | 0         |
  +----------+---------+------+------+------------+-----------+
  

References

  [1] What's LXC? [online]. Available: https://linuxcontainers.org/lxc/ [accessed: 10 Dec 2017].
  [2] What's LXD? [online]. Available: https://linuxcontainers.org/lxd/ [accessed: 10 Dec 2017].
  [3] Canonical. LXD crushes KVM in density and speed [online], 18 May 2015. Available: https://insights.ubuntu.com/2015/05/18/lxd-crushes-kvm-in-density-and-speed/ [accessed: 10 Dec 2017].
  [4] Stéphane Graber. LXD 2.0: Your first LXD container [online]. Available: https://stgraber.org/2016/03/19/lxd-2-0-your-first-lxd-container-312/ [accessed: 10 Dec 2017].
  

Transfer public key to LinuX Container (lxc)

Generate local keys

  
  alovelace@ub-17-10:~$ ssh-keygen -t rsa -C "ada@lovelace.com"
  Generating public/private rsa key pair.
  Enter file in which to save the key (/home/ubuntu/.ssh/id_rsa): 
  Enter passphrase (empty for no passphrase): 
  Enter same passphrase again: 
  Your identification has been saved in /home/ubuntu/.ssh/id_rsa.
  Your public key has been saved in /home/ubuntu/.ssh/id_rsa.pub.
  The key fingerprint is:
  SHA256:xSZx/hYlNYBtsVgeD5ccVHaTX/kRGkWqTn0WB9k2O2k ada@lovelace.com
  The key's randomart image is:
  +---[RSA 2048]----+
  |        . .oBB@@B|
  |         =.+oOBO*|
  |        . *.+o.oX|
  |         + .o. E=|
  |        S  oo..o.|
  |          o.  o  |
  |           .     |
  |                 |
  |                 |
  +----[SHA256]-----+
  

Push the public key to the container

  alovelace@ub-17-10:~$ lxc file push ~/.ssh/id_rsa.pub rs/root/.ssh/authorized_keys

Connect to container and set owner and rights on keys

  alovelace@ub-17-10:~$ lxc exec rs /bin/bash
  
  root@ub-17-10:~# chmod 600 /root/.ssh/authorized_keys 
  root@ub-17-10:~# chown root: /root/.ssh/authorized_keys
  root@ub-17-10:~# exit

Test network login

  alovelace@ub-17-10:~$ ssh root@192.168.89.6
  
  root@rs:~# 





Copyright © 2024 C²S Consulting