virli/tutorial/docker-basis/linking.md

181 lines
6.2 KiB
Markdown
Raw Normal View History

2015-10-22 03:25:20 +00:00
\newpage
2016-09-08 01:44:20 +00:00
Lier les conteneurs
===================
2015-10-22 03:25:20 +00:00
2018-10-04 03:47:52 +00:00
Lorsque l'on gère des services un peu plus complexes qu'un simple gestionnaire
d'images, on a souvent besoin de faire communiquer plusieurs services
2021-09-19 22:19:49 +00:00
entre eux.
2018-10-04 03:47:52 +00:00
2021-09-19 22:19:49 +00:00
Notre premier service, `youp0m`, utilisait le système de fichiers pour stocker
2018-10-04 03:47:52 +00:00
ses données, mais la plupart des applications réclament un serveur de base de
données.
Les bonnes pratiques nous dictent de ne pas placer plus d'un service par
conteneur : en effet, on peut vouloir mettre à jour l'applicatif sans pour
autant redémarrer sa base de données, etc. Nous allons donc voir dans cette
partie comment lier deux conteneurs.
## Mise en place du webservice
Nous allons utiliser l'interface d'administration des serveurs du FIC :
2019-10-16 01:54:56 +00:00
[`nemunaire/fic-admin`](https://hub.docker.com/r/nemunaire/fic-admin).
2018-10-04 03:47:52 +00:00
En lançant le conteneur avec les mêmes options que `youp0m`, les journaux
indiquent que le service cherche à se connecter à une base de données. Il va
2021-09-19 22:42:24 +00:00
donc falloir lier notre interface d'administration à [un conteneur
MariaDB](https://hub.docker.com/_/mariadb).
2018-10-04 03:47:52 +00:00
2015-10-22 03:25:20 +00:00
2017-10-08 22:08:33 +00:00
## Les pilotes réseau
2015-10-22 03:25:20 +00:00
2017-10-16 20:59:22 +00:00
Docker propose de base trois pilotes (*drivers*) pour « gérer » cela :
2015-10-22 03:25:20 +00:00
2017-10-16 20:59:22 +00:00
- `none` : pour limiter les interfaces réseau du conteneur à l'interface de
2017-10-08 22:08:33 +00:00
loopback `lo` ;
- `host` : pour partager la pile réseau avec l'hôte ;
- `bridge` : pour créer une nouvelle pile réseau par conteneur et rejoindre un
pont réseau dédié.
Ces trois *drivers* sont instanciés de base dans Docker avec le même nom que
2017-10-16 20:59:22 +00:00
leur pilote. Pour consulter la liste de réseaux utilisables, lancez :
2017-10-08 22:08:33 +00:00
2017-10-17 06:29:07 +00:00
<div lang="en-US">
2017-10-08 22:08:33 +00:00
```
42sh$ docker network ls
NETWORK ID NAME DRIVER SCOPE
74cedd3ff385 bridge bridge local
d5d907add6e2 host host local
16b702ed01a0 none null local
2017-10-08 22:08:33 +00:00
```
2017-10-17 06:29:07 +00:00
</div>
2017-10-08 22:08:33 +00:00
2017-10-16 20:59:22 +00:00
Par défaut, c'est le réseau `bridge` (de type `bridge`) qui est employé : ce
réseau utilise le pont `docker0` que vous pouvez voir dans vos interfaces
réseau via `ip link`. C'est via ce pont que les conteneurs peuvent avoir accès
à Internet, au travers d'une couche de NAT.
2017-10-08 22:08:33 +00:00
Pour changer le réseau principal joint par le conteneur, utiliser l'option
`--network` du `docker container run`.
### Le réseau `host`
2021-09-19 22:19:49 +00:00
En utilisant ce réseau, vous abandonnez toute isolation sur cette partie du
2017-10-08 22:08:33 +00:00
conteneur et partagez donc avec l'hôte toute sa pile IP. Cela signifie, entre
2021-09-19 22:19:49 +00:00
autres, que les ports que vous chercherez à allouer dans le conteneur devront
être disponibles dans la pile de l'hôte et également que tout port alloué sera
2017-10-08 22:08:33 +00:00
directement accessible, sans avoir à utiliser l'option `-p` du `run`.
### Créer un nouveau réseau `bridge`
2018-10-04 03:47:52 +00:00
Afin de contrôler quels échanges peuvent être réalisés entre les conteneurs, il
2017-10-08 22:08:33 +00:00
est recommandé de créer des réseaux utilisateur.
La création d'un réseau se fait tout simplement au travers des sous-commandes
relatives aux objets Docker `network` :
2017-10-17 06:29:07 +00:00
<div lang="en-US">
```bash
docker network create --driver bridge my_fic
2017-10-08 22:08:33 +00:00
```
2017-10-17 06:29:07 +00:00
</div>
2017-10-08 22:08:33 +00:00
C'est ensuite ce nom de réseau que vous passerez à l'option `--network` de vos
`run`, ou vous pouvez également faire rejoindre un conteneur déjà lancé à un
réseau :
2017-10-17 06:29:07 +00:00
<div lang="en-US">
```bash
docker network connect NETWORK CONTAINER
2017-10-08 22:08:33 +00:00
```
2017-10-17 06:29:07 +00:00
</div>
2017-10-08 22:08:33 +00:00
2018-10-04 03:47:52 +00:00
Lorsque plusieurs conteneurs ont rejoint un réseau utilisateur, ils peuvent
2017-10-08 22:08:33 +00:00
mutuellement se découvrir grâce à un système de résolution de nom basé sur leur
nom de conteneur.
2019-10-16 01:54:56 +00:00
## Exercice {-}
2019-10-01 09:03:15 +00:00
2019-10-16 01:54:56 +00:00
À vous maintenant de connecter une instance de `nemunaire/fic-admin` à sa base
de données.
2019-10-01 09:03:15 +00:00
2019-10-16 01:54:56 +00:00
Ne vous embêtez pas avec les mots de passes des services, initialisez la base
de données avec le nom d'utilisateur et le mot de passe par défaut. Vous les
2021-09-19 22:42:24 +00:00
obtiendrez en lisant la [documentation de l'image
fic-admin](https://hub.docker.com/r/nemunaire/fic-admin/) :
2019-10-01 09:03:15 +00:00
<div lang="en-US">
```bash
2019-10-16 01:54:56 +00:00
docker container run --rm -e MYSQL_HOST=mysql_cntr_name nemunaire/fic-admin -help
2019-10-01 09:03:15 +00:00
```
</div>
2019-10-16 01:54:56 +00:00
Notez la définition de la variable d'environnement `MYSQL_HOST`, celle-ci
indique le nom du serveur vers lequel le service doit se connecter.
2019-10-01 09:03:15 +00:00
2019-10-16 01:54:56 +00:00
Vous aurez besoin de créer un volume pour stocker la base de données, un réseau
dans lequel vous connecterez la base de données et le conteneur applicatif.
2019-10-01 09:03:15 +00:00
2019-10-16 01:54:56 +00:00
Une fois le service `fic-admin` lancé, vous pouvez exposer le port 8081, sur
lequel vous devriez voir l'interface d'admin : <http://localhost:8081/>.
2017-10-08 22:08:33 +00:00
2019-10-16 01:54:56 +00:00
Placez les différentes commandes (volumes, réseau, `run`, ...) dans un
script `ficadmin-run.sh`, que vous rendrez à la fin du TP. Vous
devriez pouvoir appeler ce script plusieurs fois, sans que les données
ne soient perdues, entre deux arrêts.
2017-10-08 22:08:33 +00:00
2019-10-16 01:54:56 +00:00
### Exemple d'exécution
2017-10-08 22:08:33 +00:00
2017-10-17 06:29:07 +00:00
<div lang="en-US">
```bash
2019-10-16 01:54:56 +00:00
42sh$ ./ficadmin-run.sh
http://localhost:12345/
42sh$ #docker kill db ficadmin
42sh$ ./ficadmin-run.sh # le script relancera une base de données,
# sans avoir perdu les données
http://localhost:12345/
2017-10-08 22:08:33 +00:00
```
2017-10-17 06:29:07 +00:00
</div>
2017-10-08 22:08:33 +00:00
2021-09-19 22:42:24 +00:00
### Au secours, ça veut pas se connecter !
Lorsque nous lançons pour la première fois notre conteneur MySQL ou MariaDB, un
script est chargé d'initialisé le volume attaché à `/var/lib/mysql`. Les
démarrage suivant, ou si vous réutilisez un volume déjà initialisé avec une
base de données, le script ne refait pas d'initialisation. Même si les
variables d'environnement ont changées.
Si vous rencontrez des difficultés pour connecter votre conteneur `fic-admin` à
`my-db`, prenez le temps de recréer un volume.
2019-10-16 01:54:56 +00:00
### Entrer dans un conteneur en cours d'exécution
2017-10-08 22:08:33 +00:00
2021-09-19 22:19:49 +00:00
Dans certaines circonstances, les journaux ne sont pas suffisants pour déboguer
2019-10-16 01:54:56 +00:00
correctement l'exécution d'un conteneur.
En réalisant l'exercice, vous serez sans doute confronté à des comportements
étranges, que vous ne pourriez comprendre qu'en ayant la main sur le conteneur,
via un shell.
2017-10-08 22:08:33 +00:00
2019-10-16 01:54:56 +00:00
Lorsqu'un conteneur est actif, vous pouvez y lancer un nouveau processus,
notamment un shell par exemple.
2017-10-08 22:08:33 +00:00
2017-10-17 06:29:07 +00:00
<div lang="en-US">
2019-10-16 01:54:56 +00:00
```bash
docker container exec -it ficadmin /bin/bash
(inctnr)$ ping mysql_cntr_name
2017-10-08 22:08:33 +00:00
```
2017-10-17 06:29:07 +00:00
</div>
2017-10-08 22:08:33 +00:00
2019-10-16 01:54:56 +00:00
Notez qu'il n'est pas possible d'`exec` dans un conteneur éteint, et que si la
commande initiale du conteneur se termine, tous les `exec` seront également
tués.