Connecting containers

Docker provides three kinds of networks to manage communications between containers and the hosts, namely bridge, host, and none:

$ docker network ls
NETWORK ID NAME DRIVER SCOPE
8bb41db6b13e bridge bridge local
4705332cb39e host host local
75ab6cbbbbac none null local

By default, every container is connected to the bridge network upon creation. In this mode, every container is allocated a virtual interface as well as a private IP address, and the traffic going through the interface is bridged to the host's docker0 interface. Containers within the same bridge network can also connect to each other via their IP address. Let's run one container that's feeding a short message over port 5000, and observe its configuration. The --expose flag opens the given ports to the world outside the container:

$ docker run --name greeter -d --expose 5000 busybox 
/bin/sh -c "echo Welcome stranger! | nc -lp 5000"
841138a693d220c92b8634adf97426559fd0ae622e94ac4ee9f295ab088833f5

$ docker exec greeter ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02
inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0
...

Here, the greeter container is allocated to the IP address 172.17.0.2. Now, run another container, connecting to it with this IP address:

$ docker run -t busybox telnet 172.17.0.2 5000
Welcome stranger!
Connection closed by foreign host
The docker network inspect bridge command provides configuration details, such as attached containers, subnet segments, and gateway information.

You can group some containers into one user-defined bridge network. This is the recommended way to connect multiple containers on a single host. The user-defined bridge network slightly differs from the default one, the major difference being that you can access a container from other containers with its name, rather than its IP address. Creating a network is done using the docker network create [NW-NAME] command, and we can attach containers to it by adding the --network [NW-NAME] flag at the time of creation. The network name of a container is its name by default, but it can be given another alias name with the --network-alias flag as well:

## create a network called "room"
$ docker network create room
a59c7fda2e636e2f6d8af5918c9cf137ca9f09892746f4e072acd490c00c5e99
## run a container with the name "sleeper" and an alias "dad" in the room
$ docker run -d --network room
--network-alias dad --name sleeper busybox sleep 60
56397917ccb96ccf3ded54d79e1198e43c41b6ed58b649db12e7b2ee06a69b79
## ping the container with its name "sleeper" from another container
$ docker run --network room busybox ping -c 1 sleeper
PING sleeper (172.18.0.2): 56 data bytes
64 bytes from 172.19.0.2: seq=0 ttl=64 time=0.087 ms


--- sleeper ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.087/0.087/0.087 ms
## ping the container with its alias "dad", it also works
$ docker run --network room alpine ping -c 1 dad
PING dad (172.18.0.2): 56 data bytes
...

The host network works as its name suggests; every connected container shares the host's network, but it loses the isolation property at the same time. The none network is a logically air-gapped box. Regardless of ingress or egress, traffic is isolated inside as there's no network interface attached to the container. Here, we attach a container that listens on port 5000 to the host network and communicates with it locally:

$ docker run -d --expose 5000 --network host busybox 
/bin/sh -c "echo im a container | nc -lp 5000"
a6918174c06f8f3f485913863ed69d4ae838fb550d9f4d66e24ef91534c76b3a
$ telnet localhost 5000
im a container
Connection closed by foreign host
If you are using Docker CE for macOS, the host is the micro Linux on top of the hypervisor framework.

The interaction between the host and the three network modes is shown in the following diagram. Containers in the host and bridge networks are attached with proper network interfaces and communicate with containers within the same network, as well as the outside world, but the none network is kept away from the host interfaces:

Other than sharing the host network, the -p(--publish) [host]:[container] flag, when creating a container, also allows you to map a host port to a container. We don't need attaching a --expose flag together with the --publish flag, as you'll need to open a container's port in any case. The following command launches a simple HTTP server at port 80. You can view it with a browser as well:

$ docker run -p 80:5000 busybox /bin/sh -c 
"while :; do echo -e 'HTTP/1.1 200 OK good day'|nc -lp 5000; done"
$ curl localhost
good day
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset