At Anchore we spend a whole lot of time looking at container images to provide detailed analysis and certification. Most of the discussions we hear in the industry around image analysis focus on CVE scanning: how many CVEs are in an image, what severity, etc. As we’ve mentioned before, we see CVE scanning as just the tip of the iceberg and that it’s possible to have all the latest operating system packages but still have an image that has security vulnerabilities or is otherwise not compliant with your operational, security or business policies.

There is another common issue in the tens of thousands of images that we’ve analyzed which we feel is more fundamental. As an industry we are moving to an architecture based on microservices and containers are really the key to enabling this. While the containers we’ve seen are often designed to run microservices, I’d argue that the majority of containers we see (both on DockerHub as well as our customer’s private images) are more like MicroVMs than Microservices. These images typically have a hundred or more packages and several thousand files.

In most cases, the images are general-purpose operating system images and differ only from their virtual machine brethren by not having a kernel installed. There has been much debate in the industry about image size and how smaller is better, allowing images to be rapidly deployed over the network. Others argue that size doesn’t matter and that the layered nature of Docker’s image format and caching largely mitigates this issue, but looking just at the size of the image doesn’t give you the complete picture.

While it’s certainly an important point to consider the real concern should be not the size of the image, but the content of the images.

Let’s take Alpine as an example. Let’s use the Anchore Navigator to view the contents and select the files tab to drill down further. Filtering this list to show the files in /bin highlights just how many executables are in the image. In a microservice, why does my image need utilities for process or file management? These come from having the busybox package in the image. While that may certainly be useful in some use cases I’d argue that having these kinds of binaries in an image that never directly calls them is an accident waiting to happen. I don’t mean to pick on Alpine which weighs in at 4MB (twenty-five times smaller than most base operating system images and certainly has less attack surface) but the point you must consider is that you must ensure that every artifact in your image serves a purpose and goes through some form of quality control to ensure that the final image is secure and meets your operational best practices.

Last month Oracle released a slimmed down Oracle Linux image which reduced the footprint down from 225MB to 114MB, you can read our analysis here, this week Red Hat upped the ante when they announced a slimmed down Red Hat Enterprise Linux Atomic Base Image.

The new RHEL image weighs in at 75MB, compared to 192MB for the standard RHEL image. In this image, Red Hat has removed a number of packages that are deemed not necessary for container deployments, two of the most interesting removals are systemd and Python. Traditionally all RHEL installs have included python since the YUM package manager is written in Python. To get around this Red Hat has created a new mini package manager called microdnf. While microdnf is not as functional as YUM or as DNF, the next generation package manager for RHEL based distributions, it does just what is needed: install, remove and update packages.

I wanted to look at what else changed in the image so I pulled the RHEL Atomic image from Red Hat’s registry. If you don’t have access to the RHEL registry, you can take a look at the analysis of the image using the Anchore navigator here:

Note: This image is not available publicly on DockerHub.

For the rest of the analysis, I’m going to use Anchore’s command line tools.

First I need to analyze the image.

# anchore analyze --image=registry.access.redhat.com/rhel7-atomic

I’ve already analyzed the standard rhel 7 image so now I want to run a query to compare the packages installed in the RHEL Atomic image with the standard RHEL image using the show-pkg-diffs query.

# anchore query --image=registry.access.redhat.com/rhel7 show-pkg-diffs registry.access.redhat.com/rhel7-atomic

 

PackageRHEL 7RHEL Atomic
python-chardet2.2.1-1.el7_1Not Installed
librhsmNot Installed0.0.1-1.el7
yum-plugin-ovl1.1.31-40.el7Not Installed
libuser0.60-7.el7_1Not Installed
json-glibNot Installed1.0.2-1.el7
python-urlgrabber3.10-8.el7Not Installed
libblkid2.23.2-33.el7Not Installed
audit-libs2.6.5-3.el7_3.1Not Installed
libsolvNot Installed0.6.20-5.el7
xz5.2.2-1.el7Not Installed
file-libs5.11-33.el7Not Installed
rpm-build-libs4.11.3-21.el7Not Installed
python-libs2.7.5-48.el7Not Installed
qrencode-libs3.4.1-3.el7Not Installed
gdbm1.10-8.el7Not Installed
cryptsetup-libs1.7.2-1.el7Not Installed
dbus-libs1.6.12-17.el7Not Installed
tar1.26-31.el7Not Installed
dbus-glib0.100-7.el7Not Installed
cracklib-dicts2.9.0-11.el7Not Installed
kmod20-9.el7Not Installed
systemd219-30.el7_3.7Not Installed
subscription-manager1.17.15-1.el7Not Installed
libpwquality1.2.3-4.el7Not Installed
pygpgme0.3-9.el7Not Installed
python-dmidecode3.10.13-11.el7Not Installed
pyliblzma0.5.3-11.el7Not Installed
device-mapper1.02.135-1.el7_3.3Not Installed
kmod-libs20-9.el7Not Installed
shadow-utils4.1.5.1-24.el7Not Installed
python-pycurl7.19.0-19.el7Not Installed
libcap-ng0.7.5-4.el7Not Installed
python-rhsm-certificates1.17.9-1.el7Not Installed
kpartx0.4.9-99.el7_3.1Not Installed
python-iniparse0.4-9.el7Not Installed
microdnfNot Installed2-3.el7.1.1
pam1.1.8-18.el7Not Installed
cracklib2.9.0-11.el7Not Installed
procps-ng3.3.10-10.el7Not Installed
pyxattr0.5.1-5.el7Not Installed
vim-minimal7.4.160-1.el7_3.1Not Installed
python2.7.5-48.el7Not Installed
python-rhsm1.17.9-1.el7Not Installed
python-ethtool0.8-5.el7Not Installed
cpio2.11-24.el7Not Installed
libutempter1.1.6-4.el7Not Installed
device-mapper-libs1.02.135-1.el7_3.3Not Installed
systemd-libs219-30.el7_3.7Not Installed
dmidecode3.0-2.el7Not Installed
m2crypto0.21.1-17.el7Not Installed
hardlink1.0-19.el7Not Installed
rpm-python4.11.3-21.el7Not Installed
yum-utils1.1.31-40.el7Not Installed
dbus-python1.1.1-9.el7Not Installed
python-dateutil1.5-7.el7Not Installed
librepoNot Installed1.7.16-1.el7
util-linux2.23.2-33.el7Not Installed
usermode1.111-5.el7Not Installed
yum-metadata-parser1.1.4-10.el7Not Installed
pygobject3-base3.14.0-3.el7Not Installed
dracut033-463.el7Not Installed
rootfiles8.1-11.el7Not Installed
ustr1.0.4-16.el7Not Installed
elfutils-libs0.166-2.el7Not Installed
diffutils3.3-4.el7Not Installed
dbus1.6.12-17.el7Not Installed
libuuid2.23.2-33.el7Not Installed
gdb-gdbserver7.6.1-94.el7Not Installed
libmount2.23.2-33.el7Not Installed
libxml2-python2.9.1-6.el7_2.3Not Installed
yum3.4.3-150.el7Not Installed
virt-what1.13-8.el7Not Installed
libdnfNot Installed0.7.4-2.el7.el
libsemanage2.5-5.1.el7_3Not Installed
gzip1.5-8.el7Not Installed
passwd0.79-4.el7Not Installed
python-kitchen1.1.1-5.el7Not Installed
libnl1.1.4-3.el7Not Installed
binutils2.25.1-22.base.el7Not Installed
acl2.2.51-12.el7Not Installed

Here you’ll see there are 80 package differences. Six packages have been added to support the new package manager: librhsm, json-glib, libsolv, microdnf, librepo and libdnf.74 packages have been removed leaving just the minimum set of packages.

Out of interest, I wanted to see how this package list differed from Oracle’s slim image.

PackageOracle Linux SlimRHEL Atomic
python-chardet2.2.1-1.el7_1Not Installed
nss-tools3.21.3-2.0.1.el7_33.21.3-2.el7_3
python-urlgrabber3.10-8.el7Not Installed
libxml22.9.1-6.0.1.el7_2.32.9.1-6.el7_2.3
audit-libs2.6.5-3.el7Not Installed
nss-sysinit3.21.3-2.0.1.el7_33.21.3-2.el7_3
file-libs5.11-33.el7Not Installed
rpm-build-libs4.11.3-21.el7Not Installed
python-libs2.7.5-48.0.1.el7Not Installed
json-glibNot Installed1.0.2-1.el7
gdbm1.10-8.el7Not Installed
nss3.21.3-2.0.1.el7_33.21.3-2.el7_3
pyxattr0.5.1-5.el7Not Installed
yum-plugin-ovl1.1.31-40.el7Not Installed
basesystem10.0-7.0.1.el710.0-7.el7
pygpgme0.3-9.el7Not Installed
coreutils8.22-18.0.1.el78.22-18.el7
shadow-utils4.1.5.1-24.el7Not Installed
python-pycurl7.19.0-19.el7Not Installed
libcap-ng0.7.5-4.el7Not Installed
bash4.2.46-21.0.1.el7_34.2.46-21.el7_3
python-iniparse0.4-9.el7Not Installed
microdnfNot Installed2-3.el7.1.1
librhsmNot Installed0.0.1-1.el7
kernel-container3.10.0-0.0.0.2.el7Not Installed
gobject-introspectionNot Installed1.42.0-1.el7
python2.7.5-48.0.1.el7Not Installed
cpio2.11-24.el7Not Installed
yum-utils1.1.31-40.el7Not Installed
pyliblzma0.5.3-11.el7Not Installed
rpm-python4.11.3-21.el7Not Installed
librepoNot Installed1.7.16-1.el7
yum-metadata-parser1.1.4-10.el7Not Installed
libsolvNot Installed0.6.20-5.el7
ustr1.0.4-16.el7Not Installed
oraclelinux-release7.3-1.0.4.el7Not Installed
diffutils3.3-4.el7Not Installed
redhat-release-server7.3-7.0.1.el77.3-7.el7
libxml2-python2.9.1-6.0.1.el7_2.3Not Installed
yum3.4.3-150.0.1.el7Not Installed
libdnfNot Installed0.7.4-2.el7.el
libsemanage2.5-5.1.el7_3Not Installed
python-kitchen1.1.1-5.el7Not Installed
gpg-pubkeyec551f03-53619141Not Installed

Ignoring the version differences, there are 7 packages in RHEL Atomic not present in the Oracle Slim image which support the new microdnf package manager. There are 28 packages in Oracle Slim that are not in the RHEL Atomic image – unsurprisingly most of these relate to the inclusion of YUM. It will be interesting to see if Oracle Linux and the other RHEL derivatives follow suit and use microdnf in their images.

This is a great step forward for RHEL users, reducing the image size and the attack surface but still leaves a lot of, arguably, unnecessary content in the image. Take a look at the files view in the content tab of the Anchore Navigator for this image here and, as we did for Alpine earlier, filter for /bin to see the utilities and other libraries installed in the image.

At this point, the challenge in reducing the image further is that most of the packages left are required either in whole or more likely in part due to dependencies. For example, you could argue that there is no good reason to have the /bin/chmod command in the image however that is part of the coreutils package which is required by multiple other packages so any further steps forward will require some major changes in packaging.

If you have a Red Hat Enterprise Linux subscription I’d encourage you to check out the new Atomic base image and see how you can reduce the footprint and attack surface of your RHEL based images.

And whether you use RHEL, CentOS, Debian, Ubuntu, Alpine or other distributions you can use Anchore’s image analysis and compliance tools to ensure that the images you deploy meet your security and best practices requirements.