Going Down the Rabbit Hole of Docker Engine… – dockerd

So you might ask – what does dockerd do? As its turns out, it does quite a lot of thing actually!! Things like networking, logging, docker-swarm, service discovery, DNS implementation, authentication, image management, storage management etc. It also exposes API to listen to requests from docker cli, you know the tool that decides how we interact with docker engine, in our daily lives. Someday these functionalities might be spun off to their own smaller counterparts, but for now these are all the things that dockerd does on a daily basis. Not only this, there are two different versions of docker engine – docker community edition (or docker CE) and docker enterprise edition (or docker EE).

Docker CE, Docker EE and more…

Did we ever discussed that how docker had/have ambitions of establishing Docker Datacenters and was trying hard to do everything using Docker Universal Control Plane and related features. Maybe later.

Here’s some of the features comparison between Docker CE and Docker EE. Some of such features include out of the box FIPS 140-2 compliant engine, enterprise class support with defined SLAs, extended logging features, 24 months of extended support maintenance, certified ecosystem plugins etc.

Image with courtesy of https://www.slideshare.net/Docker/dceu-18-state-of-the-docker-engine

Daemon Socket Options

The dockerd daemon listens for API requests from docker cli on three types of sockets: fd, unix and tcp. By default, a unix domain socket (or IPC socket) is created at /var/run/docker.sock, requiring either root permission, or docker group membership. On windows, it listens using named pipes, //./pipe/docker_engine. Do note that docker daemon can listens to requests either locally or remotely as well. If the dockerd is listening to remote requests, it is advisable to secure communication between the docker cli and it using TLS 1.0 or higher. You can listen on port 2375 on all network interfaces with -H tcp://0.0.0.0:2375, or on a particular network interface using its IP address: -H tcp://192.168.59.103:2375. It is conventional to use port 2375 for un-encrypted, and port 2376 for encrypted communication with the daemon.

Daemon Storage Driver

On Linux, the Docker daemon has support for several different image layer storage drivers: aufs, devicemapper, btrfs, zfs, overlay, overlay2, and fuse-overlayfs. Out of these, aufs (Remember days of LXC…) is the oldest and establish docker for what it is. It is known to cause some serious kernel crashes and eventually lead to development of other storage drivers.

The devicemapper driver uses thin provisioning and Copy on Write (CoW) snapshots. For each devicemapper graph location – typically /var/lib/docker/devicemapper – a thin pool is created based on two block devices, one for data and one for metadata.

The btrfs driver is very fast for docker build – but like devicemapper, it does not share executable memory between devices. 

The zfs driver is probably not as fast as btrfs but has a longer track record on stability. Thanks to Single Copy ARC shared blocks between clones will be cached only once.

The overlay is a very fast union filesystem. It is now merged in the main Linux kernel as of 3.18.0overlay also supports page cache sharing, this means multiple containers accessing the same file can share a single page cache entry (or entries), it makes overlay as efficient with memory as aufs driver.

The overlay2 uses the same fast union filesystem but takes advantage of additional features added in Linux kernel 4.0 to avoid excessive inode consumption.

On Windows, the Docker daemon supports a single image layer storage driver depending on the image platform: windowsfilter for Windows images, and lcow for Linux containers on Windows.

Daemon DNS Options

To set the DNS server for all Docker containers, use:

sudo dockerd --dns 8.8.8.8

To set the DNS search domain for all Docker containers, use:

sudo dockerd --dns-search example.com

Working with Insecure Registries

Docker considers a private registry either secure or insecure. A secure registry uses TLS for all communication and its CA cert is issued by trusted authorities and its in the listed of trusted authorities in dockerd. If an insecure registry is not marked as insecure, docker pulldocker push, and docker search will result in an error message prompting the user to either secure or pass the --insecure-registry flag to the Docker daemon. However, because its use creates security vulnerabilities it should only be enabled for testing purposes. For increased security, users should add their CA to their system’s list of trusted CAs instead of enabling --insecure-registry.

Access Authorization and Authentication

Docker’s access authorization can be extended by authorization plugins that your organization can purchase or build themselves. You can install one or more authorization plugins when you start the Docker daemon using the --authorization-plugin=PLUGIN_ID option. Once a plugin is installed, requests made to the daemon through the command line or Docker’s Engine API are allowed or denied by the plugin. If you have multiple plugins installed, each plugin, in order, must allow the request for it to complete.

Daemon Configuration File

Rather than starting docker daemon or dockerd with various options as discussed above, one can use daemon configuration file to specify custom options. The default location of the configuration file on Linux is /etc/docker/daemon.json. The --config-file flag can be used to specify a non-default location. The default location of the configuration file on Windows is %programdata%\docker\config\daemon.json. The --config-file flag can be used to specify a non-default location.

Below are some of the options available for custom configuration inside config file:

{
  "allow-nondistributable-artifacts": [],
  "api-cors-header": "",
  "authorization-plugins": [],
  "bip": "",
  "bridge": "",
  "cgroup-parent": "",
  "cluster-advertise": "",
  "cluster-store": "",
  "cluster-store-opts": {},
  "containerd": "/run/containerd/containerd.sock",
  "containerd-namespace": "docker",
  "containerd-plugin-namespace": "docker-plugins",
  "data-root": "",
  "debug": true,
  "default-address-pools": [
    {
      "base": "172.80.0.0/16",
      "size": 24
    },
    {
      "base": "172.90.0.0/16",
      "size": 24
    }
  ],
  "default-cgroupns-mode": "private",
  "default-gateway": "",
  "default-gateway-v6": "",
  "default-runtime": "runc",
  "default-shm-size": "64M",
  "default-ulimits": {
    "nofile": {
      "Hard": 64000,
      "Name": "nofile",
      "Soft": 64000
    }
  },
  "dns": [],
  "dns-opts": [],
  "dns-search": [],
  "exec-opts": [],
  "exec-root": "",
  "experimental": false,
  "features": {},
  "fixed-cidr": "",
  "fixed-cidr-v6": "",
  "group": "",
  "hosts": [],
  "icc": false,
  "init": false,
  "init-path": "/usr/libexec/docker-init",
  "insecure-registries": [],
  "ip": "0.0.0.0",
  "ip-forward": false,
  "ip-masq": false,
  "iptables": false,
  "ip6tables": false,
  "ipv6": false,
  "labels": [],
  "live-restore": true,
  "log-driver": "json-file",
  "log-level": "",
  "log-opts": {
    "env": "os,customer",
    "labels": "somelabel",
    "max-file": "5",
    "max-size": "10m"
  },
  "max-concurrent-downloads": 3,
  "max-concurrent-uploads": 5,
  "max-download-attempts": 5,
  "mtu": 0,
  "no-new-privileges": false,
  "node-generic-resources": [
    "NVIDIA-GPU=UUID1",
    "NVIDIA-GPU=UUID2"
  ],
  "oom-score-adjust": -500,
  "pidfile": "",
  "raw-logs": false,
  "registry-mirrors": [],
  "runtimes": {
    "cc-runtime": {
      "path": "/usr/bin/cc-runtime"
    },
    "custom": {
      "path": "/usr/local/bin/my-runc-replacement",
      "runtimeArgs": [
        "--debug"
      ]
    }
  },
  "seccomp-profile": "",
  "selinux-enabled": false,
  "shutdown-timeout": 15,
  "storage-driver": "",
  "storage-opts": [],
  "swarm-default-advertise-addr": "",
  "tls": true,
  "tlscacert": "",
  "tlscert": "",
  "tlskey": "",
  "tlsverify": true,
  "userland-proxy": false,
  "userland-proxy-path": "/usr/libexec/docker-proxy",
  "userns-remap": ""
}

Above listed are only some of the options available for dockerd or docker daemon. A more detailed overview can be found at the https://docs.docker.com/engine/reference/commandline/dockerd.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s