LXD 0.3

lxd

LXD 0.3 has been released. This version provides huge usability improvements over past versions.

Getting started

Here’s an example of quickly getting started on a fresh Ubuntu 15.04 VM:

sudo add-apt-repository ppa:ubuntu-lxc/lxd-daily
sudo apt-get update
sudo apt-get install lxd
sudo lxd-images import lxc ubuntu trusty amd64 --alias ubuntu

(If you are using Ubuntu 14.04 Trusty,  you can just add ppa:ubuntu-lxc/daily to get the uptodate packages;  If running something else, see the LXD website for instructions.)

lxd-images is a temporary script which downloads an image from images.linuxcontainers.org. You can also manually import any valid image tarball using the ‘lxc image import’ command, however the goal eventually is to have images automatically be downloaded (subject to your consent, i.e. depending on your current network situation) by the lxd package.

You can download and import a debian image by doing:

lxd-images import lxc debian wheezy amd64 --alias debian

You can view the list of available local images by doing:

ubuntu@vlxd:~$ lxc image list
+--------+----------+--------+-------------+
| ALIAS  |   HASH   | PUBLIC | DESCRIPTION |
+--------+----------+--------+-------------+
| debian | 532fc26c | no     |             |
| ubuntu | 8d39d97e | no     |             |
+--------+----------+--------+-------------+

Once the image is downloaded, you can launch containers based on it:

ubuntu@vlxd:~$ lxc launch debian d1
Creating container...done
Starting container...done
ubuntu@vlxd:~$ lxc launch ubuntu u2
Creating container...done
Starting container...done

Container manipulation

ubuntu@vlxd:~$ lxc list
+------+---------+-----------------------+------+
| NAME |  STATE  |         IPV4          | IPV6 |
+------+---------+-----------------------+------+
| u1   | RUNNING | 10.0.3.105, 127.0.0.1 | ::1  |
| u2   | RUNNING | 10.0.3.78, 127.0.0.1  | ::1  |
| d1   | RUNNING | 127.0.0.1             | ::1  |
+------+---------+-----------------------+------+

ubuntu@vlxd:~$ lxc exec u2 bash
root@u2:~# ping -c 1 10.0.3.105
PING 10.0.3.105 (10.0.3.105) 56(84) bytes of data.
64 bytes from 10.0.3.105: icmp_seq=1 ttl=64 time=0.108 ms

--- 10.0.3.105 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.108/0.108/0.108/0.000 ms
root@u2:~# exit

ubuntu@vlxd:~$ lxc exec u1 -- ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 04:40 ?        00:00:00 /sbin/init
root       399     1  0 04:40 ?        00:00:00 upstart-udev-bridge --daemon
root       433     1  0 04:40 ?        00:00:00 /lib/systemd/systemd-udevd --dae
syslog     547     1  0 04:40 ?        00:00:00 rsyslogd
root       570     1  0 04:40 ?        00:00:00 upstart-file-bridge --daemon
root       571     1  0 04:40 ?        00:00:00 upstart-socket-bridge --daemon
root      1380     1  0 04:40 ?        00:00:00 dhclient -1 -v -pf /run/dhclient
root      1446     1  0 04:40 tty4     00:00:00 /sbin/getty -8 38400 tty4
root      1448     1  0 04:40 tty2     00:00:00 /sbin/getty -8 38400 tty2
root      1449     1  0 04:40 tty3     00:00:00 /sbin/getty -8 38400 tty3
root      1458     1  0 04:40 ?        00:00:00 cron
root      1490     1  0 04:40 console  00:00:00 /sbin/getty -8 38400 console
root      1492     1  0 04:40 tty1     00:00:00 /sbin/getty -8 38400 tty1
root      1530     0  0 04:42 ?        00:00:00 ps -ef

Profiles

Version 0.3 introduces container configuration and profiles. Both are configured using the ‘lxc config’ command. By default, new containers are created with the ‘default’ profile, which has a nic enabled on bridge lxcbr0. You can edit this profile by doing

lxc config profile edit default

which will bring the profile up in an external editor, and update when you save and exit.

To take the default profile out of container u1,

ubuntu@vlxd:~$ lxc config profile list
default
ubuntu@vlxd:~$ lxc config show u1
Profiles: default
ubuntu@vlxd:~$ lxc config profile apply u1
Profile (none) applied to u1
ubuntu@vlxd:~$ lxc config show u1
Profiles:

Now u1 won’t have any nics.

Lets say we want a container to have two nics. We can do this a few ways. We can create a new profile with a second nic, and apply both profiles. We can create a new nic with two nics, and apply only that one. Or we can add the device right to the container, like so:

ubuntu@vlxd:~$ lxc config device add u1 eth1 nic nictype=bridged parent=lxcbr1
Device eth1 added to u1
ubuntu@vlxd:~$ lxc config device list u1
eth1: nic
eth0: nic

I’ve only shown local usage in this post. This means I’ve left out the exciting part – remote usage! I’ll leave that for the next post.

In the meantime, you can get lxd from the above-cited ppa, from the lxd website, or from github.

Posted in Uncategorized | Tagged , , , , | 5 Comments

Introducing lxcfs

Last year around this time, we were announcing the availability of cgmanager, a daemon allowing users and programs to easily administer and delegate cgroups over a dbus interface. It was key to supporting nested containers and unprivileged users.

While its dbus interface turned out to have tremendous benefits (I wasn’t sold at first), there are programs which want to continue using the cgroup file interface. To support use of these in a container with the same delegation benefits of cgmanager, there is now lxcfs.

Lxcfs is a fuse filesystem mainly designed for use by lxc containers. On a Ubuntu 15.04 system, it will be used by default to provide two things: first, a virtualized view of some /proc files; and secondly, filtered access to the host’s cgroup filesystems.

The proc files filtered by lxcfs are cpuinfo, meminfo, stat, and uptime. These are filtered using cgroup information to show only the cpus and memory which are available to the reading task. They can be seen on the host under /var/lib/lxcfs/proc, and containers by default will bind-mount the proc files over the container’s proc files. There have been several attempts to push this virtualization into /proc itself, but those have been rejected. The proposed alternative was to write a library which all userspace would use to get filtered /proc information. Unfortunately no such effort seems to be taking off, and if it took off now it wouldn’t help with legacy containers. In contrast, lxcfs works perfectly with 12.04 and 14.04 containers.

The cgroups are mounted per-host-mounted-hierarchy under /var/lib/lxcfs/cgroup/. When a container is started, each filtered hierarchy will be bind-mounted under /sys/fs/cgroup/* in the container. The container cannot see any information for ancestor cgroups, so for instance /var/lib/lxcfs/cgroup/freezer will contain only a directory called ‘lxc’ or ‘user.slice’.

Lxcfs was instrumental in allowing us to boot systemd containers, both privileged and unprivileged. It also, through its proc filtering, answers a frequent years-old request. We do hope that kernel support for cgroup namespaces will eventually allow us to drop the cgroup part of lxcfs. Since we’ll need to support LTS containers for some time, that will definitely require cgroup namespace support for non-unified hierarchies, but that’s not out of the realm of possibilities.

Lxcfs is packaged in ubuntu 15.04, the source is hosted at github.com/lxc/lxcfs, and news can be tracked at linuxcontainers.org/lxcfs.

In summary, on a 15.04 host, you can now create a container the usual way,

lxc-create -t download -n v1 — -d ubuntu -r vivid -a amd64

The resulting container will have “correct” results for uptime, top, etc.

root@v1:~# uptime
03:09:08 up 0 min, 0 users, load average: 0.02, 0.13, 0.12

It will get cgroup hierarchies under /sys/fs/cgroup:

root@v1:~# find /sys/fs/cgroup/freezer/
/sys/fs/cgroup/freezer/
/sys/fs/cgroup/freezer/user.slice
/sys/fs/cgroup/freezer/user.slice/user-1000.slice
/sys/fs/cgroup/freezer/user.slice/user-1000.slice/session-1.scope
/sys/fs/cgroup/freezer/user.slice/user-1000.slice/session-1.scope/v1
/sys/fs/cgroup/freezer/user.slice/user-1000.slice/session-1.scope/v1/tasks
/sys/fs/cgroup/freezer/user.slice/user-1000.slice/session-1.scope/v1/cgroup.procs
/sys/fs/cgroup/freezer/user.slice/user-1000.slice/session-1.scope/v1/freezer.state
/sys/fs/cgroup/freezer/user.slice/user-1000.slice/session-1.scope/v1/cgroup.clone_children
/sys/fs/cgroup/freezer/user.slice/user-1000.slice/session-1.scope/v1/freezer.parent_freezing
/sys/fs/cgroup/freezer/user.slice/user-1000.slice/session-1.scope/v1/notify_on_release
/sys/fs/cgroup/freezer/user.slice/user-1000.slice/session-1.scope/v1/freezer.self_freezing

And, it can run systemd as init.

Posted in Uncategorized | Tagged , , | 4 Comments

Where does lxd fit in

Since its announcement, there appears to have been some confusion and concern about lxd, how it relates to lxc, and whether it will be taking away from lxc development.

When lxc was first started around 2007, it was mainly a userspace tool – some c code and some shell scripts – to exercise the in-development new kernel features intended for container and checkpoint-restart functionality. The lxc command line experience, after all these years, is quite set in stone. While it is not ideal (the mandatory -n annoys a lot of people), it has served us very well for a long time.

A few years ago, we took all of the main container-related functions which could be done with various commands, and exported them through the new ‘lxc API’. For instance, lxc-create had been a script, and lxc-start and lxc-execute were separate c programs. The new lxc ‘API’ was premised around a container object with methods, including ‘create’ and ‘start’, for the common operations.

From the start we had in mind at least python bindings to the API, and in quick order bindings came into being for C, python3, python2, go, lua, haskell, and more, allowing container administration from these languages without having to shell out to the lxc commands. So now code running on the same machine can manipulate containers. But we still have the arguably crufty command line language, and the API is local only.

lxd addresses those two issues. First, it presents a REST API for manipulating containers, thereby exporting container management over the network. Secondly, it offers a command line client using the REST API to administer containers across remote hosts. The command line API is basically what we came up with when we asked “what, after years of working with containers, would the perfect, intuitive, most concise and still flexible CLI we could imagine?” For handling remote containers it borrows some good parts of the git remote API. (I say “we” here, but really the inestimable stgraber designed the CLI). This allows us to leave the legacy lxc api as-is for administering local containers (“lxc-create”, “lxc-start”, etc), while giving us a nicer API and easier administration using the new CLI (“lxc start c1″, “lxc start images:ubuntu/trusty/amd64 host2:new-container”).

Above all, lxd exports a new interface over the network, but entirely wrapped around lxc. So lxc will not be going away, and focus on lxd will mean further improvements for lxc, not a shift away from lxc.

Posted in Uncategorized | Tagged , | 6 Comments

Live container migration – on its way

The criu project has been working hard to make application checkpoint/restart feasible. Tycho has implemented lxc-checkpoint and lxc-restart on top of that (as well as of course contributing the needed bits to criu itself), and now shows off first steps toward real live migration: http://tycho.ws/blog/2014/09/container-migration.html

Excellent!

Posted in Uncategorized | Tagged , , | Leave a comment

rsync.net feature: subuids

The problem: Some time ago, I had a server “in the wild” from which I
wanted some data backed up to my rsync.net account. I didn’t want to
put sensitive credentials on this server in case it got compromised.

The awesome admins at rsync.net pointed out their subuid feature. For
no extra charge, they’ll give you another uid, which can have its own
ssh keys, whose home directory is symbolically linked under your main
uid’s home directory. So the server can rsync backups to the subuid,
and if it is compromised, attackers cannot get at any info which didn’t
originate from that server anyway.

Very nice.

Posted in Uncategorized | Leave a comment

unprivileged btrfs clones

In 14.04 you can create unprivileged container clones usign overlayfs. Depending on your use case, these can be ideal, since the delta between your cloned and original containers is directly accessible as ~/.local/share/lxc/clonename/delta0/, ready to rsync.

However, that is not my use case. I like to keep a set of original containers updated for quick clone and use by my package build scripts or for manual use for bug reproduction etc. Overlayfs gets in the way here since updating the original container requires making sure no clones exist, else you can cause glitches or corruption in the clone.

Fortunately, if you are using ppa:ubuntu-lxc/daily, or building from git HEAD, then as of last week you can use btrfs clones with your unprivileged containers. This is perfect for me as I can update the originals while a long-running build is on-going in a clone, or if I just want to keep a clone around until i get time to extract the patch or bugfix or log contents sitting there.

So I create base containers using

lxc-create --template download -B btrfs --name c-trusty -- -d ubuntu -r trusty -a amd64

then have create_container and start_container scripts which basically do

lxc-clone --snapshot --orig c-trusty --new c-trusty-5

Perfect.

Posted in Uncategorized | Leave a comment

Xspice in containers

For some time I’ve been wanting to run ubuntu-desktop and others, remotely, in containers, using spice. Historically vnc has been the best way to do remote desktops, but spice should provide a far better experience. Unfortunately, Xspice has always failed for me, most recently segfaulting on startup. But fortunately, this is fixed in git, and I’m told a new release may be coming soon. While waiting for the new release (0.12.7?), I pushed a package based on git HEAD to ppa:serge-hallyn/virt.

You can create a container to test this with as follows:

lxc-create -t download -n desk1 -- -d ubuntu -r trusty -a amd64
lxc-start -n desk1 -d
lxc-attach -n desk1

Then inside that container shell,

add-apt-repository ppa:serge-hallyn/virt
apt-get update
apt-get install xserver-xspice ubuntu-desktop

ubuntu-desktop can take awhile to install. You can simply install fvwm and xterm if you want a quicker test. Once that’s all one, copy the xspice configuration file into your home directory, uncompress it, set the SpiceDisableTicketing option (or configure a password), and use the config file to configure an Xorg session:

cp /usr/share/doc/xserver-xspice/spiceqxl.xorg.conf.example.gz /root
cd /root
gunzip spiceqxl.xorg.conf.example.gz
cat >> spiceqxl.xorg.conf.example.gz << EOF
Option "SpiceDisableTicketing" "1"
EOF
/usr/bin/Xorg -config /root/spiceqxl.xorg.conf.example :2 &

Now fire up unity, xterm, or fvwm:

DISPLAY=:2 unity

Now connect using either spicy or spicec,

spicec -h  -p 5900

Of course if the container is on a remote host, you’ll want to set up some ssh port forwards to enable that, but if needed then that’s a subject for another post.

Posted in Uncategorized | 4 Comments