Canonical released Ubuntu Core 20 today, and it is now available for download. If you’re already familiar with Ubuntu Core, the standout new feature is added device security with secure boot, full-disk encryption, and secure device recovery baked in. If you’re not familiar with Ubuntu Core yet… read on!
The key difference between regular Ubuntu and Ubuntu Core is the underlying architecture of the system. Traditional Linux distributions rely mostly on traditional package systems—
deb, in Ubuntu’s case—while Ubuntu Core relies almost entirely on Canonical’s relatively new
snap package format.
Ubuntu Core also gets a full 10 years of support from Canonical rather than the five years traditional Ubuntu LTS releases get. But it’s a bit more difficult to get started with, since you need an Ubuntu SSO account to even log in to a new Ubuntu Core installation in the first place.
Before we talk about why getting started might be worth that extra roadblock, we need to do a little homework—so let’s get up to speed on Ubuntu packaging systems first.
What’s an apt, and what’s a deb?
When using the
apt package manager to install a piece of software—such as the
audacity audio editing program—you need to fetch and install not only
audacity itself, but also all of its dependencies. In Audacity’s case, that would include
libavcodec57, and 31 other packages.
If you already have
apt doesn’t need or want to reinstall them, and it doesn’t want to install separate copies just for
audacity‘s sake—these libraries are all installed systemwide, and any
.deb package which depends on them uses that system-wide installation. This cuts down on the amount of disk space used—since you won’t need, for example, a hundred separate copies of
libc6—and it also ensures that any vulnerability only needs to be patched once. If you update
libasound2, you don’t just update them for
audacity, you update them for all installed packages at once.
Once you’ve fetched all 34 of the deb packages comprising Audacity and its dependencies, they’re extracted into lots of files and folders, which are distributed into the correct places around your machine’s filesystem, in
/etc, and so forth.
Let’s talk about snaps
But Ubuntu also has a newer and decidedly different package management system available, called
snap. If we were to install
audacity from a snap, we’d only need to fetch a single file—because each snap is an entirely self-contained system. At its heart, a snap is a compressed, read-only squashfs filesystem; the snap contains both the actual package desired as well as all its dependencies, and they actually run directly from the
squashfs file itself—unlike debs, snaps aren’t expanded and distributed throughout the filesystem.
When you “install” a
snap, you aren’t actually doing a whole lot—the single file you downloaded gets dumped into
/var/lib/snapd/snaps, and a system daemon automatically mounts those snaps—which, remember, are really
/snap as needed. For example, if we
sudo snap install audacity, we can see the following:
me@banshee:~$ ls -lh /var/lib/snapd/snaps | grep audacity
-rw------- 2 root root 118M Feb 2 14:46 audacity_748.snap
me@banshee:~$ mount | grep audacity
/var/lib/snapd/snaps/audacity_748.snap on /snap/audacity/748 type squashfs (ro,nodev,relatime,x-gdu.hide)
nsfs on /run/snapd/ns/audacity.mnt type nsfs (rw)
me@banshee:~$ ls -l /snap/audacity
drwxr-xr-x 9 root root 127 Dec 1 08:57 748
lrwxrwxrwx 1 root root 3 Feb 2 14:46 current -> 748
me@banshee:~$ ls /snap/audacity/current/
bin etc flavor-select lib meta snap usr var
me@banshee:~$ find /snap/audacity -name libasound2
So the actual snap we downloaded is
audacity_748.snap. It’s mounted at
/snap/audacity/748, and the contents of that mountpoint essentially look like a nearly entire miniature Linux filesystem. Within that filesystem-in-a-can, we can also see Audacity’s dependencies, such as libasound2—with the obvious implication that a different snap which also depended on libasound2 would have its own individual copy rather than sharing Audacity’s.
You may have also noticed the
nsfs filesystem at
/run/snapd/ns/audacity.mnt. This is a byproduct of the fact that snaps aren’t just containerized in the sense of their individual squashfs filesystems—their code is also executed inside Linux containers, which minimizes their ability to interact (potentially harmfully) with other running processes they have no business touching.
Putting the Core in Ubuntu Core
Now that we’re thoroughly grounded in
snap packaging, we can talk about what makes Ubuntu Core different from Ubuntu Desktop or Ubuntu Server. In traditional Ubuntu, the vast majority of the system consists of standard
deb packages installed in the root filesystem; while snaps are available, they’re a bit of an afterthought.
In Ubuntu Core, that relationship is turned on its head—to paraphrase the late, great Terry Pratchett, “it’s snaps all the way down.” Even the root filesystem itself is actually a snap and can be upgraded, sidegraded, or downgraded like any optional package would be on a traditional Linux distribution.
This approach brings some significant advantages—since everything’s a snap, everything runs in a container, and (at least theoretically) maximally isolated from everything it has no business touching. Since the default is full containerization, devs have to go out of their way to breach the containers when they need to—in sharp contrast to the traditional Linux way, in which everything gets to touch everything else unless you add SELinux or AppArmor protection layers.
With every package on the system—and the root filesystem itself—in individual read-only squashfs packages, it becomes much more difficult to compromise the system without leaving an incredibly obvious trail of breadcrumbs behind you. You can’t just overwrite the binary for a system library with a malicious version—you need to replace an actual package. And when you do replace it, it won’t be properly signed by the correct vendor… which, itself, gets verified from another immutable snap, which should be signed by Canonical.
snapd also makes maintaining multiple versions of the same package on a system considerably easier. You probably noticed in the last section that
audacity wasn’t just mounted at
/snap/audacity—it was actually mounted at
/snap/audacity/748, with a symlink from
/snap/audacity/748. If we wanted to test a different version of Audacity, we could install it without disturbing our existing version—and we could change which version we wanted to run in practice very simply, using snap channels and tracking.
Let’s take a look at the
info for our Audacity snap, which shows us its available channels:
me@banshee:~$ sudo snap info audacity
summary: Audio software for multi-track recording and editing
publisher: Daniel Llewellyn (diddledan)
Audacity® is a free, easy-to-use, multi-track audio editor and recorder for Windows, Mac OS X,
GNU/Linux and other operating systems. The interface is translated into many languages.
You can use Audacity to:
* Record live audio
* Convert tapes and records into digital recordings or CDs
* Edit WAV, AIFF, FLAC, MP2, MP3 or Ogg Vorbis sound files
* Cut, copy, splice or mix sounds together
* Change the speed or pitch of a recording
* Apply a wide range of other effects to audio recordings
Upstream Project: https://www.audacityteam.org/
snapcraft.yaml Build Definition:
latest/stable: 2.4.2 2020-12-10 (748) 123MB -
latest/candidate: 2.4.2 2020-12-13 (756) 123MB -
latest/edge: 2.4.2 2021-02-01 (779) 195MB -
installed: 2.4.2 (748) 123MB -
Since we didn’t specify a channel when we installed Audacity, we installed the
latest/stable channel by default—#748, which weighed in at 123MiB. What if we want to try out the
latest/edge version instead?
me@banshee:~$ sudo snap refresh audacity --channel=latest/edge
audacity (edge) 2.4.2 from Daniel Llewellyn (diddledan) refreshed
That’s all it takes—if you haven’t already installed
latest/edge, it’s downloaded for you. If you want to switch back, a simple
sudo snap refresh audacity --channel=latest/stable will do it for you—with no additional downloads needed, since the original version you downloaded is actually still there.
Taking this approach to every part of a Linux system means getting an unprecedented amount of modularity, with the ability to rapidly and reliably swap versions of every piece of the system back, forward, and sideways as necessary.
Who actually wants this? Also, are debs going away?
We spent quite some time discussing Ubuntu Core at length with Canonical CTO Gustavo Niemeyer, and this was one of the first things he wanted to make clear—no, traditional Ubuntu and its debs are not going away any time soon. Niemeyer told us that Ubuntu Core isn’t really ready for a traditional desktop experience—and it might not be ready for a lot of “traditional” server workloads, either.
The entirely container-driven approach underneath Ubuntu Core is much, much newer and radically different from the traditional Unix-like layout and workflow most developers, sysadmins, and other *nix nerds are accustomed to, and it takes some finessing to get “just right.” The thing is, Niemeyer told us, “the people who need Ubuntu Core right now already know they need it and are coming to us champing at the bit to get started with it.”
If you’re creating a new generation of IoT or otherwise embedded devices, all of which need to run the same packages in the same general configuration, and receive very predictable upgrades with zero tolerance for shenanigans, the extra hassle of containerizing All The Things looks like a very small price to pay.
A fleet of identical hardware can be expected to respond to fleetwide software upgrades very predictably—especially so, when there isn’t a traditional “upgrade” process that strews files all over a read/write filesystem and can be interrupted in the middle of its process (such as by power outage) with unpredictable results.
OK, so what’s the bad news?
As much as containerized packages like
snap (and the competing
flatpak) have going for them, they’re not perfect. There are those—such as your friendly local Salter—who don’t love the potential snaps create for encouraging lazy developers to continue using outdated, insecure dependencies, since they’re not being forced to keep up with a main system. There can also be some performance hassles, typically revolving around application startup times—we’ve seen the snap version of a complex package such as the Gimp photo editor take four to five times as long as the deb version to launch.
When we brought the application startup issue to Niemeyer, he rather determinedly characterized that as a fixable bug in the individual package in question, not an inescapable flaw of the snap system itself. Today, most applications aren’t designed from the start to be containerized, and it’s easy for developers not to notice nonbreaking bugs—such as trying and failing to reach a directory outside the snap mount, when the failure doesn’t actually crash the app.
There is also a small penalty associated with the compressed nature of the snaps themselves—currently, almost all snaps are
.xz compressed, which results in the smallest possible files, but not the fastest to decompress when needed. But newer versions of
snapd support multiple compression algorithms—so in the future, we can look forward to snaps with slow launch times to be migrated to faster algorithms, such as
In October, Canonical developer advocate Igor Ljubuncic handily demonstrated an excellent example of both the launch-speed penalty and how a shift to faster compression can improve it:
|Chromium startup time||Native package (DEB/RPM)
|Snap with XZ compression
|Snap with LZO compression
System 1—a Kubuntu 18.04 machine—provides, in our opinion, the most useful comparison between native and snap packaging. The initial penalty for a snap-based Chromium “cold launch”—meaning without anything precached in RAM—is a downright appalling 476 percent. Switching the snap from xz to lzo compression brings that down to a far more manageable 182 percent—still noticeably slower, but no longer “oh my god, what’s wrong with your computer?” slower.
We wouldn’t advise making too much of System 3 actually launching faster with the snap than it did natively—that’s a Fedora 32 Workstation, and in my experience, Fedora 32 is noticeably, demonstrably more sluggish to launch applications than Ubuntu is in general.
Is anybody else doing the all-containers thing?
If you’re all-in on containerization, Ubuntu Core isn’t the only way to get where you’re looking to go. Qubes OS is also out there, and it arguably takes things even further—under Qubes, a single machine is effectively a clustered system, with multiple virtual machines serving different roles all tied together beneath the Xen hypervisor.
If Qubes is too far out there for you—or you only want containers, not full-on virtual machines—there’s also Fedora Silverblue. For the most part, Silverblue is to traditional Fedora as Ubuntu Core is to traditional Ubuntu—but based on the more distribution-neutral
flatpak containerized packaging system, rather than Canonical’s
(We want to take a minute to note that
snap is as free for anyone to use, regardless of distribution, as flatpak is. However, there is a common perception outside the Ubuntu ecosystem that the snap system “belongs to Canonical, not to the community,” and that tends to lead—rightly or wrongly—to suspicion or outright hostility from fans of other distributions.)
If you’re a desktop Linux user and want to play with the concept of a fully containerized OS on a desktop platform, Silverblue is currently probably a better fit for you than Ubuntu Core. It is already explicitly designed to be a desktop-friendly distribution—if an avant-garde one—and does not have anything like Ubuntu Core’s vendor-managed SSO requirement to get started.