What is /var/run/docker.sock on Docker

0
1903
/var/run/docker.sock on Docker

/var/run/docker.sock is a Unix domain socket. Sockets are used in your favorite Linux distro to allow different processes to communicate with one another. Like everything in Unix, sockets are files, too. In the case of Docker, /var/run/docker.sock is a way to communicate with the main Docker process and, because it’s a file, we can share it with containers.

How it will help on sharing in Container?

When you start Docker and share the socket, you are giving the container the ability to do Docker-like things on the Docker host. Your container can now start or stop other containers, pull or create images on the Docker host, and even write to the host file system. Sharing the Docker socket also makes it possible to use some really great tools.

Docker daemon API

When Docker platform is installed on a host, the Docker daemon listens on the /var/run/docker.sock unix socket by default. This can be seen from the options provided to the daemon, it should contain the following entry:

-H unix:///var/run/docker.sock

Note: additional -H options can be provided to the daemon so it also listens on tcp host/port or on other unix sockets.

All the HTTP endpoints defined in the Docker engine API v1.27 (last version to date), can thus be consumed through this unix socket.

Read More: How to setup Portainer in Linux

Streaming events from the Docker daemon

The Docker API also exposes the /events endpoint that can be used to get a stream of all the events the daemon generates. For instance, this can be used by a load balancer to get the creation/removal events of containers so it can dynamically update its configuration.

Let’s run a simple container and check how we can use Docker daemon events.

Running an Ubuntu container

The following command run an alpine container in interactive mode and bind mount the docker.sock

# docker run -v /var/run/docker.sock:/var/run/docker.sock -ti ubuntu /bin/bash

Listen events from the Docker daemon

From within the alpine container we then send a HTTP request to the /events endpoint through the Docker socket. The command hangs on waiting for new events from the daemon. When events will be generated, they will be streamed from the daemon.

# curl --unix-socket /var/run/docker.sock http://localhost/events

Observe events

We then create a new container based on the nginx image, and we watch, through the alpine container standard output, the events generated by the Docker daemon.

# docker run -p 8080:80 -d nginx

We can observe that several events are received by the previous request.

{
   "status":"pull",
   "id":"nginx:latest",
   "Type":"image",
   "Action":"pull",
   "Actor":
 {
   "ID":"nginx:latest",
   "Attributes":{
   "maintainer":"NGINX Docker Maintainers \u003cdocker-maint@nginx.com\u003e",
   "name":"nginx"
  }
 },
 "scope":"local",
 "time":1514916527,
 "timeNano":1514916527077838645
 }
{
   "status":"create",
   "id":"979984d7dc36dc42939eea0b13374ba9d40d9829236524e18848d70447ee13ae",
   "from":"nginx",
   "Type":"container",
   "Action":"create",
   "Actor":
 {
   "ID":"979984d7dc36dc42939eea0b13374ba9d40d9829236524e18848d70447ee13ae",
   "Attributes":
 {
   "image":"nginx",
   "maintainer":"NGINX Docker Maintainers \u003cdocker-maint@nginx.com\u003e",
   "name":"elegant_chandrasekhar"
  }
 },
 "scope":"local",
 "time":1514916527,
 "timeNano":1514916527101936424
 }
{
  "Type":"network",
  "Action":"connect",
  "Actor":
 {
   "ID":"7b3f8c77349264d9214e85696933fc9e9bc94578022b3a2b0d3731e594b4f283",
   "Attributes":
  {
    "container":"979984d7dc36dc42939eea0b13374ba9d40d9829236524e18848d70447ee13ae",
    "name":"bridge",
    "type":"bridge"
  }
 },
 "scope":"local",
 "time":1514916527,
 "timeNano":1514916527175396848
 }
{ 
   "status":"start",
   "id":"979984d7dc36dc42939eea0b13374ba9d40d9829236524e18848d70447ee13ae",
   "from":"nginx",
   "Type":"container",
   "Action":"start",
   "Actor":
 {
   "ID":"979984d7dc36dc42939eea0b13374ba9d40d9829236524e18848d70447ee13ae",
   "Attributes":
  {
    "image":"nginx",
    "maintainer":"NGINX Docker Maintainers \u003cdocker-maint@nginx.com\u003e",
    "name":"elegant_chandrasekhar"
  }
 },
 "scope":"local",
 "time":1514916527,
 "timeNano":1514916527469276996
 }

Basically, 3 events occurred:

  • creation of the container
  • connection to the default bridge network
  • start of the container

Important…!!!

Bind mounting the Docker daemon socket gives a lot of power to a container as it can control the daemon. It must be used with cautious, and only with containers we can trust.

But How?

you simply need to take some precautions.

  1. Start by looking at which users have the ability to run the Docker command. You should consider them full system admins. Why? Because, as in the example above, users that can run Docker are able to circumvent access control tools like sudo.
  2. When it comes to running containers with access to /var/run/docker.sock, be vigilant with the Dockerfile for the container. You probably got the Dockerfile from someone’s repo on github.com. Look for signs that this is a GitHub project you can trust: active development, good documentation, and stars.
  3. Next take a look at the Dockerfile. Is the base system, the FROM line, one that you would trust? Would you install all the applications in the RUN lines of the Dockerfile on your own system? If you see something like my Dockerfile above, where Docker itself gets installed, know why. (That’s why I used a Dockerfile above instead of a single command.) Do you fully understand each and every line in the Dockerfile? If not, take a look at the command reference. There might even be a few helper shell scripts that get installed, too, and it’s a good idea to take a look at them. Make sure you understand the command line arguments that are being passed to docker run. I’ve covered the -v option here, but you should know what else is going on when you fire up a container. If you see anything mysterious, get a better understanding from the documentation.

Not too distant releases of Docker will probably alleviate some of the risk involved in sharing /var/run/docker.sock with containers. One very promising solution uses namespaces and is in the Docker 1.9.0 experimental build. If you want to know more, here’s a great read on Docker namespaces.

NO COMMENTS