How to use docker inside docker container in a safe way - docker

I have some docker containers running on my docker environment (on a CentOS VM) which need docker inside. So I mount /var/run/docker.sock inside the containers.
Now I'm creating /etc/default/docker in which I put
DOCKER_OPTS="-H tcp://xx.xx.xx.xx:2376"
But now my question is: which IP is xx.xx.xx.xx? Is it the IP of the host or the IP of a container? + Is this the savest way to let a docker container use the socket? (=use docker in docker)

Running docker within docker is not so trivial an you might have a good reason for doing that.
The last time I was doing that, I was using dind (docker in docker) and had to mount the socket (/var/run/docker.sock) and used it in a combination with the --privileged flag. However things might have changed now (see https://github.com/docker/docker/pull/15596) and it should be able to run it without the socket mount:
docker run --privileged -d docker:dind
So be sure to check out this comprehensive guide at https://hub.docker.com/_/docker/

Working with Docker in Docker can be tricky. I would recommend using the official Docker image with the dind tag. You shouldn't need to specify the DOCKER_HOST in options as it will be correctly configured. For example running:
docker run -ti --name docker -v /var/run/docker.sock:/var/run/docker.sock --privileged docker:dind sh
Will drop you to a shell inside the container. Then if your run docker ps you should see a list of containers running on the host machine. Note the --privileged flag is required in this case as we are accessing the Docker daemon outside the container.
Hope this helps!
Dylan
Edit
Drop the --privileged flag from the above command due to security issues highlighted by Alexander in the comments. You also can drop the dind tag as its not required.

Related

Why would it be necessary to give a docker container access to the docker socket?

I am reading a docker run command where it maps /var/run/docker.sock
like:
docker run -it --net=host --rm -v /var/run/docker.sock:/var/run/docker.sock theimage /bin/bash
Why would the container would need access to the socket? (this article says it is a very bad idea.)
What would be one case where the container need access to the socket?
It is not necessary until the container needs to invoke itself the docker daemon, for example, in order to create and run an inner container.
For example, in my CI chain Jenkins builds a docker image to run the build and test process. Inside it we need to create an image to test and then submit it to K8S. In such situation Jenkins, when builds the pipeline container, passes to it the docker socket to allow the container to create other containers using the host server docker daemon.

Running containers over an Ubuntu container

I need to separate the environments so my team could work without ports conflicts. My idea was to use an ubuntu container to run a lot of other containers and map just the ports we would use, without conflict.
Unfortunately after the Docker installation over the ubuntu container it gives the following error:
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is
the docker daemon running?
Is it possible to use Docker over containers? Does this idea works?
Plus, if this is not the best way to solve the original problem could you please give me a better solution?
First question:
I think you have to bind the docker daemon to your Ubuntu container
-v /var/run/docker.sock:/var/run/docker.sock
Or optional using the official docker image with the DinD flag (docker in docker) which based on Ubuntu 18.09
docker run --privileged --name some-docker -v /my/own/var-lib-docker:/var/lib/docker -d docker:dind
Second question:
Instead of the ubuntu container with docker you could use a reverse proxy in front of your other service containers.
For example traefik or nginx
You can use kubernetes, create multiple namespaces for each developer. Use nginx and dynamic server_name to map url to different namespaces.

Is there a way to start a sibling docker container mounting volumes from the host?

the scenario: I have a host that has a running docker daemon and a working docker client and socket. I have 1 docker container that was started from the host and has a docker socket mounted within it. It also has a mounted docker client from the host. So I'm able to issue docker commands at will from whithin this docker container using the aforementioned mechanism.
the need: I want to start another docker container from within this docker container; in other words, I want to start a sibling docker container from another sibling docker container.
the problem: A problem arises when I want to mount files that live inside the host filesystem to the sibling container that I want to spin up from the other docker sibling container. It is a problem because when issuing docker run, the docker daemon mounted inside the docker container is really watching the host filesystem. So I need access to the host file system from within the docker container which is trying to start another sibling.
In other words, I need something along the lines of:
# running from within another docker container:
docker run --name another_sibling \
-v {DockerGetHostPath: path_to_host_file}:path_inside_the_sibling \
bash -c 'some_exciting_command'
Is there a way to achieve that? Thanks in advance.
Paths are always on the host, it doesn't matter that you are running the client remotely (or in a container).
Remember: the docker client is just a REST client, the "-v" is always about the daemon's file system.
There are multiple ways to achieve this.
You can always make sure that each container mounts the correct host directory
You can use --volumes-from ie :
docker run -it --volumes-from=keen_sanderson --entrypoint=/bin/bash debian
--volumes-from Mount volumes from the specified container(s)
You can use volumes

Why set --privileged for VPN container?

I want to setup a VPN with docker container? I find a popular image mobtitude/vpn-pptp.
This is the start options.
# docker run -d --privileged -p 1723:1723 -v {local_path_to_chap_secrets}:/etc/ppp/chap-secrets mobtitude/vpn-pptp
I am confused why add the --privileged flat.
Some quotes from Docker official references
By default, Docker containers are “unprivileged” and cannot, for example, run a Docker daemon inside a Docker container. This is because by default a container is not allowed to access any devices, but a “privileged” container is given access to all devices (see the documentation on cgroups devices).
When the operator executes docker run --privileged, Docker will enable to access to all devices on the host as well as set some configuration in AppArmor or SELinux to allow the container nearly all the same access to the host as processes running outside containers on the host. Additional information about running with --privileged is available on the Docker Blog.

Delete Docker from Docker?

Is it possible to control (list/start/stop/delete) docker containers from docker container running on the same machine?
The idea/intent is to have docker container which monitors/controls neighbours.
Both low/high level details would be useful.
Thanks!
Yes, the easiest way is to mount the docker socket from the host inside the docker container e.g:
$ docker run -it -v /var/run/docker.sock:/var/run/docker.sock -v $(which docker):/usr/bin/docker debian /bin/bash
root#dcd3b64945ed:/# docker ps -q
dcd3b64945ed
3178d5269041
e59d5e37e0f6
Mounting the docker socket is the easiest however its unsecure as gives the root access to everyone who has access to the docker.sock
Id suggest using the Docker Remote API to do the list/start/stop/etc with a program which hides the docker remote ( in your case local ) daemon .
Ref: https://docs.docker.com/articles/basics/

Resources