Skip to content

Docker Networking

Alexandru Dan edited this page Nov 6, 2017 · 7 revisions

The docker0 interface is a virtual Ethernet bridge that connects our containers and the local host network. If we look further at the other interfaces on our Docker host, we’ll find a series of interfaces starting with veth.

Every time Docker creates a container, it creates a pair of peer interfaces that are like opposite ends of a pipe (i.e., a packet sent on one will be received on the other):

  • one of the peers of the container becomes eth0 interface
  • other peer gets a unique name (like veth3c6a)

You can think of a veth interface as one end of a virtual network cable. One end is plugged into the docker0 bridge, and the other end is plugged into the container. By binding every veth* interface to the docker0 bridge, Docker creates a virtual subnet shared between the host machine and every Docker container. (thus, every created container gets connected by default to the docker0 network)

root@container:/# traceroute google.com
traceroute to google.com (74.125.228.78), 30 hops max, 60 byte packets

172.17.42.1 (172.17.42.1)  
...

We see that the next hop from our container is the docker0 interface gateway IP 172.17.42.1 on the host network. Docker networking enables this connectivity via firewall rules and NAT configuration.

There is no default access into our containers. We specifically have to open up ports to communicate to them from the host network. We see one example of this in the DNAT, or destination NAT, rule that routes traffic from our container to port 49161 on the Docker host.

Chain DOCKER (2 references)
target prot opt source destination
DNAT tcp 0.0.0.0/0
--
0.0.0.0/0
tcp dpt:49161 to
:172.17.0.18:6379
Docker network connection types

Docker bridge

Default networks

$ docker network ls
NETWORK ID          NAME                DRIVER
7fca4eb8c647        bridge              bridge
9f904ee27bf5        none                null
cf03ee007fb4        host                host

Unless you specify otherwise with the docker run --network=<NETWORK> option, the Docker daemon connects containers to this network by default. The none and host networks are not directly configurable in Docker. However, you can configure the default bridge network, as well as your own user-defined bridge networks.

Containers connected to the default bridge network can communicate with each other by IP address. Docker does not support automatic service discovery on the default bridge network. If you want containers to be able to resolve IP addresses by container name, you should use user-defined networks instead.

You can attach to a running container to see how the network looks from inside the container:

docker attach container1

root@3386a527aa08:/# ip -4 addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
633: eth0@if634: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
    inet 172.17.0.2/16 scope global eth0
       valid_lft forever preferred_lft forever

root@3386a527aa08:/# ping -w3 172.17.0.3
PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.096 ms
64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.080 ms
64 bytes from 172.17.0.3: seq=2 ttl=64 time=0.074 ms

To detach from the container1 container and leave it running, use the keyboard sequence CTRL-p CTRL-q.

User defined networks

You can create a new bridge network, overlay network or MACVLAN network. You can also create a network plugin or remote network for complete customization and control.

Within a user-defined bridge network, linking is not supported. You can expose and publish container ports on containers in this network. This is useful if you want to make a portion of the bridge network available to an outside network. (Note: this seems to work as a FW)

The docker_gwbridge network is always present when you use overlay networks. (used to communicate between hosts)

Overlay networks in swarm mode

You can create an overlay network on a manager node running in swarm mode without an external key-value store. The swarm makes the overlay network available only to nodes in the swarm that require it for a service. When you create a service that uses the overlay network, the manager node automatically extends the overlay network to nodes that run service tasks.

The example below shows how to create a network and use it for a service from a manager node in the swarm:

$ docker network create \
  --driver overlay \
  --subnet 10.0.9.0/24 \
  my-multi-host-network

400g6bwzd68jizzdx5pgyoe95

$ docker service create --replicas 2 --network my-multi-host-network --name my-web nginx

716thylsndqma81j6kkkb5aus

Only swarm services can connect to overlay networks, not standalone containers.

Exposing and publishing ports

In Docker networking, there are two different mechanisms that directly involve network ports: exposing and publishing ports. This applies to the default bridge network and user-defined bridge networks.

  • You expose ports using the EXPOSE keyword in the Dockerfile or the --expose flag to docker run. Exposing ports is a way of documenting which ports are used, but does not actually map or open any ports. Exposing ports is optional.

  • You publish ports using the --publish or --publish-all flag to docker run. This tells Docker which ports to open on the container’s network interface. When a port is published, it is mapped to an available high-order port (higher than 30000) on the host machine, unless you specify the port to map to on the host machine at runtime. You cannot specify the port to map to on the host machine when you build the image (in the Dockerfile), because there is no way to guarantee that the port will be available on the host machine where you run the image.

Docker and iptables

Linux hosts use a kernel module called iptables to manage access to network devices, including routing, port forwarding, network address translation (NAT), and other concerns. Docker modifies iptables rules when you start or stop containers which publish ports, when you create or modify networks or attach containers to them, or for other network-related operations.

Docker dynamically manages iptables rules for the daemon, as well as your containers, services, and networks. In Docker 17.06 and higher, you can add rules to a new table called DOCKER-USER, and these rules will be loaded before any rules Docker creates automatically. This can be useful if you need to pre-populate iptables rules that need to be in place before Docker runs.

IPTables Documentation: https://netfilter.org/documentation/

Other topics

  • Swarm
  • Use a proxy server with containers

Clone this wiki locally