1

Below is the code snippet of jenkins image taken from here:

# Install Docker Engine
RUN apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D && \
    echo "deb https://apt.dockerproject.org/repo ubuntu-trusty main" | tee /etc/apt/sources.list.d/docker.list && \
    apt-get update -y && \
    apt-get purge lxc-docker* -y && \
    apt-get install docker-engine=${DOCKER_ENGINE:-1.10.2}-0~trusty -y && \
    usermod -aG docker jenkins && \
    usermod -aG users jenkins

that installs docker engine within jenkins image. My understanding is, var/run/docker.sock is created withing Jenkins container, due to installation of docker engine.


Below is the volume mapping syntax taken from here:

volumes:
  - jenkins_home:/var/jenkins_home
  - /var/run/docker.sock:/var/run/docker.sock

that launches jenkins container(above) on EC2 host.

EC2 host also has docker daemon running.

So, there is docker daemon running in EC2 host. There is also a docker daemon running within docker container(Jenkins)


With this syntax(/var/run/docker.sock:/var/run/docker.sock) in docker-compose(above) for socket files,

Does docker daemon within Jenkins container override its own socket file with the socket file present in EC2 host? If yes... what is its implication?

rok
  • 9,403
  • 17
  • 70
  • 126
overexchange
  • 15,768
  • 30
  • 152
  • 347

2 Answers2

2

/var/run/docker.sock in the container is the host's Docker socket, and nothing else. This is because:

  1. A Docker container doesn't run any programs other than what's explicitly started in its entrypoint and/or command, and that's almost always just a single application program.
  2. You're presumably not going out of your way to start the Docker daemon, so it's installed but not running.
  3. Unix socket files won't get created until a daemon starts up and it bind(2) a socket to the specific file.
  4. The docker run -v option will always "push" the host's content into the container, and this happens before any of the container processes run.

So in the scenario you're describing, it can't be anything other than the host Docker socket, because there isn't a second Docker daemon.


Let's say for the sake of argument that you actually are starting a second daemon this way.

The order of operations here is (1) Docker sets up the container filesystem, (2) Docker starts running the entrypoint, (3) the entrypoint starts the daemon, (4) the daemon tries to create the socket file. At the point where the daemon starts up, its socket file will already exist. I believe that will cause the bind(2) call to fail with EADDRINUSE, and the daemon won't start up. Hopefully this will cause your container startup to fail.

You could legitimately want to start a daemon in a container, that publishes a Unix socket, that you want to access from the host. To make this work you need to mount a directory into the container, and point the daemon at it. It probably can't be /var/run on either side (there's a lot of stuff in the host /var/run; mounting the directory hides the existing contents in the container and you could want the container's /var/run too). It must be a directory and not a socket filename since Docker will create an empty directory if it doesn't exist; something will exist in the container at that path and the bind will fail.

So if you wanted to start a hypothetical foo daemon inside a container, it would look roughly like

docker run \
  --name foo \                   # container name
  -v $PWD/socket:/socket \       # bind mount a directory
  foo \                          # image name
  food \                         # command to run in the container
    --foreground \               # don't daemonize; keep the container alive
    --bind fd://socket/foo.sock  # put the socket in the shared directory

On the host you'd need to set FOO_SOCKET_PATH=$PWD/socket/foo.sock or otherwise point to this specific file.

David Maze
  • 130,717
  • 29
  • 175
  • 215
1

From the docs:

Docker-engine is a client-server application

Please note that when you install docker-engine you install docker-daemon (server) and docker cli (client).

It means that if a docker daemon isn't running you will still be able run docker cli commands:

docker info
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

Jenkins image you shared doesn't have instructions to run docker engine. So i assume it's not running inside the container.

/var/run/docker.sock:/var/run/docker.sock volume maps docker host's docker engine socket to the container.

So docker cli commands run within the container control the docker-engine running on the docker host.

This makes sense if you do CI/CD on your host from within containerized Jenkins.

Jenkins pipelines may use docker, docker-compose and docker swarm commands to run tests, build artifacts and deploy new versions of applications.

rok
  • 9,403
  • 17
  • 70
  • 126