Building Docker Images inside Kubernetes
The Problem
Let’s say that we’re a new team who has been testing and building locally , using docker build, and pushing the images to our Docker registry. We want to put this into a CI/CD system, and so deploy Jenkins on a new Kubernetes cluster (using the Jenkins Kubernetes plugin).
We add a step to run our tests, which works flawlessly. Then we add a step to build a Docker image, but when we run it, and we find that there’s no docker daemon accessible from the Kubernetes container, which means that we can’t build docker images! Let’s investigate some ways that we can fix this problem, and start building Docker images using our CI/CD pipeline.
How image building works
First, it’s important to understand what goes on under the hood when you run docker build using a Dockerfile. Docker will start a container with the base image defined in the FROM directive of the Dockerfile. Docker will then execute everything inside the Dockerfile on that container, and at the end will take a snapshot of that container. That snapshot is the resulting docker image. The only thing that we need from this process is the docker image, so as long as the result is the same a tool can build the docker image in any way it wants, and the implementation doesn’t really matter to us as long as we get the same docker image in the end. Technically we don’t even need a Dockerfile, we can just run commands on a running Docker container and snapshot the results.
The rest of this article is going to explore different ways to generate a Docker image.
Docker out of Docker
With Docker out of Docker we’re essentially connecting the Docker inside of our container to the Docker daemon that the Kubernetes worker uses. The only good reason to use this method is because it’s the easiest to set up. The downsides are that we’re potentially breaking Kubernetes scheduling since we’re running things on Kubernetes but outside of its control. Another downside is that this is a security vulnerability because we need to run our container as privileged and our Jenkins slaves will have access to anything that’s running on the same worker node (which could be a production service if you don’t have a separate cluster for Jenkins)

Here’s a basic configuration for Docker out of Docker:


