Poursuivons sur notre formation à Docker. Et nous allons maintenant rentrer dans des éléments indispensables à bien assimiler pour pratiquer docker au quotidien et réaliser des tâches de conception ou de troubleshooting.
Dès que l’on dit réseau, souvent, on commence par avoir des frissons lol. Pourtant dans le cas de docker, je trouve que justement c’est tellement sympa à découvrir qu’en plus de se former à la conteneurisation vous vous formerez à un peu plus que ça (les éléments systèmes ntafis à Linux mais rarement utilisés comme les namespaces). Mais bon commençons par le commencement.
Comme je dis toujours, il faut savoir marcher avant de courrir mais si parfois en IT c’est pas forcément ce qui est le plus courrant.
Débutons par une histoire de ports
Si on va souvent parler des bridges et notamment du Docker0, assez souvent on va vous parler de ports. Comment tu exposes le port machin ? C’est quoi le port du conteneur ? Quel est le mapping des ports de l’applicatif xx ?… Et même souvent parfois avec des erreurs de termes employés. Par exemple, on utilise souvent le terme exposition de port … mais il s’agit de publication de port (ne vous inquiétez pas je le fais tout le temps ça).
Alors avant de parler de ports, on va retenir que docker dispose de différents mode en terme de réseau :
- bridge
- host
- overlay
- none
- macvlan…
On va pour le moment se focaliser sur lebridge docker. Par défaut, il se nomme docker0.
La difficulté avec docker c’est que chaque conteneur dispose d’une IP à travers ce bridge et au sein du réseau de la machine sur laquelle le conteneur est déployé. Or ces ip ne sont pas fixes. Pour des raisons d’arrêts et de redémarrages souvent, ces IP de conteneurs vont changer. Donc la première règle est de ne pas s’y habituer et de la utiliser.
Du coup on se dit ok on ne va pas utiliser les ip mais comment on fait. Alors il existe différentes solutions : le mapping de ports entre le conteneur et le host, les DNS, l’API/socket docker.
Pour commencer on va parler du mapping de ports. Il s’agit simplement de se dire que l’on va faire correspondre un port du conteneur par exemple le 80 pour un conteneur nginx et un port de la machine host (par exemple 8080).
Ainsi, pour taper sur le conteneur nginx de l’extérieur de la machine :
- je curl l’ip de ma machine host 12.168.10.20:8080
- et grâce à des règles iptables mise en place automatiquement par docker je finis par curl le 172.17.0.2:80 du conteneur
Ce n’est pas toujours recommandé mais c’est très très souvent utilisé pour de multiples raisons dont la simplicité.
Ainsi le bridge permet de mettre en place le réseau suivant :
Et pour notre mapping, voici comment on peut se le représenter :
Alors c’est cool mais comment fait-on cela ??
Deux méthodes : le publish simple et le publish all…
Pour un publish simple, on peu appliquer notre modèle précédent avec la ligne de commande suivante :
docker run -d --name c1 -p 8080:80 nginx:latest
Et doc le 8080 de notre machine host redirige vers le 80 du conteneur c1.
Sinon et c’est nettement moins sympa on peut faire un publish all avec cette cli :
docker run -d --name c1 -P nginx:latest
Et là on voit moins ce que l’on fait. D’une part il faut que l’image nginx ait prévu d’exposer un port avec la clause EXPOSE (dans le Dockerfile on reverra cela plus tard). D’autre part, les ports exposés seront mappés avec des ports aléatoires de la machine host à partir de 32000. C’est pas aussi fun hein 😉
On peut en retenir donc que l’on publie un port mais on ne l’expose pas. L’xposition ne revient qu’à une simple déclaration mais ça ne dit pas ce que l’on en fait.
Créez votre propre bridge !!
Voilà pour ce qui est des ports et maintenant on va découvrir un outil bien sympa à savoir docker network, une CLI dédiée à la gestion des réseaux docker et notamment des bridges.
Ainsi vous allez pouvoir créer votre propre bridge avec une simple commande. Par exemple pour créer un bridge xavki0, on utilisera :
docker network create --driver=bridge --subnet=192.168.0.0/24 xavki0
et pour l’utiliser en lançant un conteneur c’est très simple :
docker run -d --name c1 --network xavki0 nginx:lates
t
Et alors le truc cool une fois que vous affectez un réseau à un conteneur c’est que si vous ajoutez un autre conteneur à ce même réseau vous pourrez bénéficier d’une résolution dns entre les 2 conteneurs par leur nom. Cool ça non ??
Et on peut aussi reconfigurer le bridge docker0 !!
Les choses ne s’arrête pas là car on peut configurer assez largement les bridges : dns, gateway, cidr…
On peut aussi reconfigurer le bridge docker0 pour lui faire utiliser un autre range d’IP. Pour cela il suffit de créer un fichier dans /etc/docker/daemon.json contenant le paramètre bip :
{
"bip": "10.10.0.1/16"
}
Et vous pouvez aussi faire en sorte que lors de la création d’un bridge, vous pourrez lui définir le nom que vous retrouverez dans un ifconfig ou un ip a. Pour cela il suffit de passer l’option
docker network create -o com.docker.network.bridge.name=xavki0 xavki0
Allé dans un autre post et une autre vidéo on découvrira comment créer ses briges, namespaces et vethernet manuellement.