docker create --name whoami traefik/whoami
Unable to find image 'traefik/whoami:latest' locally
latest: Pulling from traefik/whoami
24f325000f63: Pull complete
13615ce8532d: Pull complete
3f914992e3e0: Pull complete
Digest: sha256:200689790a0a0ea48ca45992e0450bc26ccab5307375b41c84dfc4f2475937ab
Status: Downloaded newer image for traefik/whoami:latest
330532585f966bc24ca2f76b1d811fd028404b504205a4769f542033ffbe5dea
docker start whoami
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
330532585f96 traefik/whoami "/whoami" 16 seconds ago Up 1 second 80/tcp whoami
On note qu'un port est indiqué, essayons de l'interroger
curl http://127.0.0.1:80
curl: (7) Failed to connect to 127.0.0.1 port 80 after 0 ms: Could not connect to server
Quelle est donc l'ip a interroger ? Inspectons le container:
docker inspect whoami
[
{
"Id": "330532585f966bc24ca2f76b1d811fd028404b504205a4769f542033ffbe5dea",
"Created": "2025-11-09T07:52:11.688094916Z",
"Path": "/whoami",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 13593,
"ExitCode": 0,
"Error": "",
"StartedAt": "2025-11-09T07:52:25.381332702Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
...
...
"NetworkSettings": {
"Bridge": "",
"SandboxID": "e6307dd1daf2d47c04266cb786c4bae2acb7511d4da4729870d264c7af8b2748",
"SandboxKey": "/var/run/docker/netns/e6307dd1daf2",
"Ports": {
"80/tcp": null
},
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "8e82835620c9e1a2b9b2b62e876f53c0cb6e27869b9fefa01060dc73e92dd5d6",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "5a:de:2b:01:83:20",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"MacAddress": "5a:de:2b:01:83:20",
"DriverOpts": null,
"GwPriority": 0,
"NetworkID": "9dc8014e58e3869d83390d9e70046344a8e7c588e7ac1176c9a95fe1a65be808",
"EndpointID": "8e82835620c9e1a2b9b2b62e876f53c0cb6e27869b9fefa01060dc73e92dd5d6",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"DNSNames": null
}
}
}
}
]
Ou pour avoir un résultat plus concis, mais nécessitant de connaitre la structure du json:
docker inspect --format '{{ .NetworkSettings.IPAddress }}' whoami
172.17.0.2
On peu maintenant interroger le container:
curl http://172.17.0.2:80
Hostname: 330532585f96
IP: 127.0.0.1
IP: ::1
IP: 172.17.0.2
RemoteAddr: 172.17.0.1:60450
GET / HTTP/1.1
Host: 172.17.0.2
User-Agent: curl/8.14.1
Accept: */*
docker network list
NETWORK ID NAME DRIVER SCOPE
9dc8014e58e3 bridge bridge local
9e5fb4f7e1cf host host local
131587c55590 none null local
docker network inspect bridge
[
{
"Name": "bridge",
"Id": "9dc8014e58e3869d83390d9e70046344a8e7c588e7ac1176c9a95fe1a65be808",
"Created": "2025-11-09T07:19:43.960001885+01:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv4": true,
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"330532585f966bc24ca2f76b1d811fd028404b504205a4769f542033ffbe5dea": {
"Name": "whoami",
"EndpointID": "8e82835620c9e1a2b9b2b62e876f53c0cb6e27869b9fefa01060dc73e92dd5d6",
"MacAddress": "5a:de:2b:01:83:20",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]
Effacer le container
docker network create net01
docker network list
NETWORK ID NAME DRIVER SCOPE
9dc8014e58e3 bridge bridge local
9e5fb4f7e1cf host host local
e5d89b063e11 net01 bridge local
131587c55590 none null local
Demarrons le container whoami sur ce nouveau réseau:
docker create --name whoami --hostname whoami --network net01 traefik/whoami
Recherche de l'ip du container:
docker inspect whoami | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAddress": "172.18.0.2",
Test d'interrigation:
curl http://172.18.0.2:80
Hostname: whoami
IP: 127.0.0.1
IP: ::1
IP: 172.18.0.2
RemoteAddr: 172.18.0.1:52544
GET / HTTP/1.1
Host: 172.18.0.2
User-Agent: curl/8.14.1
Accept: */*
Le mapping permet d'exposé sur l'adresse du host un service exposé sur un reseau interne Docker
Dans l'exemple ont expose sur le port 12345 le service exposé par whoami sur le port 80
docker run -d --name whoami --hostname whoami --network net01 -p 12345:80 traefik/whoami
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bb63c1599c8e traefik/whoami "/whoami" 6 seconds ago Up 5 seconds 0.0.0.0:12345->80/tcp, [::]:12345->80/tcp whoami
On note un changement du type d'informations concernant les ports
0.0.0.0:12345->80/tcp : Indique que le port 80 du container est exposé sur le host (IP V4) en port 12345
[::]:12345->80/tcp: Même chose en IP V6
curl http://127.0.0.1:12345
Hostname: whoami
IP: 127.0.0.1
IP: ::1
IP: 172.18.0.2
RemoteAddr: 172.18.0.1:47116
GET / HTTP/1.1
Host: 127.0.0.1:12345
User-Agent: curl/8.14.1
Accept: */*
ou encore:
curl http://tuto01.bv.stef.lan:12345
Hostname: whoami
IP: 127.0.0.1
IP: ::1
IP: 172.18.0.2
RemoteAddr: 192.168.200.26:53094
GET / HTTP/1.1
Host: tuto01.bv.stef.lan:12345
User-Agent: curl/8.14.1
Accept: */*
L'interrogation de l'url http://192.168.200.26:12345 via navigateur externe retourne ceci:
Hostname: whoami
IP: 127.0.0.1
IP: ::1
IP: 172.18.0.2
RemoteAddr: 192.168.1.55:54800
GET / HTTP/1.1
Host: tuto01.bv.stef.lan:12345
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: fr-FR,fr;q=0.9
Connection: keep-alive
Cookie: tinyauth-session-8d858b75=MTc2MjY2NjYyMHxEWDhFQVFMX2dBQUJFQUVRQUFEXzlQLUFBQWNHYzNSeWFXNW5EQW9BQ0hWelpYSnVZVzFsQm5OMGNtbHVad3dHQUFSemRHVm1Cbk4wY21sdVp3d0dBQVJ1WVcxbEJuTjBjbWx1Wnd3R0FBUlRkR1ZtQm5OMGNtbHVad3dIQUFWbGJXRnBiQVp6ZEhKcGJtY01FZ0FRYzNSbFprQmlkaTV6ZEdWbUxteGhiZ1p6ZEhKcGJtY01DZ0FJY0hKdmRtbGtaWElHYzNSeWFXNW5EQW9BQ0hWelpYSnVZVzFsQm5OMGNtbHVad3dJQUFabGVIQnBjbmtGYVc1ME5qUUVCZ0Q4MGlMei1BWnpkSEpwYm1jTURRQUxkRzkwY0ZCbGJtUnBibWNFWW05dmJBSUNBQUFHYzNSeWFXNW5EQTBBQzI5aGRYUm9SM0p2ZFhCekJuTjBjbWx1Wnd3Q0FBQT18XiizdKPHjoetYpG35bmCzuiifOptjHk5-uKG1t3uWcw=
Sec-Gpc: 1
Upgrade-Insecure-Requests: 1
La création du reseau docker net01 a généré une interface reseau virtuel sur l'host Docker , cette interface permet l'interconnexion au reseau 172.18.0.0/16 ( net01 )
Details de l'interface
ip a
26: br-e5d89b063e11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 9e:5a:c8:e7:5f:b3 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.1/16 brd 172.18.255.255 scope global br-e5d89b063e11
valid_lft forever preferred_lft forever
inet6 fe80::9c5a:c8ff:fee7:5fb3/64 scope link proto kernel_ll
valid_lft forever preferred_lft forever
ip link
26: br-e5d89b063e11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
Table de routage
ip r
default via 192.168.200.254 dev enp1s0 proto dhcp src 192.168.200.26 metric 1002
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
172.18.0.0/16 dev br-e5d89b063e11 proto kernel scope link src 172.18.0.1
192.168.200.0/24 dev enp1s0 proto dhcp scope link src 192.168.200.26 metric 1002
Règles de NAT netfilter
iptables -t nat -L -v
Chain PREROUTING (policy ACCEPT 39 packets, 2383 bytes)
pkts bytes target prot opt in out source destination
2 112 DOCKER all -- any any anywhere anywhere ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 143 packets, 11838 bytes)
pkts bytes target prot opt in out source destination
1 60 DOCKER all -- any any anywhere !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT 145 packets, 11950 bytes)
pkts bytes target prot opt in out source destination
0 0 MASQUERADE all -- any !br-e5d89b063e11 172.18.0.0/16 anywhere
38 2323 MASQUERADE all -- any !docker0 172.17.0.0/16 anywhere
Chain DOCKER (2 references)
pkts bytes target prot opt in out source destination
0 0 RETURN all -- br-e5d89b063e11 any anywhere anywhere
0 0 RETURN all -- docker0 any anywhere anywhere
2 112 DNAT tcp -- !br-e5d89b063e11 any anywhere anywhere tcp dpt:12345 to:172.18.0.2:80
C'est, entre autre ce que simplifie Docker bien que l'ensemble des fonctions permettant de crée des applications isolé de l'os existe dans linux depuis longtemps, la gestion des switchs virtuels, routage et autres regles netfilter devait être fait manuelment avant ce qui etait assez fastidieux.
Il est possible d'attacher plusieurs réseaux à un mème container
docker rm -f whoami
docker network create net02
docker create -ti --name testreseau --hostname testreseau --network name=net01,gw-priority=1 --network net02 almalinux
docker start testreseau
docker exec -ti testreseau bash
[root@testreseau /]# dnf install iproute -y
[root@testreseau /]# ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host proto kernel_lo
valid_lft forever preferred_lft forever
2: eth0@if48: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether aa:90:ce:2d:dc:08 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
valid_lft forever preferred_lft forever
3: eth1@if49: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether d2:84:c0:53:1a:f1 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.19.0.2/16 brd 172.19.255.255 scope global eth1
valid_lft forever preferred_lft forever
Nous allons creer un autre container connecté sur le reseau net02
Les containers connecté à un meme réseau peuvent utiliser leurs noms pour communiquer entre eux ( pas forcement besoin de spécifier le hostname )
docker run -ti --name testreseau2 --network net02 almalinux
[root@testreseau2 /]# ping -c 1 testreseau
PING testreseau (172.19.0.2) 56(84) bytes of data.
64 bytes from testreseau.net02 (172.19.0.2): icmp_seq=1 ttl=64 time=0.165 ms
--- testreseau ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.165/0.165/0.165/0.000 ms
docker network disconnect net02 testreseau
docker exec -ti testreseau ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host proto kernel_lo
valid_lft forever preferred_lft forever
2: eth0@if48: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether aa:90:ce:2d:dc:08 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
valid_lft forever preferred_lft forever
docker network connect net02 testreseau
docker exec -ti testreseau ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host proto kernel_lo
valid_lft forever preferred_lft forever
2: eth0@if48: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether aa:90:ce:2d:dc:08 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
valid_lft forever preferred_lft forever
4: eth1@if56: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether aa:ac:e8:ff:e5:39 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.19.0.2/16 brd 172.19.255.255 scope global eth1
valid_lft forever preferred_lft forever
docker exec -ti testreseau2 ping -c 1 testreseau
PING testreseau (172.19.0.2) 56(84) bytes of data.
64 bytes from testreseau.net02 (172.19.0.2): icmp_seq=1 ttl=64 time=0.173 ms
--- testreseau ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.173/0.173/0.173/0.000 ms
Il est donc possible de modifier dynamiquement la configuration et la topologie réseau des containers.
docker rm -f testreseau
docker rm -f testreseau2
docker network rm net01
docker network rm net02
docker image prune