Networks#
This section focuses on docker networks in docker.
Check network of container#
It is crucial to obtain the name of the network to which the container is connected. To achieve this, you can use the following command:
docker inspect -f '{{range $key, $value := .NetworkSettings.Networks}}{{$key}} {{end}}' <container name>
The following cell prints the network name for the container just created.
docker run --name network_test -itd alpine &> /dev/null
docker inspect \
-f '{{range $key, $value := .NetworkSettings.Networks}}{{$key}} {{end}}' \
network_test
docker stop network_test &> /dev/null
bridge
Containers connect to the brindge
network by default. As a result we got the message bridge
.
Connect container#
To effectively connect Docker containers to networks, you need to understand the following options:
The
--network <network>
parameter in thedocker run
command, which specifies the network a container should connect to.The
docker network connect <network> <container>
command, used for connecting an existing container to a specified network.The
docker network disconnect <network> <container>
command, used for disconnecting a container from a network.
As an example, let’s look at the test_network
created in the following cell.
docker network create test_network &> /dev/null
The following example shows how to connect the container to the test_network
using the --network
parameter of the docker run command
. It connects a new container to the network and then prints it’s network name corresponding to the container.
docker run -itd --rm \
--network test_network \
--name test_container \
alpine &> /dev/null
docker inspect \
-f '{{range $key, $value := .NetworkSettings.Networks}}{{$key}} {{end}}' \
test_container
test_network
Now, using docker disconnect
, we can disconnect the container from the test_network
. And again - print out the container’s current network.
docker network disconnect test_network test_container
docker inspect \
-f '{{range $key, $value := .NetworkSettings.Networks}}{{$key}} {{end}}' \
test_container
So now we consider that containers simply have no network.
Here is the example of connecting the container back to the network using command docker network connect
.
docker network connect test_network test_container
docker inspect \
-f '{{range $key, $value := .NetworkSettings.Networks}}{{$key}} {{end}}' \
test_container
test_network
So we got test_network
back in the output.
Remove all temporary entities to keep the environment clean.
docker stop test_container &> /dev/null
docker network rm test_network &> /dev/null
Default networks#
For more infomation check specific page.
Docker has three default networks: bridge
, host
, and none
. The following command lists all of them:
docker network ls \
--filter name=bridge \
--filter name=host \
--filter name=none
NETWORK ID NAME DRIVER SCOPE
77a0faf549ac bridge bridge local
80c3e6772c8c host host local
45bb103d970f none null local
Here’s a brief description of each default Docker network:
Bridge: The default network for containers when none is specified. Containers on the same bridge network can communicate with each other using their container names or IP addresses. It provides basic isolation between containers on different bridge networks.
Host: Containers share the host’s network stack and IP address. This means the container will have direct access to the host’s network interfaces and ports, which can be useful for performance but offers less isolation.
None: Disables all networking for the container. Containers on the
none
network cannot communicate with other containers or the outside world, making it suitable for scenarios where networking is not needed.
Containers communication#
There is a way to organise container communication - to be able to send arbitrary messages from one container to another. This section deals with this issue.
Find out more in the specific for this topic page.
We will try to organise client/server communication. The example_client
will try to send requests to the example_server
container.
docker run -itd --name example_client --rm alpine
docker exec example_client apk add curl &> /dev/null
docker run -itd --name example_server --rm kennethreitz/httpbin
b6b0ca6c0bc7be5670b39d224aa683ea5a8c9f261258e36b4c2500552c94fa9a
1bfdf8f7954f5d15a8edfb8a0f3154f583f2422ce96b537e20e00a5191efe3db
Even considering that, by default, the created containers are on the same docker network. Messages from one container will not pass to another container. The following cell shows it.
docker exec example_client curl -s example_server
Note you can access exaple_server
by using it’s ip instead of the name. Check “Communicating by IP” section.
We need to connect both containers to the same custom network to make it all work.
docker network create test_network &> /dev/null
docker network connect test_network example_server
docker network connect test_network example_client
That’s all we needed, no ports required. Using just the container name we can access example_server
from example_client
. The following cell shows exact option.
docker exec example_client curl -s example_server/anything
{
"args": {},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Host": "example_server",
"User-Agent": "curl/8.9.0"
},
"json": null,
"method": "GET",
"origin": "172.18.0.3",
"url": "http://example_server/anything"
}
Clean it all up.
docker stop example_client example_server
docker network rm test_network
example_client
example_server
test_network
Network interfaces#
Each container creates it’s own network interface. To list information about network interfaces in linux you have to use ifconfig
command.
In the following cell we first printed the ifconfig
result without specifying any containers, then started a few containers and ran ifconfig
again.
echo "=====before creating a container====="
ifconfig -s | awk '{print $1}'
for i in {1..4}; do docker run --rm -d --name test_nginx$i nginx; done &> /dev/null
echo "=====after creating a container====="
ifconfig -s | awk '{print $1}'
docker stop test_nginx{1..4} &> /dev/null
=====before creating a container=====
Iface
docker0
eno1
lo
wlp0s20f
=====after creating a container=====
Iface
docker0
eno1
lo
veth0cb1
veth795d
vethc33d
vethc6d4
wlp0s20f
The second ifconfig
we got more network interfaces.
Internal ip address#
Each docker container has an internal ip address on the host machine. You can use this to access the container. Use docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container name>
to get container’s ip.
The following cell starts a docker container with a python http server. Stores the container’s ip in the server_ip
variable and prints it out.
docker run --rm -itd -p 12345:12345 --name http_serv python:3.12 \
python3 -m http.server 12345
server_ip=$(
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' http_serv
)
echo $server_ip
49f56ecb03e566f8d1b144513a229b5aaefa52aae952658d96e295788a630496
172.17.0.2
Now access to the server via the container’s ip in the host.
curl $server_ip:12345
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Directory listing for /</title>
</head>
<body>
<h1>Directory listing for /</h1>
<hr>
<ul>
<li><a href=".dockerenv">.dockerenv</a></li>
<li><a href="bin/">bin@</a></li>
<li><a href="boot/">boot/</a></li>
<li><a href="dev/">dev/</a></li>
<li><a href="etc/">etc/</a></li>
<li><a href="home/">home/</a></li>
<li><a href="lib/">lib@</a></li>
<li><a href="lib64/">lib64@</a></li>
<li><a href="media/">media/</a></li>
<li><a href="mnt/">mnt/</a></li>
<li><a href="opt/">opt/</a></li>
<li><a href="proc/">proc/</a></li>
<li><a href="root/">root/</a></li>
<li><a href="run/">run/</a></li>
<li><a href="sbin/">sbin@</a></li>
<li><a href="srv/">srv/</a></li>
<li><a href="sys/">sys/</a></li>
<li><a href="tmp/">tmp/</a></li>
<li><a href="usr/">usr/</a></li>
<li><a href="var/">var/</a></li>
</ul>
<hr>
</body>
</html>
docker stop http_serv
http_serv