Tech Topics

Docker Networking

In this blog we’ll talk about network considerations when using Docker with an Elasticsearch cluster. 

Note: In this blog we will reference the Elasticsearch image found on the Docker Hub.
The development and production of this Docker image is not affiliated with Elastic.

You can create your own image by following our recommendation in the blog How to make a Dockerfile for Elasticsearch.

There are different ways to setup networking in Docker and by default three network types are presented. We can list all of them using the following command:

$ docker network ls
NETWORK ID          NAME                DRIVER
d610d782daa0        bridge              bridge              
16a982d835f8        none                null                
7d80e0e91caf        host                host

None Network

It completely disables networking, which is not useful when running an Elasticsearch cluster.

Host Network

If you use --net=host then the container will use the host network and this can be dangerous. It will allow you to change the host network from within the container and if you have an application running as root and it has a vulnerability, there is risk of unsolicited remote control of the host network via the the Docker container. In general we recommend against using it for security reasons, but it can be useful when you need to get the best network performance because it is as fast as normal host networking.

Bridge Network

The bridge network is the default network in Docker.

We can check the details of the default bridge network using the following command:

$ docker network inspect bridge
[
  {
     "Name": "bridge",
     "Id": "b38c312777a0f3890034c9b396669842947b80c9051d10a283c9d43937910578",
     "Scope": "local",
     "Driver": "bridge",
     "IPAM": {
     "Driver": "default",
     "Options": null,
     "Config": [
      {
         "Subnet": "172.17.0.0/16"
      }
    ]
  },
  "Containers": {},
  "Options": {
   "com.docker.network.bridge.default_bridge": "true",
   "com.docker.network.bridge.enable_icc": "true",
   "com.docker.network.bridge.enable_ip_masquerade": "true",
   "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
   "com.docker.network.bridge.name": "docker0",
   "com.docker.network.driver.mtu": "1500"
     }
   }
]

The bridge network name here is docker0. When you add a container, each of them will have its own virtual Ethernet interface connected to the docker bridge docker0 and it will have an IP address allocated to the virtual interface.

This bridge will automatically forward packets between any other network interfaces that are attached to it and also allow containers to communicate with the host machine as well as with the containers on the same host.

By default, Docker containers can make connections to the outside world, they connect via the docker0 interface but the outside world cannot connect to containers.

External connectivity is provided by IP forwarding and iptables rules. You can achieve that using the port mapping.

When running Elasticsearch, you will need to ensure it publishes to an IP address that is reachable from outside the container; this can be configured via the setting network.publish_host.

For the discovery between the nodes you have to configure Zen Discovery via the settings discovery.zen.ping.unicast.hosts and discovery.zen.minimum_master_nodes.

Example:

docker run -d -p 9200:9200 -p 9300:9300 elasticsearch:2 \
        elasticsearch \
            -Des.discovery.zen.ping.unicast.hosts=192.168.99.100,192.168.99.101 \
            -Des.discovery.zen.minimum_master_nodes=2 \
            -Des.network.publish_host=192.168.99.100
docker run -d -p 9200:9200 -p 9300:9300 elasticsearch:2 \
    elasticsearch \
    -Des.discovery.zen.ping.unicast.hosts=192.168.99.100,192.168.99.101 \
    -Des.discovery.zen.minimum_master_nodes=2 \
    -Des.network.publish_host=192.168.99.101

By default, a Docker container is configured to use IPv4 only. It is possible to configure IPv4/IPv6 by starting the Docker daemon with the --ipv6 flag.

When creating a container it will get a link-local IP address. You can also assign a globally routable IPv6 addresses to your containers.

Using routable IPv6 addresses allows you to realize communication between containers on different hosts. The following article provides a lot more information on this subject: Advanced networking.

Overlay Network

In recent versions of Docker they introduced a new type of network called overlay network which Docker recommends for multi-host networking.

To use overlay networking you will need to setup a key-value store so that nodes can be discovered and added to the cluster; Docker currently supports only Consul, etcd, and ZooKeeper.