Archives Wild Code School
Docker

Docker - Les réseaux

Quête 7 sur 8 · 3 images archivées

Introduction

Lorsque l'on travaille avec Docker, la gestion des réseaux est essentielle pour assurer la connectivité entre les conteneurs, ainsi que la communication avec d'autres services et réseaux externes. Docker offre une gamme de fonctionnalités de réseau flexibles et puissantes, permettant aux développeurs et aux administrateurs système de créer et de gérer des environnements conteneurisés hautement interconnectés.

Cette quête vise à explorer les différents aspects des réseaux Docker.

Turtles phone

🤓 Objectifs :

✅ Comprendre les concepts de base des réseaux Docker ✅ Apprendre à créer et à gérer des réseaux personnalisés ✅ Savoir connecter des conteneurs à des réseaux spécifiques

Sommaire


:point_right: Les réseaux sous Docker

Docker propose une gamme variée de configurations réseau pour répondre aux besoins diversifiés en matière de connectivité des conteneurs. Ces configurations offrent des solutions adaptées à différents scénarios d'utilisation, permettant ainsi de gérer efficacement les communications entre les conteneurs.

Pour assurer cette connectivité, Docker utilise des drivers , des mécanismes logiciels qui déterminent la manière dont les réseaux sont créés, configurés et utilisés par les conteneurs. Ces drivers sont conçus pour répondre à des exigences spécifiques et offrir des fonctionnalités variées, selon les besoins des applications et des environnements de déploiement.

Voici un aperçu des drivers disponibles dans l'écosystème Docker, chacun adapté à des cas d'utilisation particuliers :

Pilote Description
bridge Le pilote réseau par défaut
host Supprime l'isolation réseau entre le conteneur et l'hôte Docker
none Isole complètement un conteneur de l'hôte et des autres conteneurs
overlay Les réseaux superposés connectent plusieurs démons Docker ensemble (cluster Docker)
ipvlan Les réseaux IPvlan offrent un contrôle total sur l'adressage IPv4 et IPv6
macvlan Attribue une adresse MAC à un conteneur
Plugin réseau tiers Permettent d'intégrer Docker à des piles réseaux spécialisées
↗
https://docs.docker.com/network/drivers/

Pour en savoir plus sur les différents types de drivers, consulte la page de documentation officielle de Docker.

docs.docker.com
spacer

Lorsque tu installes Docker, plusieurs réseaux sont déjà créés :

  • Bridge
  • Host
  • None

Tu peux utiliser la commande docker network ls pour afficher la liste des réseaux disponibles sur ton hôte Docker.

bash
wilder@docker:~$ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
038bc330d049   bridge    bridge    local
60cfb5440f00   host      host      local
14c750ea17bf   none      null      local
Bravo

La commande docker network ls affiche une liste de tous les réseaux Docker disponibles sur ton système, avec des informations telles que leur ID, leur nom, leur driver et leur scope.

Info

Network ID représente l'identifiant de l'objet propre à Docker.

Info

Le Driver dans le contexte de Docker se réfère au mécanisme utilisé pour gérer le réseau.

Info

Le Scope fait référence à la portée du réseau. Les réseaux peuvent être de portée locale (local), ce qui signifie qu'ils sont disponibles uniquement sur l'hôte Docker où ils ont été créés, ou de portée globale (global), ce qui signifie qu'ils sont disponibles sur tous les hôtes Docker d'un cluster.

spacer

:point_right: Les drivers

Le driver bridge

Le réseau par défaut appelé bridge utilise le driver du même nom. Il permet à tous les conteneurs qui en font partie de communiquer entre eux et avec l'extérieur, mais ils ne sont pas accessibles depuis l'extérieur. Finalement, ce driver s'apparente à la notion de NAT : les flux réseaux peuvent sortir, les réponses à ces flux peuvent atteindre les conteneurs, mais il n'est pas possible d'initier une connexion depuis l'extérieur du réseau. Le réseau bridge est le type de réseau le plus couramment utilisé.

Le driver bridge fournit au conteneur :

  • Une interface réseau
  • Une adresse IPv4
  • Une passerelle
  • Une table de routage
  • Des services DNS
  • D'autres détails réseau

Lorsque tu crées un conteneur Docker, il est automatiquement connecté à ce réseau bridge.

→ Ce réseau bridge est automatiquement connecté à l'interface réseau docker0de ton hôte Docker. → L'interface docker0 à été créée automatiquement lors de l'installation de Docker sur ta machine. → Par défaut, son adresse est 172.17.0.1/16. → Le réseau 172.17.0.0/16 est le réseau par défaut connecté au driver bridge. → Chaque nouveau conteneur Docker est automatiquement connecté à ce réseau, à moins qu'un réseau personnalisé ne soit spécifié.

Tu peux afficher la configuration de la carte virtuelle docker0 de ton hôte Docker avec la commande suivante :

bash
wilder@docker:~$ ip addr show docker0
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:25:35:40:0c brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:25ff:fe35:400c/64 scope link
       valid_lft forever preferred_lft forever

Tu peux avoir plus d'informations sur les réseaux en utilisant la commande docker inspect <ID>. Allons en apprendre plus sur le réseau bridge, en utilisant son Network ID :

bash
wilder@docker:~$ docker network ls
NETWORK ID     NAME                DRIVER    SCOPE
c75194d2a8f8   bridge              bridge    local
60cfb5440f00   host                host      local
14c750ea17bf   none                null      local

wilder@docker1:~$ docker inspect c75194d2a8f8
[
    {
        "Name": "bridge",
        "Id": "c75194d2a8f86a6d682cc291fa35862ceaefe02f786959ca584180c58ad7caa2",
        "Created": "2024-04-02T10:21:07.293740997+02:00",
        "Scope": "local",
        "Driver": "bridge",
        "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": {},
        "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": {}
    }
]

Cette commande nous renvoie beaucoup d'informations. On retrouvera notamment :

  • Name : Le nom du réseau Docker, dans ce cas, "bridge".
  • Id : L'identifiant unique du réseau Docker.
  • Created : La date et l'heure de création du réseau Docker.
  • Scope : La portée du réseau, dans ce cas, "local".
  • Driver : Le driver utilisé par le réseau Docker, ici, "bridge".
  • EnableIPv6 : Indique si IPv6 est activé pour le réseau (dans ce cas, il est désactivé).
  • IPAM : Configuration de la gestion des adresses IP pour le réseau.
    • Driver : Le driver IPAM utilisé (dans ce cas, "default").
    • Config : Configuration spécifique des adresses IP pour le réseau, comme le sous-réseau et la passerelle.
  • Containers : Les conteneurs connectés à ce réseau, s'il y en a.
  • Options : Options de configuration supplémentaires pour le réseau, telles que les paramètres de pont Docker.
  • Labels : Les étiquettes associées au réseau Docker.

Créons un conteneur et connectons-le à ce réseau bridge par défaut:

bash
wilder@docker:~$ docker run -ti --name alpine1 alpine        
/ #
Bravo

Cette commande lance un conteneur Alpine en mode interactif et lui attribue le nom alpine1. Nous n'avons pas spécifié le réseau qu'il utilisera, par défaut le conteneur utilisera donc le réseau bridge Comme il s'agit d'un conteneur en mode interactif, nous sommes connecté à sa TTY en mode shell

Vérifions sa configuration réseau :

bash
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=0 ttl=127 time=14.385 ms
64 bytes from 8.8.8.8: seq=1 ttl=127 time=13.892 ms
64 bytes from 8.8.8.8: seq=2 ttl=127 time=18.312 ms
Bravo
  • La carte eth0 à été créée à l'intérieur du conteneur
  • Elle a comme adresse 172.17.0.2/16
  • L'adresse 172.17.0.2 est généralement attribuée au premier conteneur créé sur le réseau bridge par défaut. Les adresses suivantes (comme 172.17.0.3, 172.17.0.4, etc.) sont attribuées aux conteneurs suivants créés sur le même réseau
  • Le conteneur peut pinguer l'adresse 8.8.8.8, il peut donc communiquer avec l'extérieur sans configuration particulière.

On peut même vérifier que le conteneur utilise l'adresse de la carte réseau docker0 de l'hôte comme adresse de passerelle pour communiquer avec l'extérieur :

bash
/ # traceroute 8.8.8.8
traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 46 byte packets
 1  172.17.0.1 (172.17.0.1)  0.005 ms  0.005 ms  0.003 ms
...

Le driver None

Idéal si tu souhaites interdire toute communication interne et externe avec un conteneur. Le conteneur rattaché à ce driver sera dépourvu de toute interface réseau, sauf l'interface loopback .

Créons un conteneur Alpine basé sur le driver none:

bash
wilder@docker1:~$ docker run -ti --name alpine1 --network none alpine ip add show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
Bravo

Cette commande crée un conteneur alpine1 basé sur l'image Alpine en mode interactif, le connecte directement au réseau none et affiche ensuite les informations des cartes réseaux à l'intérieur du conteneur. Tu peux voir qu'il n'existe qu'une seule carte réseau au sein du conteneur : la carte loopback .

Le driver Host

Ce type de réseau permet aux conteneurs d'utiliser la même interface que l'hôte. Il supprime donc l'isolation réseau entre les conteneurs et l'hôte. Les conteneurs seront par défaut accessibles exactement comme l'hôte lui-même. De ce fait, il prendra la même IP que ta machine hôte et partagera les ports (TCP et/ou UDP) avec les processus du système hôte.

Attention

Le driver host est à proscrire en production, cette méthode n'est pas du tout sécurisée. Le conteneur et le système hôte ne sont pas isolés.

Pour mon exemple, j'utilise un hôte Docker connecté au réseau 192.168.200.0/24 à travers sa carte ens33. L'hôte Docker est joignable par son adresse 192.168.200.139 :

bash
wilder@docker:~$ ip addr show ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:5e:a7:a0 brd ff:ff:ff:ff:ff:ff
    altname enp2s1
    inet 192.168.200.139/24 brd 192.168.200.255 scope global dynamic ens33
       valid_lft 1287sec preferred_lft 1287sec
    inet6 fe80::20c:29ff:fe5e:a7a0/64 scope link
       valid_lft forever preferred_lft forever

On crée maintenant un conteneur de type Alpine rattaché à ce driver host :

bash
wilder@docker:~$ docker run -it --network host --name alpine2 alpine ip add show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:5e:a7:a0 brd ff:ff:ff:ff:ff:ff
    inet 192.168.200.139/24 brd 192.168.200.255 scope global dynamic ens33
       valid_lft 1052sec preferred_lft 1052sec
    inet6 fe80::20c:29ff:fe5e:a7a0/64 scope link
       valid_lft forever preferred_lft forever
Bravo

Cette commande crée un conteneur alpine2 basé sur l'image Alpine en mode interactif, le connecte directement au réseau Host et affiche ensuite les informations de ses interfaces réseaux à l'intérieur du conteneur. Les informations réseaux obtenues sont les mêmes que celles de l'hôte, car le conteneur alpine2 utilise les mêmes interfaces réseaux que l'hôte grâce au driver host :

  • Même adresses IP
  • Même adresse MAC
spacer

:point_right: Création d'un réseau Docker

Tu as la possibilité de créer des réseaux personnalisés pour tes applications en utilisant la commande docker network create <NOM_RESEAU>.

Cela te permet de spécifier des options de configuration avancées, telles que

  • le type de pilote de réseau
  • le sous-réseau IPv4
  • la configuration IPv6
  • les serveurs DNS
  • les options de pontage

Imaginons que tu disposes d'un serveur web fonctionnant dans un conteneur Docker et un serveur de base de données dans un autre conteneur. Plutôt que de les connecter au réseau par défaut de Docker, il est recommandé de créer un réseau personnalisé dédié à cette application. Cela te permet d'isoler ces services des autres conteneurs sur la même machine, renforçant ainsi la sécurité.

Source : Recommandation de sécurité relatives au déploiement et à l'exécution de conteneur Docker - ANSSI

↗
https://cyber.gouv.fr/sites/default/files/2020/12/docker_fiche_technique.pdf

On crée généralement un réseau par "stack" d'application que l'on déploie.

Il s'agit d'ailleurs d'une recommandation de l'ANSSI. Comme tu peux le voir dans la documentation, les recommandations R3, R4 et R5 nous préconisent de :

  • Ne pas connecter de conteneur au réseau par défaut bridge docker0
  • Ne pas utiliser non plus le driver host
  • Créer un réseau dédié pour chaque connexion
cyber.gouv.fr

Un autre avantage d'utiliser un réseau personnalisé, c'est la simplification des communications entre les conteneurs, car ils seront capables de communiquer entre eux en utilisant leurs noms d'hôtes, Docker les résout automatiquement, chose qui n'est pas possible en utilisant un réseau par défaut.

spacer

Créons un réseau personnalisé :

bash
wilder@docker:~$ docker network create my_network
Bravo

Sans spécifier d'options, cette commande crée un nouveau réseau Docker de type bridge nommé my_network.

Tu peux d'ailleurs le vérifier en utilisant le commande apprise plus tôt (colonne Driver) :

bash
wilder@docker:~$ docker network ls
NETWORK ID     NAME                DRIVER    SCOPE
038bc330d049   bridge              bridge    local
60cfb5440f00   host                host      local
39e537726708   my_network          bridge    local
14c750ea17bf   none                null      local

Il est possible de récolter plus d'informations sur ce réseau, en spécifiant son nom plutôt que son ID :

bash
wilder@docker:~$ docker network inspect my_network
[
    {
        "Name": "my_network",
        "Id": "39e537726708cbd616bfe3578a0619dca9ec5b59b4d11eaff0f85fb9b9224512",
        "Created": "2024-03-29T16:53:59.073045544+01:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.19.0.0/16",
                    "Gateway": "172.19.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]
Bravo

Docker à créé un nouveau réseau de type bridge, dans le plan d'adressage 172.19.0.0/16

D'ailleurs, il a aussi créé une carte réseau virtuelle appartenant à ce sous-réseau sur l'hôte :

bash
wilder@docker:~$ ip a
...
4: br-39e537726708: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:1b:44:7b:a1 brd ff:ff:ff:ff:ff:ff
    inet 172.19.0.1/16 brd 172.19.255.255 scope global br-39e537726708
       valid_lft forever preferred_lft forever
...
Info

Il est aussi possible de surcharger différentes valeurs lors de la création d'un réseau en spécifiant des options comme --subnet , --gateway .

Exemple :

bash
wilder@docker:~$ docker network create --driver=bridge --subnet=192.168.50.0/24 --gateway=192.168.50.254  mon_bridge_perso
80bee674fcd4799fcece0b7c7f035431948bf209ae604f0c7a05c136edcdf2ac
wilder@docker:~$ docker network ls
NETWORK ID     NAME                DRIVER    SCOPE
c75194d2a8f8   bridge              bridge    local
60cfb5440f00   host                host      local
80bee674fcd4   mon_bridge_perso    bridge    local
39e537726708   my_network          bridge    local
14c750ea17bf   none                null      local

Nous allons créer 2 conteneurs (alpine1 et alpine2) et les connecter à notre nouveau réseau personnalisé :

bash
# Création du conteneur alpine 1 en tache de fond
wilder@docker:~$ docker run -d --name alpine1 --network mon_bridge_perso alpine /bin/sleep infinity
6c2e806ebad18e7de8b7a1fb8c961d131207b7f8e23ecdb06264985ec601874c

# Création du conteneur alpine 2 avec un shell
wilder@docker:~$ docker run -ti --name alpine2 --network mon_bridge_perso alpine
/ # 

# Ping de alpine2 vers alpine1 avec son nom
/ # ping alpine1
PING alpine1 (192.168.50.1): 56 data bytes
64 bytes from 192.168.50.1: seq=0 ttl=64 time=0.074 ms
64 bytes from 192.168.50.1: seq=1 ttl=64 time=0.093 ms
Bravo

Notre réseau personnalisé mon_bridge_perso permet aux conteneurs de se joindre à travers leur nom, Docker s'occupe de tout !!!

Info

Si on inspecte notre réseau personnalisé, on verra notre conteneur alpine1 dans les informations retournées, dans la section "Containers": :

bash
wilder@docker:~$ docker network inspect mon_bridge_perso
[
    {
        "Name": "mon_bridge_perso",
        "Id": "80bee674fcd4799fcece0b7c7f035431948bf209ae604f0c7a05c136edcdf2ac",
        "Created": "2024-04-02T14:49:49.72073307+02:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.50.0/24",
                    "Gateway": "192.168.50.254"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "6c2e806ebad18e7de8b7a1fb8c961d131207b7f8e23ecdb06264985ec601874c": {
                "Name": "alpine1",
                "EndpointID": "c114941ca28fa87f9cb7ddb121dc94cd69073f1fcc4f0c606c538da2b8543b34",
                "MacAddress": "02:42:c0:a8:32:01",
                "IPv4Address": "192.168.50.1/24",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
spacer

:point_right: Connecter, déconnecter et supprimer un réseau Docker

Connexion à un réseau existant

Pour connecter un conteneur existant à un réseau spécifique, utilise la commande docker network connect.

bash
wilder@docker:~$ docker network connect my_network alpine1
Bravo

Le conteneur alpine1 est désormais connecté à notre réseau my_network en + de notre réseau mon_bridge_perso :

bash
wilder@docker:~$ docker inspect alpine1
...
            "Networks": {
                "mon_bridge_perso": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": [
                        "6c2e806ebad1"
                    ],
                    "MacAddress": "02:42:c0:a8:32:01",
                    "NetworkID": "80bee674fcd4799fcece0b7c7f035431948bf209ae604f0c7a05c136edcdf2ac",
                    "EndpointID": "c114941ca28fa87f9cb7ddb121dc94cd69073f1fcc4f0c606c538da2b8543b34",
                    "Gateway": "192.168.50.254",
                    "IPAddress": "192.168.50.1",
                    "IPPrefixLen": 24,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "DriverOpts": null,
                    "DNSNames": [
                        "alpine1",
                        "6c2e806ebad1"
                    ]
                },
                "my_network": {
                    "IPAMConfig": {},
                    "Links": null,
                    "Aliases": [
                        "6c2e806ebad1"
                    ],
                    "MacAddress": "02:42:ac:13:00:02",
                    "NetworkID": "39e537726708cbd616bfe3578a0619dca9ec5b59b4d11eaff0f85fb9b9224512",
                    "EndpointID": "88e42767327e2a7e951b338c12d27fedd118b545fb0868d57b5bc7aba6df8237",
                    "Gateway": "172.19.0.1",
                    "IPAddress": "172.19.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "DriverOpts": {},
                    "DNSNames": [
                        "alpine1",
                        "6c2e806ebad1"
                    ]
                }
...

Déconnexion d'un réseau

Pour déconnecter un conteneur d'un réseau spécifique, utilise la commande docker network disconnect.

bash
wilder@docker:~$ docker network disconnect my_network alpine1

Suppression d'un réseau personnalisé

Avant de supprimer un réseau docker, il est nécessaire au préalable de supprimer (ou déconnecter) tout conteneur connecté à ce réseau docker :

bash
# Test de suppression d'un réseau personnalisé
wilder@docker:~$ docker network rm mon_bridge_perso
Error response from daemon: error while removing network: network mon_bridge_perso id 80bee674fcd4799fcece0b7c7f035431948bf209ae604f0c7a05c136edcdf2ac has active endpoints

# Déconnection du conteneur rattaché à ce réseau
wilder@docker:~$ docker network disconnect mon_bridge_perso alpine1

# Suppression du réseau personnalisé
wilder@docker:~$ docker network rm mon_bridge_perso
mon_bridge_perso

Cependant les conteneurs se retrouvent maintenant sans interface réseau bridge, il faut donc reconnecter les conteneurs au réseau bridge par défaut pour qu'ils puissent de nouveau communiquer :

bash
wilder@docker:~$ docker network connect bridge alpine1

:point_right: Publication de port

Comme abordé précédemment, les applications conteneurisées ne sont pas accessibles depuis l'extérieur. Pour permettre à des services exécutés à l'intérieur du conteneur d'être accessibles depuis l'extérieur, il est nécessaire de mettre en place de la publication de ports.

La publication de port fonctionne en exposant des ports spécifiques à l'extérieur du conteneur et en les liant à des ports sur l'hôte, permettant ainsi d'établir des connexions réseau.

Par exemple, supposons que tu exécutes un serveur web dans un conteneur Docker et que tu souhaites que ce serveur soit accessible depuis l'extérieur. Tu peux publier le port 80 du conteneur (port par défaut pour HTTP) en le liant à un port de ta machine hôte, le port 8080, par exemple. Ainsi, toute requête HTTP envoyée à ta machine hôte sur le port 8080 sera redirigée vers le serveur web fonctionnant dans le conteneur.

On publie un port lors de la création d'un conteneur, en utilisant la syntaxe suivante : -p <PORT_HOTE>:<PORT_CONTENEUR> .

Exemple :

bash
wilder@docker:~$ docker run -d --name srv-web -p 8080:80 nginx
Bravo

Cette commande crée un conteneur nommé srv-web basé sur l'image nginx, et publie le port 80du conteneur sur le port 8080 de l'hôte. Le premier port indique celui de la machine hôte.

Vérification du serveur web depuis une machine tierce :

Vérification depuis l'hôte Docker:

bash
wilder@docker1:~$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                                   NAMES
721bfd07741c   nginx     "/docker-entrypoint.…"   10 minutes ago   Up 10 minutes   0.0.0.0:8080->80/tcp, :::8080->80/tcp   srv-web
Bravo

La colonne PORTS nous fourni les indications de publication de port.

spacer

:point_right: Résumé

Les réseaux Docker offrent une flexibilité et un contrôle considérables sur la connectivité des conteneurs. En comprenant les différents types de réseaux disponibles, les pilotes associés et les options de configuration avancées, les développeurs et les administrateurs système peuvent créer des environnements conteneurisés hautement interconnectés et sécurisés.

Dans cette quête, nous avons exploré les bases des réseaux Docker, y compris la création de réseaux personnalisés, la connexion de conteneurs à des réseaux spécifiques et la publication de ports.

Continue d'explorer les fonctionnalités réseaux de Docker en parcourant la documentation officielle .

:books: CheatSheet Réseaux Docker

  • docker network ls : Lister les réseaux docker
  • docker network inspect <NETWORK NAME> : Récolter des informations sur un réseau docker
  • docker network create --driver <DRIVER TYPE> <NETWORK NAME> : Créer un réseau docker
  • docker run --network <NETWORK NAME> <IMAGE NAME> : Démarrer un conteneur et le connecter à un réseau docker
  • docker network rm <NETWORK NAME> : Supprimer un réseau docker
  • docker network connect <NETWORK NAME> <CONTAINER NAME> : Connecter un conteneur à un réseau docker
  • docker network disconnect <NETWORK NAME> <CONTAINER NAME> : Déconnecter un conteneur d'un réseau docker
  • docker run -p <HOST PORT>:<CONTAINER PORT> : Publier un port choisi du conteneur sur un port de l'hôte Docker
spacer

📝 Quiz

quiz
false|||false|||false
# Quelle commande permet d'afficher la liste des réseaux disponibles sur un hôte Docker ?
[] docker network inspect
[x] docker network ls
[] docker network show

# Quel est le rôle du driver "bridge" dans Docker 
[] Isoler complètement un conteneur de l'hôte et des autres conteneurs
[] Supprimer l'isolation réseau entre le conteneur et l'hôte Docker
[] Attribuer une adresse MAC à un conteneur
[x] Permettre la connectivité entre les conteneurs Docker et avec d'autres ressources réseau via la machine hôte
# Quel type de réseau Docker permet aux conteneurs d'utiliser la même interface que l'hôte ?
[] None
[] Bridge
[x] Host
[] Overlay
# Quelle option de la commande docker network create permet de spécifier le type de pilote de réseau ?
[] --network-driver
[x] --driver
[] --network-type
[] --type
# Comment connecter un conteneur existant à un réseau spécifique ?
[] docker network join
[x] docker network connect
[] docker network attach
[] docker network add
# Quelle est la fonction principale de la publication de port dans Docker ?
[] Isoler les conteneurs de l'hôte et des autres conteneurs
[] Créer des réseaux personnalisés
[x] Permettre à des services exécutés à l'intérieur du conteneur d'être accessibles depuis l'extérieur
[] Gérer les pilotes de réseau dans Docker
# Quelle commande permet de publier un port lors de la création d'un conteneur Docker ?
[] docker port
[] docker publish
[x] docker run -p
[] docker expose
spacer

💪 Challenge

Pour déployer une stack comprenant un serveur web et une base de données, ta mission consiste à établir la connectivité réseau entre ces conteneurs en suivant les bonnes pratiques, puis à les déployer.

Voici les éléments à respecter :

  • Le conteneur web doit utiliser l'image nginx et le conteneur db doit utiliser l'image mariadb.
  • Le conteneur db doit être connecté au réseau nommé db, tandis que le conteneur web doit être connecté aux réseaux db et web.
  • Seul le conteneur web est accessible depuis l'extérieur sur le port 8080
  • Seul le conteneur web doit avoir accès au conteneur db, aucun autre potentiel conteneur.
  • Tu ne dois pas utiliser le bridge par défaut, mais plutôt des réseaux personnalisés.
Bravo

Le livrable attendu pour ce challenge est la réalisation d'un script bash qui permet de créer ces réseaux personnalisés et les conteneurs connectés à ces réseaux. Ensuite, ton script doit afficher dans le terminal les adresses IPv4 des différents conteneurs. Poste ton script en tant que solution au challenge.

L'appréciation portera sur la conformité de la création des réseaux, et sur la connexion des conteneurs à ces réseaux.

🧐 Critères d'acceptation

Ton script est conforme aux instructions :

  • Les réseaux personnalisés sont créés
  • Les conteneurs se connectent au bons réseaux
  • La sortie du terminal affiche les adresses IPv4 des conteneurs