Posts

Distroless containers for security and size?

Feb 2, 2023
Dmitry Chuyko
16.3

Distroless container images are becoming increasingly popular in cloud-native computing because they make it possible to create both secure and lightweight production container images. Two key benefits of distroless are reduced disc space usage in the clusters and minimized attack surface. But are they truly the optimal solution for your application? Let’s explore.

What is a Distroless Container Image

Distroless image is a type of Docker image that contains only the essential components for running the application. This approach is in line with the modern practices of deploying the application to the cloud in an immutable container, meaning that we have no need for introducing system changes or utilizing libraries not involved in app’s work.

6 questions about distroless and small Linux distros

1. “Is there really no distribution in distroless?”

To set the record straight — distroless images are not distroless.

Although they are served up as ones containing only the application and runtime dependencies without an OS, the only genuinely distroless images are built from scratch. Such OS-less scratch images can be used to run simple statically linked hello-world apps. But the absence of an OS deems running any enterprise-grade application impossible, as there are no

  • Certificate data for proper TLS management;
  • libc for dynamically compiled languages;
  • Necessary components for regular work: timezone, passwd, group folders, etc.

So distroless images do contain a Linux distribution, albeit an incredibly stripped-down one, without a package manager, shell, or other typical Linux components.

2. “Are distroless smaller than traditional Docker images?”

The fact the application relies on the operating system makes it hard to keep the image slim. Let’s take a look at the most popular distroless images produced by GoogleContainerTools (the data is valid as of July 25, 2024):

  • gcr.io/distroless/static-debian12 — 1.9 MB — includes ca-certificates, timezone data, a etc/passwd entry, and a /tmp directory. Statically-linked applications will benefit from this image, but what if your application has dynamic features and requires libc?
  • gcr.io/distroless/base-debian12 — 29.7 MB — is built upon the static image and includes glibc, libssl, and openssl. The image is optimal for dynamically-linked programs, but even in this case, you may require additional shared libraries, which takes us to another level (or layer, for that matter).
  • gcr.io/distroless/cc-debian12 — 32.3 MB — is built upon the base image and includes libgcc1 with dependencies. What about interpreted or VM-based languages (Java, Python, JavaScript)?
  • gcr.io/distroless/java21-debian12 — 192 MB — includes a base Linux image plus OpenJDK (Eclipse Temurin) with dependencies.

The more dynamic your application is, the more OS libraries it needs, so the image size bloats.

Distroless image size

3. “How to debug and configure distroless Docker images effectively?”

Due to the absence of shell access, troubleshooting or profiling distroless images requires mastering additional technologies or techniques. One efficient approach is to use ephemeral containers. These containers can be started at an arbitrary point in time and run temporarily to accomplish some task. They contain shell access and necessary tools for the task at hand: debugging utilities, a profiler, etc.

Ephemeral containers are useful even if you don’t use distroless images, because

  • They enable you to keep that target container clean of auxiliary tools,
  • You don’t have to run the target container with administrator access, which may be unacceptable from the security standpoint.

Ephemeral containers are part of the Kubernetes API, but you can easily spin them up without Kubernetes. For more details, refer to this guide on using ephemeral containers to profile containerized Java applications.

As for the configuration of distroless images, it might be challenging. To adjust Google's images, you need to know bazel, and adding new packages is complicated without a package manager. A limited range of out-of-the-box distroless images increases the risk of the image being incompatible with your app.

If you don’t want to use distroless images, you can save resources by selecting an optimal Linux base image (some modern OSs are similar to or smaller than distroless/base) or mastering at least one Docker container image reduction technique.

4. “Are distroless more secure than regular Docker images?”

It is believed that distroless images are more secure due to smaller attack surface.

The attack surface is a sum of attack vectors, the potentially exploitable paths or scenarios. In other words, it is not about the number of files in your container, but how accessible and vulnerable they are to attacks. Such components as config files, locale, man pages. etc., are less likely to contribute to the attack surface than files sitting in the direct execution path: web servers, libc, encryption modules, etc.

Distroless container images contain a very scarce number of Linux components, including those that might be more accessible to attackers, so they have a smaller track surface than regular Linux distros. But still, there are a few factors to consider if you want to increase the security of your containers:

  • Distroless images are still derived from a Linux distribution. Therefore, they can have nested vulnerabilities. A missed CVE can bear a significant risk of exploits. 
  • Software standardization contributes to enhanced security and accelerated remediation, but it might be challenging with distroless images. The inability to use the same distroless image with the same Linux distro and version for all workloads increases the attack surface.
  • Apart from Linux, the dependencies you use for your project and the runtime for VM-based languages are also associated with security risks. For instance, if you run Java-based workloads, you have to be sure that the OpenJDK distribution in your base image is updated just as regularly as Linux and includes all the latest security patches.

Summarizing, distroless container images have a smaller attack surface. But it is not enough to simply migrate to distroless. To enhance security, regular software updates, standardization, and implementation of modern software security mechanisms such as a Software Bill of Materials (SBOM) are essential to keep your project clean of known vulnerabilities and react to security threats in a timely fashion.    

5. “Can I make my own distroless image?”

If you need a specific distroless container image not supported by providers of distroless images such as Google or Chainguard, you can make your own. To do that, you can use bazel or apko. For more details on building your own distroless images, refer to this article.

6. “What is better, a distroless container image or a small Linux distribution?”

As usual, there’s no one-size-fits-all solution. Distroless may be a perfect solution for some enterprises. They have a good security profile, and if your application fits into the static distroless image, you can reduce disk space usage and network traffic in your clusters. 

However, there is an alternative to distroless container images: minimalistic Linux distributions such as Alpine or Alpaquita. Their base image size is only about 3 MB, but they preserve all core functionalities of Linux. These distributions contain only necessary packages, and others can be pulled from the repository. 

As a result, they provide flexible, configurable environments for virtualization or containers. If for some reason, you don’t want to use distroless images, consider a small Linux distribution that provides a familiar workflow.

How to choose a small Linux distribution

In the section above, we mentioned Alpine and Alpaquita as two minimalistic Linux distros perfect for building small container images. What are the differences between them?

Alpine Linux is a community project, and Alpaquita Linux has both community and LTS versions with technical support from BellSoft. Alpine is based on musl libc, and Alpaquita Linux has versions with both musl and glibc. The glibc-based version is only a few megabytes bigger than the musl-based Alpaquita (3.5 with musl vs 11.5 with glibc). In addition, Alpaquita supports musl perf, an optimized musl implementation to meet or exceed the glibc performance.

The comparison of key Alpine and Alpaquita features can be summarized as follows:

Feature

Alpaquita

Alpine

Free community support

Commercial support

Open source

musl support

default musl

musl perf

default musl

glibc support

License

EULA

GPL2 mostly, MIT for

musl, various licenses for

software components

Platform support

x86_64

AArch64 

x86
x86_64

AArch64 

ARMhf

ARMv7

ppc64le

s390x

GraalVM support

Production-ready Java containers

The picture below shows the comparison of the most widely used Linux distros in terms of size.

Linux container image size

And here is the comparative graph for base Docker images with and without a JDK:

Linux Docker image size with and without JDK

As you can see, you can have a minuscule yet fully functional Linux that can be tailored to your application without inflating the Docker container image.

To make Alpaquita an optimal choice for enterprise applications, we provide LTS Alpaquita releases with a strict update schedule, Security Advisory, and 24/7 commercial support.

How to use distroless with Java

If you decide to try distroless out with your Java application, here’s how you can do that.

We will take Spring Petclinic as an example, but you can use your own project.

Copy the following Dockerfile:

FROM eclipse-temurin:21.0.3_9-jdk-alpine as builder

WORKDIR /home/app
ADD spring-petclinic-main /home/app/spring-petclinic-main
RUN cd spring-petclinic-main && ./mvnw -Dmaven.test.skip=true clean package


FROM gcr.io/distroless/java21-debian12

WORKDIR /home/app
COPY --from=builder /home/app/spring-petclinic-main/target/*.jar petclinic.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/petclinic.jar"]

We use Docker multi-stage builds to build the jar file and then place it into the fresh image. This way, the final image will be free of unnecessary layers.

It is not possible to build an application using a distroless image because shell is needed for that. So, at the first stage, we take a base image with Eclipse Temurin and Alpine. At the final stage, we take Google’s distroless image for Java based on Eclipse Temurin 21 and Debian.

Build the image with the usual command:

docker build -t petclinic-distroless .

Now, check the image size:

docker images
REPOSITORY             TAG       IMAGE ID       CREATED          SIZE
petclinic-distroless   latest    ebb8f2b96dd6   53 seconds ago   263MB

Before we make any conclusions, let’s build another image using Liberica Runtime Container. 

Distroless vs Liberica Runtime Container: compare image sizes

BellSoft’s Liberica Runtime Container is based on Liberica JDK Lite optimized for cloud and Alpaquita Linux.

We will need the following Dockerfile: 

FROM bellsoft/liberica-runtime-container:jdk-21-stream-musl as builder

WORKDIR /home/app
ADD spring-petclinic-main /home/app/spring-petclinic-main
RUN cd spring-petclinic-main && ./mvnw -Dmaven.test.skip=true clean package


FROM bellsoft/liberica-runtime-container:jre-21-musl

WORKDIR /home/app
COPY --from=builder /home/app/spring-petclinic-main/target/*.jar petclinic.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/petclinic.jar"]

Here, we build the project using the base image with Liberica JDK. After that, we copy the resulting jar to a fresh container with Liberica JRE.

Build the image and check its size:

docker build -t petclinic-alpaquita .
docker images
REPOSITORY                                          TAG                                                   IMAGE ID       CREATED             SIZE
petclinic-alpaquita                                 latest                                                325ba5c52e28   7 seconds ago       200MB

As you can see, an image based on Liberica Runtime Container is 63 MB smaller than the distroless-based one!

Conclusion

To sum up, distroless is not a one-size-fits-all solution. Some applications will run with distroless/static, while others may be a perfect fit for distroless/base. In some cases, the complicated workflow and constant image monitoring for vulnerabilities may outweigh the possible pros of distroless. 

A viable alternative to distroless images is to optimize the Docker images by reducing the OS layer and cutting the runtime for VM-based apps.

As a result, distroless images and lightweight Linux distributions for the cloud such as Alpaquita Linux offer excellent opportunities to optimize your containers. Whether your goal is to enhance security, reduce size, or standardize the environments, these tools can make a difference. Visit our Docker Hub repository, choose an image, and start building better containers today!

Go to Alpaquita Linux Docker Hub repository

Subcribe to our newsletter

figure

Read the industry news, receive solutions to your problems, and find the ways to save money.

Further reading