I have been using Distroless containers for a little over a year now, and they're awesome! They're secure, easy to use, and smaller than your average container. So why don't I see them being used more often? Let's take a look!
What is Distroless?
Distroless containers are based off of the Debian container, but they are very different from Ubuntu. First of all, Google manages these containers. That means you can rely on them to mow the lawn, pull the weeds, and remove newly discovered vulnerabilities.
Second difference is there are specific containers for specific languages. As of now, they have dotnet, java, node, rust, and golang (which just runs on the base distroless image). Why have specific containers for specific images? Why not install them all on one container? Besides the size problem, Google has removed 90% of the container and have kept only what is required to run the specific language. This greatly removes the amount of vulnerabilities that can be found in the container. For instance, let's say someone is able to exec into your container and they want to run a command. Guess what? There's no shell. Let's say a vulnerability has been found in a library in Debian. Chances are that the library doesn't exist in Distroless. It would be like if you only used your place of residence for sleeping. You don't need a kitchen, basement, living room, tv, etc. So why pay for a full house? This is how it is when you use a full container for simply running an app.
Advantages of Distroless
As I already mentioned, someone the size of Google is maintaining these containers, so you can bet they are kept up to date. They have publicly said that they use them internally, and just expose them for everyone else. There is a team constantly updating them, so they're going to stick around.
I know some people got a bad taste when I said that these are Google containers. Let me help put your mind at ease.
- Google doesn't install anything on these containers. There's no Google Play Services on these containers. It's open source, so if you want to verify for yourself, have at it.
- I know Google has a reputation of trying things for a while, then just dropping them. While I don't think this would happen (Google has taken security seriously in the past, and they want their own containers to be secure), it is a very easy migration to another container. I was able to just change the base image of my Java application to the OpenJDK image, and run a java command at the end, and it worked just fine. This can also be done if you simply don't want the weighted blanket of Distroless helping you sleep at night anymore. The migration process is very simple.
Disadvantages of Distroless
That all sounds perfect... why aren't they used everywhere? There are some disadvantages.
- You cannot install anything else with your app. You want to install something to assist with some metrics? Sorry, not in this container. Does your security want to install something on everyone's container? Sorry, not here! (is that a disadvantage?) Many of these things can be made up if you host on a PaaS, however.
- One of my biggest issues with Distroless came when attempting to publish to AWS. AWS does not expect to not have a shell in a container, so it's health checks start failing. I'll go into how I fixed this in a future post (stay tuned!)
- You can only use the versions of each language they provide. Do you want to use Java 6? They don't support that. What about Java 14? Sorry, only 8 and 11 are supported right now.
- You can use one and only one language. I came across someone who wanted to use both python and java in the same container. That won't work with distroless!
How to use Distroless?
Using a distroless image is very simple, but it might be a little confusing at first. How can I start a Java app (for example) if I can't run any java commands (it requires a shell to run "java -jar xxx.jar", remember?) Luckily, they have excellent documentation. Here's an example, as well as the links to other examples:
FROM gcr.io/distroless/java:11
COPY ./main.jar /app
WORKDIR /app
CMD ["main.jar"]
The container is set to run the equivalent of "java -jar" already, it just needs the path to your jar in a CMD. Here are the official examples:
Questions? Comments? Concerns? Let me know!
Top comments (0)