Networking before Docker 1.9 release

In this section we are going to look at state of Networking with current Docker release 1.8. More details can be found at Docker Documentation

What happens by default

As soon as you start the Docker daemon, it would create a Linux Brigde (virtual Ethernet bridge) called docker0, that automatically forwards packets between any other network interfaces that are attached to it. As a new container would start, Docker would create a peer of network interfaces and attach one end to the container and other to the bridge docker0.

Docker has some global network configuration options which effects all the containers and some per container configurtion options. Global options are passed to the Docker daemon. Some of the global configuration options are :-

  • -b BRIDGE or --bridge=BRIDGE to use custom bridge
  • --default-gateway=IP_ADDRESS to set the default route for containers
  • --icc=true|false to enable/disable container communication

Visit Docker Documentation for more details.

And the per conatainer options are:-

  • -h HOSTNAME or --hostname=HOSTNAME to set the hostname for container
  • --link=CONTAINER_NAME_or_ID:ALIAS to link the container with other contaiiners
  • --net=bridge|none|container:NAME_or_ID|host to connect the container with differnt namespaces
  • -p SPEC or --publish=SPEC to bind the container with specific port of host
  • -P or --publish-all=true|false to bind all the exposed port from a container to host ports (from ephemeral port range)

--net Networking options

–net=bridge

$ vagrant ssh labvm-1
$ sudo -s
$ ip a
$ docker run -itd centos bash
$ ip a
$ docker ps
$ docker exec -it <ID> ip a
$ vagrant ssh labvm-1
$ sudo -s
$ docker run -itd --name web centos bash
$ docker run -itd --name db mysql bash
$ brctl-show docker0
$ iptabales -t nat -n -L POSTROUTING
$ docker ps
$ docker exec -it web bash
$ tracepath redhat.com

–net=host

With --net=host option, Docker would not create network namespace for the container and would share the namespace of the host.

$ vagrant ssh labvm-1
$ sudo -s
$ ip a
$ ip adocker run -it  centos bash
$ docker run -it  --net=host centos bash
$ ip a

–net=container:NAME_or_ID

With above Docker would also not create new network namespace of container but it would share it with other container. In Kubernetes, a pod can consist of multiple container and it uses --net=container:NAME_or_ID trick to share same namespace among them .

$ vagrant ssh labvm-1
$ sudo -s
$ docker run -itd --name database mysql bash
$ docker exec -it database ip a
$ docker run -it --net=container:database centos  bash
$ ip a

–net=none

With --net=none, Docker would not create any namespace for the container.

$ vagrant ssh labvm-1
$ sudo -s
$ ip adocker run -it --net=none  centos bash
$ ip a

Accessing the container from outside world

In case of –net=host, container can be accessed through host IP. In other cases, if you would like to access the containers from outside, then we can a map host port with the container port and forward the traffic from host to container using iptables.

$ vagrant ssh labvm-1
$ sudo -s
$ docker run -d  -e MYSQL_ROOT_PASSWORD=my-secret-pw  --name=db mysql
$ docker ps
$ docker inspect --format="" db
$ telnet <IP> 3306
$ telnet localhost 3306
$ docker run -d  -e MYSQL_ROOT_PASSWORD=my-secret-pw  --name=db1 -P 3306 mysql
$ docker ps 
$ tenet localhost <PORT>
$ docker run -d  -e MYSQL_ROOT_PASSWORD=my-secret-pw  --name=db2 -p 3306:3306 mysql
$ docker ps
$ telnet localhost 3306
$ iptables -t nat -n -L  DOCKER

Other examples

$ docker run -i -d -p 192.168.1.10::22 --name f20 fedora /bin/bash

We can bind multiple ports on container to hosts ports like following:-

$  docker run -d -i -p 5000:22 -p 8080:80 --name f20 fedora /bin/bash