Search notes:

Docker networking

Tests to demonstrate some features and characteristics when using networks in Docker.

Prerequisites

We need a Python and busybox image:
$ docker pull python:alpine
$ docker pull busybox

Opening a port, but not listening on it

The following command creates a container. The -p parameter forwards port 8001 to the container:
$ docker run --rm -it --name no-listener -p 8001:8001 busybox /bin/sh
Because there is no process in the container that listens on port 8001, trying to connect to this port from the host with curl results in the error message Recv failure: Connection reset by peer:
$ curl localhost:8001
curl: (56) Recv failure: Connection reset by peer

Opening a port and listening it

The next command creates a container with a webserver listening on port 8001:
$ docker run --rm -it --name listener -p 8001:8001 python:alpine python -m http.server --directory /etc 8001
Because -p 8001:8001 forwards the host's port 8001 to the container's port 8001, we can make a request to the webserver from the host:
$ curl localhost:8001/hostname
7d7872083d8c

Forwarding a port to a different port number

The following command uses -p to forward port 7777 on the host to 8001 in the container:
$ docker run --rm -it --name listener -p 7777:8001 python:alpine python -m http.server --directory /etc 8001
With this forwarding, the webserver can be accessed from the host on port 7777:
$ curl localhost:7777/hostname
6d05678cc3b0

Accessing the host from the container

On the host, we determine the host's IP address used for Docker:
$ ip -br a | grep docker0
docker0          UP             172.17.0.1/16 fe80::42:36ff:fed5:1b8f/64
Then, still on the host, we start a web server:
$ python3  -m http.server --directory /etc 8001
Now, we create a container that accesses the web server running on the host:
$ docker run --rm -it --name client busybox wget -O- -q 172.17.0.1:8001/hostname 

Creating a network

We create a dedicated network for the client and server containers:
$ docker network create -d bridge client-server-network
The server is started with the --network command line option:
$ docker run --rm -it --name http-server --network client-server-network --hostname srv python:alpine python -m http.server --directory /etc 8001
The client is also started with the --network command line option. Note how the client can specify the server by its hostname (srv) which was specified with --hostname when the server was started:
$ docker run --rm -it --name http-client  --network client-server-network busybox wget -O- -q srv:8001/hostname 

Connect from the host to a container in the network

First, we need to determine the IP number of the container running the web server:
$ docker inspect  client-server-network | jq -r '.[] | .Containers | to_entries | .[] | .value | select(.Name == "http-server") | .IPv4Address'
172.18.0.2/16
We're now ready to establish a TCP/IP connection to the container from the host:
$ wget -O- -q 172.18.0.2:8001/hostname
srv

Exposing a container's port to the host

Again, we use the -p option of docker run to specify that a port on localhost is forwared to a container:
$ docker run --rm -it --name http-server-2 --network client-server-network --hostname srv-2 -p 8888:8002 python:alpine python -m http.server --directory /etc 8002
We can now access the container on port 8888 (which is forawrded to port 8002):
$ wget -O- -q localhost:8888/hostname
srv-2

TODO

DNS Server

Containers attached to the default bridge network

The host's /etc/hosts and /etc/resolv.conf files are copied from the host to containers that attach to the default bridge network.

Containers attached to a custom network

Containers that are attached to a custom network use a DNS server that is embedded with Docker which forwards external DNS lookups to the host's configured DNS servers.

Command line options for «docker run»

Command line options for docker run which allow to change this default behavior include:
  • --dns
  • --dns-option
  • --dns-search
  • --hostname

Index