Alpine Linux is a relative new-comer in terms of Linux distributions, one of several in a recent proliferation of distros tailored for virtualization, containerization and the cloud. As noted on its website, Alpine Linux is “…an independent, non-commercial, general purpose Linux distribution designed for power users who appreciate security, simplicity, and resource efficiency.”
Performance and security being more or less universal goals, Alpine’s self-proclaimed focus is hardly earth-shattering. This particularly in light of the growing number of performance- and security-oriented distros available.
So what makes Alpine different – sufficiently different enough to warrant Docker switching to Alpine for its base images? At first glance, two things stand out:
- Alpine is incredibly compact. The install ISO is around 80MB. Compare this to the 1.2 GB ISO for Fedora Core 24. A working Alpine installation runs from five to twelve megabytes, a fraction of a minimal Fedora Core install, which weighs in at around 1.5 gigabytes.
- Alpine employs busybox to provide much of its userland functionality. Despite being compact, most of the functionality expected of a server-oriented distro is available, with a few notable exceptions. What functionality is lacking can usually be provided via the package management system.
And this brings me to (in my mind) Alpine’s most noteworthy detraction: Another package management system to learn and haggle with.
Under the hood, however, what sets Alpine apart from other distros is its libc implementation. Most distros rely on glibc, the GNU implementation of the Standard C Library, which is packaged as “libc” in UNIX and UNIX-like operating systems (like the BSDs). Since libc (and alternative implementations like glibc) are the de facto API by which userland binaries interact with the kernel, all binaries rely heavily on the local libc implementation.
Alpine Linux foregoes glibc in favor of a newer implementation known as ‘musl’ (pronounced like the freshwater shellfish known as “mussels”). Musl differs significantly from glibc in the following ways:
- Musl strives to be as compliant as possible in terms of standards, and is more ISO and POSIX compliant than glibc.
- Musl minimizes the performance hit inherent in dynamic linking by providing the entire standard library and the linker in a single shared object.
- Musl strives to avoid the use of machine-specific instructions.
- Musl provides the first native Posix threads implementation since NPTL (or the [N]ative [P]osix [T]hread [L]ibrary), which was introduced in RedHat Linux 9.
These are all great things, but do they (corporately speaking) translate into real world benefit? Small image sizes, of course, have a measurable impact on build and deployment pipelines. The other benefits, however (like the improved threads library musl provides) can’t be capitalized upon unless the container host is running Alpine Linux.
That begs the question: how does Alpine stack up next to Ubuntu in terms of performance? Keep your eyes open for my next post, in which we take Alpine and Ubuntu head-to-head in a series of disk and performance benchmarks.