Command Line Client
LXD command line client provides a good user-friendly interface for the users to manage and use LXD containers. But it might be impossible to manage thousands of containers on multiple LXD servers using this command line client. In such cases OpenStack provides a plugin "nova-lxd" to manager LXD containers just like any virtual machine.
INSTALLATION
Installing LXD on Ubuntu 16.04 Desktop
$ sudo apt-get install lxd lxd-* criu python-setuptools zfsutils-linux bridge-utils
The above command will install lxd, lxd-client and lxd-tools packages. One can verify that the above packages are installed by running the below command.
$ sudo dpkg -l | grep lxd
Before the installation exits, it will display a message that a default LXD bridge "lxdbr0" is also provided unconfigured with the LXD package. The lxdbr0 bridge is used for routing the traffic to the containers either through proxied HTTP or SSH for user convenience. Earlier versions LXD used lxcbr0 as default bridge, but now LXD is gradually stopping it's dependency upon LXC. Using the below command one can exclusively configure lxdbr0 bridge.
$ sudo dpkg-reconfigure -p medium lxd
INITIALIZATION
Command line tool can be used for LXD to configure all of LXD and it's components like filesystem and bridge. The "lxd init" tool helps to interactively configure various LXD component and their functions.
$ sudo lxd init
Canonical recommends to use ZFS filesystem for LXD. ZFS supports per-container disk quotas, snapshot / restore, live migration, instant container creation like advanced features. LXD also supports other filesystems such as btrfs, lvm and a simple directory.
CONTAINER MANAGEMENT
LXD provides a very user-friendly command line interface to manage containers. One can perform activities like create, delete, copy, restart, snapshot, restore like many other activities to manage the containers.
Creating a container with the below shown command is very easy, it will create a container with best supported Ubuntu image from ubuntu: image server, set a random name and start it.
$ lxc launch ubuntu:
Creating a container using latest, stable image of Ubuntu 12.04, set a random name and start it.
$ lxc launch ubuntu:12.04
Creating a container using latest, stable image of Ubuntu 16.04, set name "container1" and start it.
$ lxc launch ubuntu:16.04 container0
To create a container using CentOS 7 64-bit image, set name "container2" and start it, we first have to search the "images:" remote image server and copy the required alias name.
$ lxc image list images: | grep centos | grep amd
$ lxc launch images:centos/7/amd64 container1
Creating a container using OpenSuSE 13.2 64-bit image, set name "container3" without starting it.
$ lxc init images:opensuse/13.2/amd64 container2
Remote image server "ubuntu-daily" can be used to create a container using latest
development release of Ubuntu.
Listing containers
$ lxc list
Query detailed information of a particular container
$ lxc info container1
Start, stop, stop forcibly and restart containers
$ lxc start container1
$ lxc stop container1
$ lxc stop container1 --force
$ lxc restart container1
Stateful stop
Containers start from scratch after a reboot. To make the changes persistent across reboots, a container needs to be stopped in a stateful state. With the help of CRIU, the container state is written to the disk before shutting down. Next time the container starts, it restores the state previously written to disk.
$ lxc stop container1 --stateful
Pause containers
Paused containers do not use CPU but still are visible and continue using memory.
$ lxc pause container1
Deletion and forceful deletion of containers
$ lxc delete container1
$ lxc delete container1 --force
Renaming Containers
Just like the Linux move command renames a particular file or directory, similarly the containers can also be renamed. A running container cannot be renamed. Renaming a container doesnot change it's MAC address.
$ lxc move container1 new-container
Configuring Containers
Container settings like controlling container startup, including resource limitations and device pass-through options can be altered on live containers. LXD supports varioius devices like disk devices (physical disk, partition, block/character device), network devices (physical interface, bridged, macvlan, p2p) and none. None is used to stop inheritance of devices from profiles.
Profiles
Profiles store the container configuration. Any number of profiles can be applied to a container, but these profiles are applied in the order they are specified. Hence, always the last profile overrides the previous one. By default, LXD is preconfigured with "default" profile which comes with one network device connected to LXD's default bridge "lxdbr0". Any new container that is created has "default" profile set.
Listing profiles
$ lxc profile list
Viewing default profile content
$ lxc profile show default
Editing default profile
$ lxc profile edit default
Applying a list of profiles to a container
$ lxc profile apply container1 <profile1> <profile2> <profile3> ...
Editing the configuration of a single container
$ lxc config edit container1
Adding a network device to container1
$ lxc config device add container eth1 nic nictype=bridged parent=lxcbr0
Listing the device configuration of container1
$ lxc config device list container1
Viewing container1 configuration
$ lxc config show container1
Above listed are a few examples of basic commands in use. There are many more options that can be used with these commands. A complete list of configuration parameters is mentioned here.
Executing Commands
Commands executed through LXD will always run as the container's root user.
Getting a shell inside the container
$ lxc exec container1 bash
File Transfers
LXD can directly read / write in the container's filesystem.
Pulling a file from container1
$ lxc file pull container1 /etc/redhat-release ~
Reading a file from container1
$ lxc file pull container1 /etc/redhat-release -
Pushing a file to container1
$ lxc file push /etc/myfile container1/
Editing a file on container1
$ lxc file edit container1/etc/hosts
SNAPSHOT MANAGEMENT
Snapshots help in preserving the point in time running state of containers including container's filesystem, devices and configuration, if --stateful flag is used. A stateful snapshot can only be taken on a running container, where stateless snapshot can be taken on stopped containers.
Creating container1 stateless snapshot
$ lxc snapshot container1
Creating container1 stateful snapshot with name c1s1
$ lxc snapshot container1 --stateful c1s1
Listing snapshots
Number of snapshots created per container can be listed using below mentioned command.
$ lxc list
A detailed snapshot information related to container1 like snapshot name, stateless / stateful can be obtained by executing below command.
$ lxc info container1
Restoring snapshot
$ lxc restore container1 c1s1
Renaming snapshot
$ lxc move container1/c1s1 container1/c1s1-new\
Creating a container using snapshot
$ lxc copy container1/c1s1 container-c1s1
Deleting snapshot
$ lxc delete container1/c1s1
Cloning
Cloning or copying a container is a lot faster process to create containers if the requirement permits so. Cloning a container resets the MAC address for the cloned container and does not copy the snapshots of parent container.
$ lxc copy container1 container1-copy
RESOURCE MANAGEMENT
LXD allows an efficient way to dynamically manage the resources like setting memory quotas, limiting CPU, I/O priorities and limiting disk usage. Resource allocation can be done on per container basis as well as globally through profiles. All limits can be configured in live environments where they can take effect immediately. In the below example, first command defines the limit on per container basis whereas the second sets the limits globally using profiles.
$ lxc config set <container> <key> <value>
$ lxc profile set <profile> <key> <value>
Disk Limits
Unlike virtual machines containers don't reserve resources but allow us to limit the resources. Currently disk limits can be implemented only if ZFS or btrfs filesystems are in use.
CPU Limits
CPU limits can be configured using the following ways.
- Limiting number of CPUs: Assigning only a particular number of CPUs, restricts LXD to use specified number of CPUs and not more than that. LXD load balances the workload among those number of CPUs as the containers start and stop. For example, we can allow LXD to use only 4 cores and it will load balance between them as per the requirement.
$ lxc config set container1 limits.cpu 2
- Limiting to particular set of CPUs: Assigning only particular cores to be used by the containers. Load balance does not work here. For example, we can allow only cores 5, 7 and 8 to be used by the containers on a server.
$ lxc config set container1 limits.cpu 1,2,3,4
Pinning cpu core ranges
$ lxc config set container1 limits.cpu 0-2,7,8
- Limiting to CPU usage percent: Containers can be limited to use only a particular percent of CPU time when under load even though containers can see all the cores. For example, a container can run freely when the system is not busy, but LXD can be configured to limit the CPU usage to 40% when there are a number of containers running.
$ lxc config set container1 limits.cpu.allowance 40%