Understanding and Using LXC and LXD

Posted by admin at 7:38 AM on Nov 7, 2016

Share:


LXC/LXD is a Virtual Machine-like (VM), yet lightweight, Linux container system. Each container has its own filesystem, process space and network stack, thus firewalling a container from its host and the other containers. Rather than emulating hardware they all use the same kernel, so the containers run much more efficiently.

Interesting uses for lxc:

  • compartmentalization (for security, or imposing resource limits)
  • self-contained build or application environments that are independent of the host OS
  • run an older OS version than the host (e.g. run a Ubuntu 12.04 container on a 16.04 host)
  • run a different distro than the host (e.g. run a Fedora container on an Ubuntu host)

What is LXC (lex-see)?

From the official LXC page:

“LXC containers are often considered as something in the middle between a chroot and a full fledged virtual machine. The goal of LXC is to create an environment as close as possible to a standard Linux installation but without the need for a separate kernel.”

“LXC is a userspace interface for the Linux kernel containment features. Through a powerful API and simple tools, it lets Linux users easily create and manage system or application containers.

“Current LXC uses the following kernel features to contain processes:

  • Kernel namespaces (ipc, uts, mount, pid, network and user)
  • Apparmor and SELinux profiles
  • Seccomp policies
  • Chroots (using pivot_root)
  • Kernel capabilities
  • CGroups (control groups)

What is LXD (lex-dee)?

From the official LXD page:

“LXD is a container ‘hypervisor’ and a new user experience for LXC.” Basically it’s a layer above lxc that manages containers using liblxc and a Go binding. “The daemon exports a REST API both locally and, if enabled, over the network.”

“It's basically an alternative to LXC's tools and distribution template system with the added features that come from being controllable over the network.”

How does LXC/LXD differ from Virtualbox, Docker?

Virtualbox is a full VM, emulating hardware and running a kernel on top of it, whereas lxc does not emulate hardware and uses the same kernel as the host.

Docker containers only run a single process and do not have init, whereas lxc does have init and therefore can run a full userspace. Docker containers also have less networking flexibility. It is possible to run Docker in an lxc container.

Networking

By default, when a container is created it assigned a non-routable IP address dynamically via DHCP, and that address is added to the bridge lxdbr0 running NAT. All kinds of configurations are possible, such as:

  • routable IP address so packets flow directly to the container
  • bridge two interfaces, e.g. for a front-end container that needs a routable IP address to talk to the internet while bridging to containers running various back-end application components on non-routable IP addresses
  • fan networking, for very dense virtualization

Note that lxd 2.3+ has much better networking support, since most networking config happens in lxd with its config stored alongside all the other container config, instead of having to configure it all separately.

A Word about ZFS

ZFS is the preferred filesystem to use with lxd, due to:

  • instantaneous snapshots
  • per-filesystem quotas and reservations
  • partition-less, so any number of filesystems can be created dynamically
  • deduplication
  • ease of transferring filesystems between hosts (zfs send/recv), which is useful for migrating containers between hosts

Further reading

https://linuxcontainers.org/

https://www.stgraber.org/2016/03/11/lxd-2-0-blog-p...

https://help.ubuntu.com/lts/serverguide/lxd.html


Installation (Ubuntu 16.04 or newer)

	$ sudo apt install lxd
	$ sudo apt install zfsutils-linux
        $ sudo lxd init


LXC/LXD Crib Sheet

Launch a new container

	lxc launch ubuntu falcon
	lxc launch ubuntu:16.04 falcon
	lxc launch ubuntu:12.04/i386 falcon


Get a list of OS images

	lxc image list images:


Start a shell inside a container

	lxc exec falcon bash


See running containers

	lxc list


Start/stop a container

	lxc start falcon
	lxc stop falcon
	lxc restart falcon
	lxc pause falcon


Move files into/out of a container

	lxc file push myfile falcon/path/to/dest
	lxc file pull falcon/path/to/source myfile
	lxc file edit <container>/<path>


Limit how much disk space a container can use (ZFS/btrfs only)

	lxc config device set falcon root size 20GB


Add a remote lxd to control

	lxc remote add tatooine tatooine.example.com:8443


Create and launch a container on a remote host

	lxc launch ubuntu:16.04 tatooine:cantina


Connect to a remote container

	lxc exec tatooine:cantina bash


Move a container from one instance of lxd to another

        lxc stop falcon
        lxc move falcon tatooine:bar


Automatic Container Setup upon First Boot

Cloud-init is a de facto standard for specifying container configuration. May have originated with AWS. With it you can do things on first boot like:

  1. copy ssh keys into the container
  2. update all packages to the latest
  3. pre-install packages
  4. etc.

Example:

    lxc launch ubuntu:16.04 falcon --config=user.user-data="$(cat cloud-init.yaml)"


cloud-init.yaml:
#cloud-config


# Update apt database on first boot
# (ie run apt-get update)
#
# Default: true
# Aliases: apt_update
package_update: true


# Upgrade the instance on first boot
# (ie run apt-get upgrade)
#
# Default: false
# Aliases: apt_upgrade
package_upgrade: true


packages:
 - rsync


# add each entry to ~/.ssh/authorized_keys for the configured user or the
# first user defined in the user definition directive.
ssh_authorized_keys:
  - ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAu815gmOvEKtfzWp2YQvhz/vpeNX5XczpfKgSxExocjuUV2L70mRHhtF45TwgNdcgWoW5QmYVDrAyuJvywG8NVM77s+UzDrllm+4s7sBBYqZ8kawLjVlHF6NNJn5EhPE5AJGGiTtI0QgM7YGUGx8ZkIC2/VFOxiYjfJV2S9oTHZW3NNc8THb7gBfROxu5KVHIC2Mz9JToZSLX3Evl05HFjYW6Ijs+00af7VBcgXRnEWCZNmbI8G4PSHLSo0NzH1mPPNzAavCfLKZ4MGF10KPWDdsx/YbNPPlr8ZIDCDW3W2N/ldKu8GSfOfNti7KlAj2HUVgupwOQlClWnIozye3eBw== joe@example.com
  - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCUPpQPBwOhs2Bk20ZJO0OdjZOVyYOsJxldl+P8s8LTvYDLkaxLZGtaIyaQISybI/5kUQa6soPhxn8x1lzDWnQU109pdFNbTlqtnQZi/lBu8qwMzeaWf2PL/Dd7F7ha5VA11omtBM87f5rRm4hGT3i96WxDg6/KW2/oqVBufa9P7WMQKRyKuSB0Tw5GzJrFcUvUDYDJ2KYIeCVfPUiinTrdVSCUMuPdhLxbRag//8OrN4+ACON+Gbe0l0cx172HHHcfaQZmrlb3W7JuyQg2m6BO45SC8/qpL50fDld1LmswrqzwOqwwlF3dq3x67sei3puP5vZIVhOEq3gGIQxyvb/5 foo@bar.com

Loading Conversation