Linux Container Hypervisor (LXD)
Diarmuid O'Briain, diarmuid@obriain.com11/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:~#