Basics of Docker Networking
I have been wanting to learn some basic networking in Docker and what better way than by building a super simple image from a custom template and inspect the communication between two containers!
The image will just be based on httpd
with some additional tooling.
# base image on Apache HTTP server
FROM httpd
# install additional tooling we will use to debug a bit with
RUN apt-get update && apt-get install -y \
iputils-ping \
inetutils-traceroute \
iproute2 \
curl \
telnet \
dnsutils \
vim
Build it!
docker build --tag httd .
The value passed to
--tag/-t
is actually thename
value, the image will be tagged with the default which is always:latest
, resulting inhttd:latest
.
Beautiful. With this very fresh and very cool image we can start two containers.
docker run --detach --name one dhttp
docker run --detach --name other dhttp
Nothing fancy and mostly default values all around. Inspecting the NetworkSettings
prop for the container of one
feels like a good place to start.
docker container inspect one | jq '.[].NetworkSettings'
I love using
jq
for inspecting or editing JSON strings. If you haven’t heard about it before then check it out!
While the output from inspect
is pretty lengthy, there is not a lot of scary
looking information in there… Of course, some things are going right above my
head but I will just ignore them for now.
I do find some things in the Networks
object interesting though.
docker container inspect one | jq '
.[].NetworkSettings.Networks[]
| { Aliases, IPAddress, Gateway }
'
Aliases
in particular stuck out to me so I looked it up.
--alias
option can be used to resolve the container by another name in the network being connected to.
So aliases are basically host names that will be resolved by Docker within a network. Most people, myself included, have surely used aliases before when using Docker Compose, but getting some deeper knowledge about things is always rewarding. Like seeing these values in the actual container configuration.
Focusing on the Networks
object one can see that one
(heh) belongs to a single
network, bridge
. Let’s see how this looks from the perspective of the network by
inspecting bridge
.
docker inspect bridge | jq '.[] | { Containers, Config: .IPAM.Config }'
From the output we can identify our container IP addresses.
Cool, if we have the IP addresses we can curl them! — You, maybe
Let us put that theory to the test.
curl --connect-timeout 3 <ONE_IP_ADDRESS>
Did it time out? I bet it did. The reason is that containers lives only within
the bridge
network which in turn lives inside of Docker Engine running on our
computer. How in the world would it be able to know where to route requests
heading to <SERVER1_IP_ADDRESS>
?
Happy coding!