RFC: Ubuntu 18.04 LTS Minimal Images
blog.dustinkirkland.com
blog.dustinkirkland.com
CONTAINER ID IMAGE SIZE
493450e7bc12 alpine 1.37MB (virtual 5.52MB)
62b1db90500c ubuntu:bionic 6MB (virtual 87MB)
I deleted the cache files from apt after installing (/var/lib/apt/lists*)Looks quite nice, but it seems Ubuntu packages are much bigger than Alpine package, e.g. Postgres is 159 MB in Ubuntu Bionic and only 32 MB in Alpine (including dependencies). Do the Ubuntu packages have more feature than the equivalent Alpine packages?
The ubuntu package comes with more stuff. e.g. It includes all the 'in tree' PG extensions and their dependencies where as alpine keeps them in a separate package, postgresql-contrib.
typo: libc -> glibc
What happens if you do a multistage build (to get rid of the build tools once you don't need them) and compile Postgres from source on Alpine and Bionic?
Probably makes your total build time significantly longer; you'd need aggressive caching based on the feature flag set.
Specifically the differences in enabling ICU (portable collations) and nls (i.e. translations) alone are probably going to be the majority of difference in installed size.
"The Ubuntu Minimal Image is the smallest base upon which a user can apt install any package in the Ubuntu archive."
"Do you see any other opportunities for savings? Can you help us crop the Bionic Beaver images any further? Is there something that we've culled, that you see as problematic? We're interested in your feedback"
Searching for "cropped beaver images" is going to raise some interesting HR conversations somewhere along the line.
https://a-z-animals.com/animals/beaver/pictures/1724/ For instance.
“To date, we've shaved the Bionic Beaver minimal images down...”
After Artful Aardvark now follows Bionic Beaver.
It wasn't until the first LTS version, dapper drake, that the letters started matching the release number. The second LTS, or 8th release overall - Hardy Heron, in April 2008, was the second "hh" version.
Shockingly we still have 6 hardy heron boxes on our network in far flung locations.
Bison, Beetle, Badger, Baboon, ...
apt update -y
apt install -y telnet
Now you have a 200 MB image.I have used the minimals for years now and they really do give you a pretty decent starter for 10, with a minimum of hassle and a minimum of bloat. Boot the ISO (PXE, obviously) and off you go.
Even doing the install by hand, you get a fully patched basic server up and running within 10-20 minutes - the install is all off the current packages. Add Samba and a few copy n pastes and you have AD joined. A few more copy n pastes from your docs and you have an app server.
I wrote this lot: https://www.mediawiki.org/wiki/Intranet which simply assumes Ubuntu mini at the moment. I do have screenshots and could put together a pretty noddy guide for that bit but I'm not sure its necessary. Actually now I come to think of it, it probably is. Couple that with my Ref. build and you have a domain joined, Kerberized etc app server within about an hour if you do the job by hand and are unfamiliar with the process. I can do it rather quicker.
Yes, the installer is a 30MB image - good. An installer's size is no reflection on the installation size.
EDIT: I am from the sysadmin side of things and not dev ops ...
Twelve years ago, I hired senior sysadmins. About seven years ago, I hired senior devops. Same people, same skill sets, same approach.
It should be as you say but it isn't really. I too hire and fire. To be honest "dev ops" should not really exist but has become a thing. Many who describe themselves as such do not bother with the nuts and bolts. To be fair to them, though, quite a few sysadmins I've known are a bit slack on the networking side, for example. sigh
Take about 4 minutes to build from scratch.
Containers of corse are a different issue, but I'd probably use something like coreos as the host in that case.
base kbd-bkeymaps, xz compressed: 2.8 MB
base kbd-bkeymaps busybox-extras, xz compressed: 2.8 MB
Just 100 kB more for telnet, no extra deps.I wouldn't actually want to work in that chroot but for containers it's fine.
There is something about the way the disk is partitioned that makes the use of virt-resize no longer work (as it does for 16.04).
Specifically, I am referring to: https://cloud-images.ubuntu.com/bionic/20180124/bionic-serve...
The boot partion looks to be sda14 or sda15. But judging from the output of virt-resize, it appears that although these are sda14/15, they appear in front of sda1. (When virt-resize is run on sda1, sda14 becomes sda1, sda15 becomes sda2, and sda1 is now the resized sda3, and grub is confused.
$ virt-filesystems --long --parts --blkdevs -h -a bionic-server-cloudimg-amd64.img
Name Type MBR Size Parent
/dev/sda1 partition - 2.1G /dev/sda
/dev/sda14 partition - 4.0M /dev/sda
/dev/sda15 partition - 106M /dev/sda
/dev/sda device - 2.2G -
$ virt-resize --expand /dev/sda1 bionic-server-cloudimg-amd64.img bionic0.qcow2
$ virt-filesystems --long --parts --blkdevs -h -a bionic0.qcow2
Name Type MBR Size Parent
/dev/sda1 partition - 4.0M /dev/sda
/dev/sda2 partition - 106M /dev/sda
/dev/sda3 partition - 25G /dev/sda
/dev/sda device - 25G -
I am hoping this can be addressed before April, as I would prefer not to maintain my own LTS image (that doesn't have this issue).Also, why are there still motd files in /etc/update-motd.d? No sshd but still a motd? Odd.
You could eliminate this by going through and finding all packages with implicit dependencies on ncurses-bin / ncurses-base, but that seems highly unreliable, and also a huge amount of pain, since Debian probably will not want to drop these packages from Essential (so you will end up maintaining a huge Ubuntu diff).
I could also imagine a scheme where packages in Ubuntu main are scrubbed for these sorts of implicit dependencies, but packages in Ubuntu universe (which is where auto-imports from Debian go) aren't, and apt-get automatically pulls in all Debian "Essential" packages as soon as you try to install something outside main. But that's a good bit of dev work and it's not clear that you'd get a meaningful payoff.
(update-motd.d is from base-files, which is also an essential package, and is actually important; again, possibly Ubuntu could carry a patch to split up base-files, but for < 1kb of text files, it's unclear this is worth doing)
Our ubuntu builds are either 1) On real hardware, in which case it's a network boot which takes an IP address etc, and configured the partitions but allows you to override it (you have to press ok) or 2) On KVM builds, where virt-install is used, network detail is specified on the command line upfront and partitioning is fully automatic.
Thus the majority of debconf settings are either default (a requirement of the package manager is a sensible default), or specified in the preseed file.
[0] https://help.ubuntu.com/community/Installation/MinimalCD
Most recent amd64 minimal image is 58MB ("Artful Aardvark").
Trusty Tahr bzImage compressed kernel is 5.5MB.
The initrd.cpio.gz is 20MB.
The uncompressed initrd is 52MB.
Assuming most of the initrd size is modules, can the Linux user reduce the size of the initrd by compiling own kernel and creating own initrd with only the modules she needs?
If you really do need a kernel, and the few extra MB required by modules is a problem, you should probably be using Buildroot or Yocto for your bootloader/kernel.
These things are a full OS installer ie put it on a USB key, CDROM, PXE boot or whatever. These are a minimal installer and not a minimal installation, although that is a side effect - you don't get much out of the box but you can add everything later.
You could, for example, do a minimal install and then do "# apt install libreoffice" and with luck (not too sure) get the whole lot - X etc - to run it. You might have to add a Window Manager and a few other things.
Also worth noting:these images are full minimal root filesystems. "installer" images refer to the images containing software --the debian/ubuntu installer for bootstrapping a root filesystem onto a mounted volume. The minimal images from thearticle do not contain this installer, and are stanalone root filesystems.
The installs the OP is talking about are images that don't even have a kernel, and don't use the traditional installer.
These things are loaded on every boot, which needs to be fast. That includes both the time to load them into RAM and to decompress them, and it's possible that gzip still wins on that.
Personally, I keep my initrd uncompressed because I've found that on my SSD loading that is faster than loading any compressed version + decompressing it, but that doesn't hold for spinning rust.
It’s why lz4 compression of a file system can be faster than no compression even with an ssd on fast machines; I wonder if that would boost your performance vs the uncompressed image (though I don’t know if the kernel supports lz4 decimal at boot time)?
Doesn't have to be. You could also load it from HDD, which is probably rather common when we're talking about containers and such (and in other circumstances, the couple of MB you'd save here with xz hardly matter). Also there's this PXE thing that I don't understand.
> I wonder if that would boost your performance vs the uncompressed image (though I don’t know if the kernel supports lz4 decimal at boot time)?
It didn't last time I checked, but it seems like it does now. So I'll give that a go.
Though I did figure out that for some reason my system was running "lvm2-monitor.service", which took 1s all by itself for doing absolutely nothing (don't use lvm). So I masked that and gained more time than any compression method could.
I would prefer to manually install build-essentials when needed (I can then get rid of them after compiling via multistage builds).
Alpine Linux specifically makes you manually install compilers and necessary headers via
apk add --update build-base
EDIT: Make is not being installed by default. But I would like to manually install GCC as needed (for a truly minimal image).EDIT2: I stand corrected. Looks like GCC isn't installed by default (which is exactly what we want for minimal images). Awesome.
That's perfect then. Install GCC, compilers, build headers etc via `sudo apt-get install build-essential` when necessary. So this should be the same general approach as on Alpine.
What about adding sshd to the minimal install? If the purpose of this is minimal installs of containers and cloud servers and such, that seems like quite an omission.
- on embedded and some other places where minimal images are used, generating the host key on first run can cause a very significant startup delay.
- on some container environments, environments are so identical that you might not have enough entropy to generate sufficiently unique keys.
- if somebody generates a host key and then creates an image from a running container, then you might end up distributing a host key, making what should be private public.
I've probably got some of these details wrong and am going to be promptly corrected, but there are some very good reasons for excluding sshd.
Plus it's a minimal image, you can build your own intermediate one on top of that with SSH added.
EDIT: I was wrong, this is made to be a container base, not for the nodes themselves (there is no init system)
I currently use packer.io to script the creation of a bunch of server images, and for ubuntu I've missed the "minimal install CD" that other distros have. Instead packer has to download a 800MB CD image, in order to install only a few hundred megabytes of uncompressed packages in a bare-bones install, which is then provisioned using some orchestration tool that at its heart uses ssh to login to the virtual machine.
Not having SSH means you need to add in some sort of serial-attach step to manually install sshd, or hook into the install scripts to download sshd as part of the install or whatever. Either way that's additional custom work that is probably common to a great many use cases.
Your Dockerfile could be something like this:
FROM ubuntu:bionic
RUN sudo apt-get install openssh-server -y && sudo service ssh restart
These are definitely not the complete steps for setting up SSHd but you get the idea.Our server preseed has the following line
d-i pkgsel/include string openssh-server build-essential iperf htop screen sysstat vim-nox
And a couple of internal packages which have their own dependencies (including lldp, snmpd etc) which do a variety of things including user management (active directory based), automatic registration into our asset database and monitoring systems
But the sibling comment about using a Dockerfile to install/start sshd works if you're running these containers on a remote host without any kind of access to the running container.
Now when I need to move my dev environment to another computer (travel), I just copy the home dir, docker build, and I have the exact same environment ready to go.
My dev environment is 100% deterministic, backed up to git, and serves as documentation for what I need installed to do my work. If I find I need something else added, I modify the Dockerfile, commit, rebuild and redeploy. If something messes up my environment, destroy and rebuild is only a couple of commands away.
For anyone interested: https://github.com/kstenerud/docker-desktops
I'm reluctant to get off-topic here, because the narrative relating to the actual post should be "Does it makes sense to have openssh in a minimal ubuntu base image", to which the answer is "No, obviously".
EDIT: Good point, you're right, it has no init system etc and is meant to be used in a container. Point conceded :)
On GKE, one advantage of using Ubuntu as the node OS is you can get access to Sysdig or OpenEBS.
Thinking about it - with Linux KSM the overhead of full-fat containers based on Ubuntu (for example) isn't massive. We may have to look at the metrics I reckon.
(It would be nice to have a one-click tool that builds you a customized image with your own SSH public keys baked in. Ubuntu doesn't have to run this tool - actually there's probably a cool project idea for someone in standing up a little website to do this, either by letting you paste in public keys or grabbing them from the GitHub public API.)
Second reason is that I can't fit more than two hard disks in my laptop, and more than 4 in my desktop.
Third reason is that internal or external hard disks are not exactly cheap in my country. My country sees ridiculously high import duties and retail markup on all electronics.