In this blog, we are going to explore the three different ways and the step involved for implementation on how to run docker in docker.
Docker in Docker as the name implies, running Docker on top of a Docker container. Controlling containers from a Docker container is not a particular use case but is often used in few scenarios as mentioned.
Docker in Docker Use Cases
There are two prominent use cases for Docker-in-Docker:
- The first is to run CI systems such as GitLab or Jenkins on-premises on Docker containers. In this case, you can run Docker containers for each programming language/dependent middleware in the container and then create Docker images for production use, etc. This has the advantage of nested usage of Docker.
- Another common use case is when you want to use Docker as a sandbox environment.
Approaches to Run Docker-in-Docker
There are three major approaches we can use to achieve this
- Run Docker By Mounting docker.sock
- Docker in Docker using dind
- Using Nestybox sysbox Docker runtime
Note: Make sure you have docker installed in your machine to implement these approaches
Docker in Docker Using docker.sock
What is /var/run/docker.sock?
/var/run/docker.sock is the default UNIX Socket. Socket are meant for the communication between the processes running on a host. By default, docker listen to the docker.sock, so we can manage containers with it if we are on the same host where Docker daemon is running.
For Example, we can check the version of Docker with the following command,
curl --unix-socket /var/run/docker.sock http://localhost/version
So with this approach, a container with docker installed does not have its own docker daemon but is connected to the Docker daemon of the host, i.e the Docker CLI in the container and of the host will connect to the same Docker daemon.
Now lets see how we can run docker in docker using this method, all we need to do is mount the sock file of the host in our container where we want to use the Docker Commands
For example, you can use the below command to run docker inside docker
docker run -ti -v /var/run/docker.sock:/var/run/docker.sock docker
You would be able to use docker commands from within the container. But, the major point to note is that as we are using the same daemon as of the host we would be able to see all the images and containers running on the host in our container
docker images
Here, the actual operations happen on the VM host rather than from within the container, meaning that even if are executing the commands from within the container we are instructing the docker client to connect with the docker engine of the VM host through docker.sock. In short, we can say that if you run a container inside the container, this container will actually be a “sibling” to all the containers running on the host machine (including the container in which you are running Docker).
Unfortunately, this can be an issue in certain scenarios, when this container creates more containers, those containers will be created in the top-level Docker. You will not experience nesting side effects, and the build cache will be shared across multiple invocations.
Docker in Docker using dind
This method is useful if you want to overcome the above issue where everyone can access our container, in this approach container and images created inside the container would not be visible from the VM host.
This method is called the dind method, all we need to do is use the official docker image with the dind tag. The dind image is baked with the required utilities for Docker to run inside a docker container. This method actually creates a child container inside a container.
Launch new container using docker image with dind tag(version)
docker run --privileged -d --name dind-test docker:dind
Note: This requires your container to run in --privileged mode Privileged containers in Docker are, concisely put, containers that have all of the root capabilities of a host machine, allowing the ability to access resources that are not accessible in ordinary containers.
Now let’s exec in the container
docker exec -it dind-test /bin/sh
From the above image can observe that no images and containers in this dind container
Within the container now let’s launch a new container
docker run -it --name dind-ubuntu ubuntu
If we go to the host even if we try to find a nested container I mean a container inside the launched container we can’t see or we can’t start that container that is because this dind method completely encapsulated from each other
Using Sysbox To Run Docker in Docker
As described above, both the Docker DinD image and DooD approaches have some important drawbacks, in terms of security because of running the base containers in privileged mode.
Sysbox is an open-source dedicated container runtime that can nest containers without requiring privileged mode.
Nestybox Sysbox runtime offers an alternative solution that overcomes these drawbacks, any Containers created using this are capable of running systemd, docker, and Kubernetes without the need to have the privileged access of the underlying host.
Lets`s take a glimpse at how it works:
- The very first step is to install the Sysbox runtime environment and to do so you can refer to this link.
- Once installed all we need to do now is start a container using your container manager or orchestrator (e.g., Docker or Kubernetes) and an image of your choice, with the sysbox runtime flag.
docker run --runtime=sysbox-runc -it any_image
- Once the container is up and running we can we can start an exec session into the container and start building images as shown in previous steps
docker exec -it <container-name> /bin/bash
Conclusion
In this blog we saw three different ways which can be used to run docker commands in a container, and what can be few use cases and pros and cons of the various methods. But in real-life scenarios, you need to take a few key points into consideration when implementing this
For further details please reach out to us at info@climstech.com