This commit is contained in:
nemunaire 2017-10-05 01:42:56 +02:00 committed by nemunaire
commit 7a1d5d9981
10 changed files with 189 additions and 219 deletions

View file

@ -1,33 +1,7 @@
\newpage
Volumes
=======
Il est possible de partager des répertoires entre plusieurs conteneurs. Pour ce
faire, il faut déclarer dans le `Dockerfile` une ou plusieurs instructions
`VOLUME` avec le chemin du répertoire à considérer comme volume (il est
également possible de le faire via l'option `--volume` du client). Ces deux
lignes sont équivalentes :
```
VOLUME /var/log/nginx
```
```
docker run -v /var/log/nginx my_nginx
```
Pour monter les volumes dans un autre conteneur, on utilise l'argument
`--volume-from` du client, en indiquant le nom du conteneur avec lequel on
souhaite partager les volumes :
```
docker run -it --volume-from romantic_archimedes ubuntu /bin/bash
```
Vous constaterez que le répertoire `/var/log/nginx` est partagé entre
`romantic_archimedes` et le dernier conteneur lancé.
\newline
Stockage de données applicatives
================================
Le concept principal de Docker est de concevoir des conteneurs applicatifs : on
va préférer assigner un unique rôle à un conteneur (donc géralement on ne va
@ -35,8 +9,15 @@ lancer qu'une seule application par conteneur) et concevoir un service complet
en créant un groupe de conteneur, partageant des données entre-eux par des
volumes.
Une lecture intéressante sur ce sujet est sans doute [cet article de Michael
Crosby](http://crosbymichael.com/advanced-docker-volumes.html).
Il est possible d'utiliser la dernière couche en lecture/écriture pour inscrire
des données. Il n'est cependant pas recommandé de stocker des données de cette
manière, car les données ne vont pas persister une fois que le conteneur aura
terminé son exécution ; elles seront alors plus compliqués à retrouver
manuellement.
Docker met à notre disposition plusieurs mécanismes pour que les données de nos
applications persistent et soient prêtes à migrer plus facilement vers une
solution plus apte à la décentralisation.
## Partage avec la machine hôte
@ -48,68 +29,57 @@ le protocole HTTP, mais sans se casser la tête à installer et configurer un
serveur web :
```
docker run --rm -p 80:80 -v ~/Downloads:/usr/share/nginx/html:ro -d nginx
docker container run --rm -p 80:80 -v ~/Downloads:/usr/share/nginx/html:ro -d nginx
```
Une fois cette commande lancée, votre voisin pourra accéder à votre dossier
Downloads en renseignant l'IP de votre machine dans son navigateur favori !
## Data Volume Container
## Les volumes
Dans de nombreuses situations, il est intéressant de séparer les données de
l'application, et donc d'avoir un conteneur exécutant l'application et un
second stockant les données.
Les volumes sont des espaces créés via Docker (il s'agit d'objets Docker). Ils
permettent de partager facilement des données entre conteneurs, sans avoir à se
soucier de leur réel emplacement.
Cela est particulièrement utile dans le cas d'une base de données : on veut
pouvoir mettre à jour le conteneur exécutant le serveur, sans pour autant
perdre les données.
L'idée derrière le concept de `Data Volume Container` est de partager un volume
avec un conteneur dont le seul rôle est de stocker les données.
Il est parfaitement possible de partager un volume avec un conteneur qui n'est
plus lancé. En effet, tant que vous n'avez pas demandé explicitement à un
conteneur d'être supprimé, il est préservé dans un coin en attendant des jours
meilleurs.
Voici comment on pourrait lancer un conteneur exécutant une base de données :
Comme il s'agit d'un objet, la première chose à faire va être de créer notre
volume :
```
docker create -v /var/lib/mysql --name dbdata busybox /bin/true
docker run --volume-from dbdata -e MYSQL_ROOT_PASSWORD=mysecretpassword -d mysql
docker volume create prod_db
```
Le premier conteneur, sans commande passée, va s'arrêter dès son
lancement. Busybox est l'une des plus petites images possédant tous les outils
de base (il est possible d'obtenir un shell en cas de besoin). Il expose un
volume qui sera utiliser comme stockage persistant.
Ensuite, nous pouvons démarrer un conteneur l'utilisant, par exemple :
Le second conteneur va lancer le serveur MySQL et utiliser le répertoire
partagé pour stocker les données.
```
docker container run --name mydb --mount source=prod_db,target=/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw mysql
```
Lorsqu'il y aura besoin de mettre à jour le conteneur MySQL, les données ne
seront pas perdues (et s'il y avait besoin de migrer les données entre les deux
versions des conteneurs, un conteneur intermédiaire pourrait parfaitement s'en
charger).
Lorsque le volume est vide, si des données sont présentes à l'endroit du point
de montage, celles-ci sont recopiées dans le volume.
Cela facile également les sauvegardes, qui peuvent s'exécuter dans un conteneur
distinct, dédié à la tâche de sauvegarde.
Si plus tard, vous souhaitez créer un conteneur chargé de faire des
sauvegardes, vous pourriez le lancer comme ceci :
```
docker container run -it --volume-from mydb busybox /bin/bash
```
## Volumes temporaires
Lorsque vous n'avez pas besoin de stocker les données et que vous ne désirez
pas qu'elles persistent (des données sensibles par exemple) ou si cela peut
améliorer les performances de votre conteneur, il est possible de créer des
points de montages utilisant le système de fichiers `tmpfs` et donc résidant
exclusivement en RAM.
## Rendu
### Exercice
Modifiez le `Dockerfile` de l'exercice précédent pour que votre application web
(ok, c'est juste un `index.html` ...) soit contenue dans un *data volume
container*.
Choisissez le nom de votre volume judicieusement, cela peut vous faciliter la
vie !
Écrivez un script shell qui reprend les commandes que vous avez tapé dans votre
terminal pour créer le *data volume container*, construire l'image à partir du
Dockerfile et lancer le conteneur `my_webserver` lié.
Rendre le `Dockerfile`, son contexte et le script de construction/lancement.
Modifiez le `Dockerfile` de l'exercice précédent pour que les logs de votre
application web (ok, c'est juste un `index.html` ...) soient contenus dans un
*volume*.