Introduction

Ubuntu released a stable version of Snappy Ubuntu Core on April 21. Snappy Core is a minimalist operating system along the lines of CoreOS and Project Atomic. I've been using Debian and then Ubuntu for a long time now, so I decided to take a look at Ubuntu Snappy Core a while ago, but waited to use do a lot with it until this first stable release.

Ubuntu Snappy Core focuses on two aspects:

  1. Security
  2. Transactional and Reversible Updates

On the security front, the operating system's binaries and library are all in a read-only filesystem. This should make it nearly impossible to put malicious versions of any of the central unix binaries on the system or to modify the kernel in any straightforward way. The other security feature is the use of AppArmor to isolate running software from other processes, as well as manage the security permissions of each process group.

Transactional updates are built into the new package management system, known as snappy. The core operating system is encapsulated in a package called ubuntu-core and a hardware component, which for 64-bit AMD architectures is generic-amd64. These core modules can be updated with the snappy update command and a reboot. The reboot will load the new version of the core operating system, however if there is an issue you can issue a snappy rollback command and boot into the earlier version of the operating system. Both versions of the operating system are stored on the hard drive in separate partitions, to make a rollback quick. On a first boot of a new version of the operating system, snappy core marks that new partition as being in a trial mode, ready to roll back to the other partition if need be. If there is no rollback, the operating system will continue to boot into that partition, if there is a rollback then you will switch back to the old partition.

Very few snappy packages exist right now, however there is a docker docker framework you can load in order to install just about any anything in a safe and isolated way on Snappy Ubuntu Core. The docker framework can be installed with the command snappy install docker. The combination of security, stability, and docker could make this a good operating system for large-scale docker deployments.

Deployment

To experiment on your own system, I recommend using vagrant. Once vagrant is installed, you can start a Snappy Ubuntu Core instance by creating a directory, and running the following commands in that directory:

vagrant init http://cloud-images.ubuntu.com/snappy/15.04/core/stable/current/core-stable-amd64-vagrant.box
vagrant up

You can log in by using the command:

vagrant ssh

For cloud deployments, Snappy Ubuntu Core comes with cloud-init, and can be configured to automatically install docker and allow ssh access with the following user data:

#cloud-config
snappy:
  ssh_enabled: True
  packages:
    - docker

In order to simplify deployment on AWS, I have put together a this cloudformation script which lets you start a Snappy Ubuntu Core server in a VPC and subnet you select. It also allows connections on ports 22, 80, and 443. An EC2 role is also created for the server, but no permissions are granted by default. To use the cloudformation script just save it and upload it to the AWS cloudformation console.

Running Docker Applications

In order to do a little testing, I decided to run two containers on an AWS EC2 t2.micro instance. The first container is the Docker hellobottle image which runs a simple python web service using the Gunicorn WSGI engine and the Bottle web framework. I ran this with the command:

docker run --restart always --name hellobottle -d devries/hellobottle:latest

The second container I ran was an nginx simple reverse proxy container, which will bind to port 80 and forward all requests to port 8080 of a linked container called backend. I ran this with the command

docker run --restart always --name nginx --link hellobottle:backend -d -p 80:80 devries/revproxy:latest

I pointed my browser to the running instance and saw the simple messaging indicating that the devries/hellobottle image was service web pages through the proxy.

Snappy Ubuntu Core has both ssh and python installed, which should allow for management using Ansible. I would also recommend using docker save and docker load to save images for uploading to a Snappy Ubuntu Core instance if you wish to avoid using a Docker repository like hub.docker.com.

I let the containers continue to run, and luckily on June 11th, there was an update, which taught me several things. Updates are run automatically by default by the system-image client. The system-image client will do a daily check for an update of the system image, and will apply that update by default. It should be possible to disable this automatic updating using the command below, but I have not tested it.

system-image-cli --set auto_download=0

The June 11 update went fine. The new ubuntu-core system image was loaded and the system rebooted. The docker containers came back up after reboot and served the web pages without incident, however the next time I attempted to run the docker command I saw the following error:

FATA[0000] Get http:///var/run/docker.sock/v1.18/containers/json: dial unix /var/run/docker.sock: permission denied. Are you trying to connect to a TLS-enabled daemon without TLS?

I tried rebooting again, but that did not fix the problem. I saw in the dmesg log, when I attempted to run the docker command, that apparmor was denying my access:

[   72.230872] audit: type=1400 audit(1434397079.776:12): apparmor="DENIED" operation="connect" info="Failed name lookup - disconnected path" error=-13 profile="docker_docker_1.6.1.002" name="run/docker.sock" pid=1025 comm="docker.x86_64" requested_mask="wr" denied_mask="wr" fsuid=1000 ouid=0

Initially I managed to resolve the issue by using the commands,

sudo snappy remove docker

followed by

sudo snappy install docker

which reinstalled the docker framework. I worried that my docker images would be gone, but they were still present and actually restarted as soon as the docker framework was reinstalled.

I later found a better solution to this problem, which is to use the command:

sudo aa-clickhook -f

to force Snappy Ubuntu Core to rebuild the apparmor permissions cache, which was denying access to the unix socket.

Conclusions

Overall I like this move toward a stripped down operating system for hosting containers. I appreciate Snappy Ubuntu Core's attention to security in particular, and I hope the claims they make are borne out with widespread use. I think the hiccup with the ubuntu-core upgrade affecting permissions on the docker unix socket is the sort of bug we can expect in a first stable release, and I hope that it is fixed soon. I am going to continue to experiment with Snappy Ubuntu Core in development work, but probably will hold off before using it for production workloads.