Building Docker images using Kaniko

11/13/20233 min read

Kaniko is a project designed to simplify the process of creating Docker images inside a Docker container. Sometimes you may need an isolated environment for creating images, and using a separate container can help with this.

When run, Kaniko uses your Dockerfile and other project artifacts and builds the image in the same way as if you had run docker build, but does not rely on the Docker daemon. This makes it especially useful for environments where sharing the Docker daemon between build containers, as happens on Jenkins production machines, could pose a security risk.

Kaniko vs DinD

DinD (Docker in Docker) is a technology that allows you to share the Docker host daemon between running containers. This means that it has full access to Docker on the host, and can potentially affect the host machine, which in turn can be very dangerous.

Kaniko is safer in this regard, for the reasons already mentioned above. It does not require access to the host Docker daemon.

On the other hand, Kaniko is primarily useful for creating images, whereas DinD has a wider range of uses, and creating images is only one of them. With DinD, you can perform various tasks such as managing containers on the host and monitoring their status.

Kaniko vs Buildpacks

Buildpacks aims to simplify image creation through highly automated build processes. It doesn't even need a Dockerfile to run the build. Whereas Kaniko, in turn, requires a Dockerfile.

However, this level of automation comes at the cost of a high level of setup complexity. Setting up Buildpacks for non-trivial projects can be not only difficult, but even impossible.

Here Kaniko acts as the golden mean between a high level of automation and complexity of setup.

When to use Kaniko?

Kaniko offers many features to make your tasks easier. It may be useful in the following scenarios:

If you need to dockerize a multi-language project or a monolithic application, Kaniko is the best choice. It allows you to define your Dockerfile exactly the way you need it, giving you the freedom to customize it to suit your requirements. In contrast, other alternatives such as Buildpacks may not offer as much flexibility for customization.

Kaniko runs an isolated build process that does not require access to the Docker daemon. This ensures that your build environment remains secure and does not interfere with other containers, making it a suitable choice when security is a priority.

Application in practice

Let's assume that you needed to build a project image. First, let's create a Dockerfile. After this, you can already create an image using Kaniko. You don't need any additional tools other than Docker itself. Kaniko provides a Docker image that allows you to build your project inside a container with all the necessary build tools pre-installed.

The gcr.io/kaniko-project/executor:v1.14.0 image is used to build your project. The "Executor" is responsible for getting your source code and creating an image from it.

Let's look at a few of the build commands used above:

-v $PWD:/workspace - we mounted the repository with the Dockerfile and project artifacts into the Kaniko container.

--destination - This option specifies the image name and tag. Kaniko can automatically push the final image to the right place.

There are a few more optional options.

In the output above, you can see that the image is being pushed to DockerHub. To make sending possible, you need to provide Kaniko with your credentials.

Now let's move on to the parameters:

--context - this option describes the path to the project directory

--dockerfile is a parameter that specifies the path to the Dockerfile. It may not be in the project directory, but this is a rather unusual case

-v ~/.docker/config.json:/kaniko/.docker/config.json - parameter that allows you to provide your credentials to send the image to the appropriate repository.

Conclusion

Kaniko offers a secure and flexible solution for creating Docker images in isolation.

$ git clone https://github.com/dstar55/docker-hello-world-spring-boot

$cd docker-hello-world-spring-boot

$

$ docker run --rm \

-v $PWD:/workspace\

gcr.io/kaniko-project/executor:v1.14.0\

--destination mylocalregistry:5000/test

$

$ docker run --rm mylocalregistry:5000/test

$ git clone https://github.com/dstar55/docker-hello-world-spring-boot

$cd docker-hello-world-spring-boot

$

$ docker run --rm \

-v $PWD:/workspace\

-v ~/.docker/config.json:/kaniko/.docker/config.json \

gcr.io/kaniko-project/executor:v1.14.0\

--context "/workspace" \

--dockerfile "/workspace/Dockerfile" \

--destination mcsimple/test

$

$ docker run --rm mcsimple/test