Archives Wild Code School
Docker

Docker - Les volumes

Quête 8 sur 8 · 1 image archivée

Introduction

Lorsque l'on travaille avec Docker, il est crucial de maîtriser la gestion des volumes pour assurer la persistance des données dans les conteneurs.

Contrairement aux machines virtuelles traditionnelles, les conteneurs Docker sont éphémères par nature, ce qui signifie que les données qu'ils contiennent sont généralement perdues lorsque le conteneur est arrêté ou supprimé.

Cependant, les volumes Docker offrent une solution élégante à ce problème en permettant de stocker des données de manière durable, indépendamment du cycle de vie des conteneurs.

Cette quête vise à explorer les volumes Docker, un outil essentiel pour la gestion des données persistantes dans les conteneurs.

spacer-small

Persistent data in Docker volumes

spacer-small

🤓 Objectifs :

✅ Comprendre le concept de volume Docker ✅ Apprendre à créer et gérer des volumes ✅ Comprendre les types de volumes

Sommaire


:question: Qu'est-ce qu'un volume Docker ?

Prenons l'exemple d'une application conteneurisée qui nécessite un stockage de données persistant, comme une base de données. Sans l'utilisation de volumes, chaque fois que le conteneur de la base de données est arrêté ou redémarré, toutes les données qu'il contient sont perdues. Cela rendrait impossible le stockage et la récupération fiable des données sur le long terme.

La solution réside dans l'utilisation de volumes Docker, qui agissent comme des points de montage pour les données à l'intérieur des conteneurs. En montant un volume sur un répertoire spécifique à l'intérieur du conteneur, les données peuvent être stockées de manière persistante en dehors du conteneur lui-même, sur le système hôte ou sur un autre emplacement distant.

Les volumes Docker offrent de nombreux avantages :

  • facilité de persistance des données au-delà du cycle de vie des conteneurs
  • possibilité de réaliser des sauvegardes régulières et fiables
  • capacité à partager des données entre plusieurs conteneurs

Ils permettent également une gestion flexible des permissions sur les données, tout en offrant la possibilité d'utiliser des volumes locaux ou distants en fonction des besoins spécifiques de l'application et de l'infrastructure.

Avant de rentrer dans le vif du sujet, je t'invite à visionner la vidéo suivante :

▶
Vidéo YouTube
https://www.youtube.com/watch?v=lstTLSM5494

:point_right: Création d'un Volume Docker

Création d'un volume

Pour créer un volume Docker, utilise la commande docker volume create <nom_du_volume>. Cette commande génère un nouveau volume avec le nom spécifié.

bash
wilder@docker:~$ docker volume create data_volume
Bravo

Cette commande crée un volume Docker nommé data_volume.

Info

Lorsque tu créés un volume Docker, il est intéressant de comprendre où ce volume est stocké sur l'hôte Docker.

En général, les volumes Docker sont stockés dans un répertoire spécifique du système de fichiers de l'hôte, qui varie selon la plateforme et la configuration de Docker.

Par exemple, sur un système Linux, les volumes Docker sont généralement stockés dans le répertoire /var/lib/docker/volumes.

Sur d'autres systèmes d'exploitation, tels que Windows ou macOS, les volumes peuvent être stockés ailleurs en fonction de la configuration de Docker Desktop.

Lister les volumes

Une fois le volume créé, tu peux afficher la liste des volumes disponibles en utilisant la commande docker volume ls. Cela te permet de vérifier que ton volume a été créé avec succès.

bash
wilder@docker:~$ docker volume ls
DRIVER		VOLUME NAME
Local		data_volume
Bravo

Cette commande affichera la liste des volumes Docker disponibles sur ton système, y compris le volume que tu viens de créer.

Information détaillée sur un volume

Pour obtenir des informations détaillées sur un volume spécifique, utilise la commande docker volume inspect <nom_du_volume>. Cela te fournira des détails sur le volume, tels que son nom, son identifiant unique, son point de montage sur le système hôte, etc ...

bash
wilder@docker:~$ docker volume inspect data_volume
[
    {
        "CreatedAt": "2024-03-28T12:01:53+01:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/data_volume/_data",
        "Name": "data_volume",
        "Options": null,
        "Scope": "local"
    }
]
Bravo

Cette commande affichera des informations détaillées sur le volume Docker nommé data_volume, sous format JSON.

Info

JSON (JavaScript Object Notation) est un format de données léger, facile à lire et à écrire pour les humains, ainsi qu'à analyser et à générer pour les machines. Il est largement utilisé pour l'échange de données entre serveurs web et clients, ainsi que pour le stockage de données structurées. Dans notre exemple, les informations sur le volume Docker sont présentées sous forme de tableau JSON, avec des paires clé-valeur pour chaque attribut du volume, telles que CreatedAt, Driver, Mountpoint, etc.

↗
Qu'est-ce qu'un driver ?

Le retour au format JSON de la commande docker volume inspect data_volume nous renvoie l'élément "Driver": "local", L'indication driver local signifie simplement que ces volumes sont gérés localement par Docker, c'est-à-dire qu'ils sont stockés localement sur la machine Docker. En d'autres termes, Docker utilise un pilote local pour gérer ces volumes sur le système de fichiers de l'hôte.

Le terme driver se réfère au mécanisme utilisé par Docker pour gérer les volumes. Il existe différents types de pilotes de volume Docker, chacun étant adapté à des cas d'utilisation spécifiques. Par exemple, en plus du pilote local, Docker prend en charge des pilotes pour des systèmes de stockage distants tels que NFS, Amazon EBS, Azure Disk, etc.

docs.docker.com

Suppression d'un volume

Si tu n'as plus besoin d'un volume Docker, tu peux le supprimer en utilisant la commande docker volume rm <nom_du_volume>. Assurez toi que le volume que tu souhaites supprimer n'est pas utilisé par des conteneurs en cours d'exécution.

bash
wilder@docker:~$ docker volume rm data_volume
Bravo

Cette commande supprimera le volume Docker nommé data_volume de ton système.

Attention

Si le volume est utilisé par un ou plusieurs conteneurs, tu devras alors supprimer ce(s) conteneurs(s) avant de pouvoir supprimer le volume. Le fait de stopper simplement un conteneur avec la commande docker stop <conteneur> ne permet pas de supprimer le volume.

bash
wilder@docker:~$ docker volume rm data_volume
Error response from daemon: remove data_volume: volume is in use - [7f3c5941992e8b518ca0fa0213b367ce12df5f300dd8fb229b0f5a0c6db78411]
wilder@docker:~$ docker stop nginx
nginx
wilder@docker:~$ docker volume rm data_volume
Error response from daemon: remove data_volume: volume is in use - [7f3c5941992e8b518ca0fa0213b367ce12df5f300dd8fb229b0f5a0c6db78411]
wilder@docker:~$ docker rm nginx
nginx
wilder@docker:~$ docker volume rm data_volume
data_volume
spacer-medium
Info

En gérant efficacement les volumes Docker, tu peux libérer de l'espace disque inutilisé et maintenir un environnement Docker propre et bien organisé. Assure toi de bien comprendre les implications de la suppression d'un volume avant de procéder à sa suppression, car cela peut entraîner la perte de données importantes en production.

spacer-medium

:point_right: Utilisation des Volumes dans les Conteneurs

Pour utiliser un volume Docker lors de la création d'un conteneur, tu peux spécifier le volume à l'aide de l'option -v ou --volume suivie du nom du volume.

Par exemple, pour créer un conteneur MySQL avec un volume Docker nommé "mysql_data", tu peux exécuter la commande suivante :

bash
wilder@docker:~$ docker run -d --name mysql_container -v mysql_data:/var/lib/mysql mysql:latest 
Bravo

Dans cet exemple, le volume Docker nommé mysql_data est monté dans le répertoire /var/lib/mysql du conteneur qui porte le nom mysql_container.

Toutes les données stockées dans ce répertoire seront persistantes, même si le conteneur est arrêté ou supprimé. Docker se charge de créer et de gérer ce volume de manière transparente, ce qui simplifie considérablement la gestion des données dans les conteneurs.

spacer-small

:point_right: Types de volumes

Docker offre plusieurs types de volumes, appelés driver, pour la gestion des données dans les conteneurs, chacun offrant des fonctionnalités spécifiques adaptées à différents cas d'utilisation.

Driver type Volume Docker

Le premier type de volume est le volume Docker, qui est géré par Docker lui-même. C'est celui-ci que nous avons abordé. Le volume sur l'hôte Docker se situe à un emplacement fixe, comme vu plus haut : /var/lib/docker/volumes

Il est particulièrement utile pour les applications nécessitant un stockage durable des données, telles que les bases de données, les fichiers de configuration, ou tout autre type de données nécessitant une persistance au-delà du cycle de vie du conteneur. Avec ce type de volume il est aussi possible d'utiliser des volumes distants comme NFS ou iSCSI.

Driver type Bind

Ensuite, il y a les montages de type bind (bind mount), qui permettent de monter directement des répertoires ou des fichiers de l'hôte dans un conteneur. Contrairement aux volumes Docker, les bind mount ne sont pas gérés par Docker et offrent un accès direct aux fichiers de l'hôte dans le conteneur. On peut alors renseigner un répertoire spécifique de l'hôte Docker à partager avec le conteneur lors de la création de celui-ci.

Info

L'approche est un peu différente , dans le sens ou il n'est pas nécessaire de créer un volume avant de le mettre à disposition d'un ou de plusieurs conteneurs.

Ils sont particulièrement utiles pour le partage de fichiers entre l'hôte et les conteneurs, ainsi que pour l'accès à des données spécifiques de l'hôte dans le conteneur.

Lors de la création d'un conteneur, tu peux spécifier des volumes à monter en utilisant l'option -v suivie du chemin du volume sur l'hôte et du chemin de destination dans le conteneur.

bash
wilder@docker:~$ docker run -v /chemin/sur/hote:/chemin/dans/conteneur nom_de_l_image 
Bravo

Cette commande monte le volume local situé à /chemin/sur/hote dans le conteneur à /chemin/dans/conteneur.

↗
https://docs.docker.com/storage/bind-mounts/

En savoir plus sur le type de montage Bind mount :

docs.docker.com

Autres types

Docker prend également en charge les volumes de type tmpfs, qui sont stockés en mémoire et ne sont pas persistants au-delà du cycle de vie du conteneur. Les volumes tmpfs sont utiles pour stocker des données temporaires ou des fichiers système en mémoire, offrant ainsi des performances améliorées et une réinitialisation automatique à chaque redémarrage du conteneur.

↗
https://docs.docker.com/storage/tmpfs/

Documentation officielle Docker sur le driver type tmpfs :

docs.docker.com
↗
https://docs.docker.com/storage/storagedriver/

Pour aller plus loin sur les différents types de driver :

docs.docker.com

:point_right: Différences fondamentales entre volume docker et bind mount

Quelle différence entre volume bind et volume docker ?

Les volumes de type volume Docker et les montages de type bind sont deux mécanismes utilisés dans Docker pour gérer la persistance des données dans les conteneurs, mais ils diffèrent par leur comportement lorsqu'il s'agit de la source des données.

Les volumes de type volume Docker prennent les données de l'image Docker à partir de laquelle le conteneur est créé et les stockent dans un volume sur l'hôte. Cela signifie que les données présentes dans le volume sur l'hôte sont initialement basées sur les données de l'image Docker, mais peuvent être modifiées ou étendues pendant l'exécution du conteneur par l'hôte ou le conteneur. Par exemple, si tu utilises un volume Docker pour stocker des données de base de données, les données initiales peuvent provenir de l'image de la base de données, mais peuvent être modifiées à mesure que de nouvelles données sont ajoutées pendant l'exécution du conteneur.

POC - Proof of Concept Docker Volume

bash
# Création d'un volume docker
wilder@docker:~$ docker volume create data_volume

# Vérification du volume sur l'hôte
wilder@docker:~$ sudo ls /var/lib/docker/volumes/
data_volume

# Instanciation d'un conteneur nginx, montage du volume 
# data_volume de type volume docker et publication du port 80
wilder@docker:~$ docker run -d --name nginx -p 80:80 -v data_volume:/usr/share/nginx/html nginx
f4d480583da60a01d47d8be8e85b74d01be43fd3572a96ee5f8a54adf81c369d

# Récupération de la page d'accueil du conteneur nginx avec la commande curl
wilder@docker:~$ curl 192.168.200.139:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
Bravo

Les données sont celles du serveur web nginx !!! Il s'agit de la page d'accueil par défaut du conteneur nginx, et donc du fichier index.html par défaut.

spacer-small

Les montages de type bind prennent les données de l'hôte Docker lui-même et les montent directement dans le conteneur, en écrasant tout contenu existant dans le conteneur à cet emplacement. Cela signifie que les données présentes dans le répertoire monté dans le conteneur sont directement celles de l'hôte, sans modification ou extension à partir de l'image Docker. Par exemple, si tu montes un répertoire de ton hôte contenant des fichiers de configuration dans un conteneur, les fichiers présents dans ce répertoire de l'hôte seront accessibles dans le conteneur, remplaçant tout fichier existant à cet emplacement dans l'image Docker.

POC - Proof of Concept Bind Mount

bash
# Création du fichier index.html sur l'hôte Docker
# dans le $HOME de l'utilisateur wilder
wilder@docker:~$ nano index.html 

# Contenu du fichier index.html
<h1>Montage de type bind !!!</h1> 

# Instanciation d'un conteneur nginx, montage du volume de type bind
# et publication du port 80
wilder@docker:~$ docker run -d --name nginx -p 80:80 -v /home/wilder/:/usr/share/nginx/html nginx
1f99c0eff4d2ac8e20974221a481005f35d4e2c9a5f434f669227d9d55672687

# Récupération de la page d'accueil du conteneur nginx avec la commande curl
wilder@docker:~$ curl 192.168.200.139:80                                       
<h1>Montage de type bind !!!</h1>

Bravo

Les données sont celles de l'hôte Docker !!! Il s'agit du fichier index.html créé depuis l'hôte Docker.

Attention

:u[Conclusion : ] Les volumes de type volume Docker permettent de stocker des données basées sur l'image Docker avec possibilité de modification, tandis que les montages de type bind fournissent un accès direct aux données de l'hôte, écrasant tout contenu existant dans le conteneur à cet emplacement.

Le choix entre ces deux types de stockage dépend des besoins spécifiques de ton application et du niveau de contrôle souhaité sur les données dans le conteneur.


:point_up: Résumé

  • Une fois montés, les volumes peuvent être utilisés dans les conteneurs de la même manière que n'importe quel autre répertoire ou fichier.

  • Les données écrites dans les volumes seront stockées de manière persistante et seront accessibles même après l'arrêt ou la suppression du conteneur. Tu peux utiliser un volume Docker pour stocker des fichiers de configuration, des bases de données, des journaux d'application, ou tout autre type de données nécessaires à ton application.

  • En utilisant les volumes Docker de manière appropriée, tu peux garantir la portabilité et la fiabilité de tes applications conteneurisées, tout en assurant la persistance des données importantes.


📝 Quiz

quiz
true||true|||false
# Quel est l'avantage principal de l'utilisation de volumes Docker dans les conteneurs ?
[] Réduire l'utilisation de la mémoire RAM
[x] Assurer la persistance des données au-delà du cycle de vie du conteneur
[] Accélérer le temps de démarrage des conteneurs
[] Améliorer la sécurité des conteneurs

# Comment crée-t-on un volume Docker nommé "data_volume" à l'aide de la CLI Docker ?
[x] docker volume create data_volume
[] docker volume new data_volume
[] docker create volume data_volume
[] docker volume add data_volume

# Quelle commande permet de lister tous les volumes Docker disponibles sur le système ?
[] docker volume show
[x] docker volume ls
[] docker volume info

# Quelle commande te permet de lancer un conteneur Nginx en spécifiant un volume Docker nommé "data_volume" ?
[x] docker run -v data_volume:/usr/share/nginx/html nginx:latest
[] docker start -v data_volume:/usr/share/nginx/html nginx:latest
[] docker create -v data_volume:/usr/share/nginx/html nginx:latest

# Quelle commande permet de supprimer un volume Docker nommé "data_volume" ?
[] docker volume delete data_volume
[x] docker volume rm data_volume
[] docker volume erase data_volume

# Quelle est la différence fondamentale entre un volume Docker et un montage de type bind (bind mount) ?
[] Les volumes Docker sont stockés en mémoire, tandis que les montages de type bind sont persistants.
[] Les montages de type bind sont gérés par Docker, tandis que les volumes Docker ne le sont pas.
[] Les volumes Docker permettent un accès direct aux fichiers de l'hôte, tandis que les montages de type bind sont basés sur l'image Docker.
[x] Les volumes Docker prennent les données de l'image Docker et les stockent sur l'hôte, tandis que les montages de type bind montent directement des répertoires de l'hôte dans le conteneur.

🎉 Bravo !

Félicitations pour avoir terminé cette quête sur les volumes Docker ! Tu devrais maintenant avoir une compréhension solide du concept de volume Docker, ainsi que des compétences pratiques pour créer, gérer et utiliser des volumes dans tes propres projets conteneurisés.

Bravo

Continue d'explorer d'autres fonctionnalités avancées des volumes Docker, telles que les volumes de type bind, les volumes de type tmpfs, et les plugins de stockage externes car cela te sera certainement bénéfique dans ta carrière en développement logiciel ou en administration système.


💪 Challenge

Dans ce challenge, tu vas mettre en pratique tes connaissances sur les volumes Docker en rédigeant un script Bash qui permet de réaliser les actions suivantes :

  1. Création du volume et ajout de la page index.html :
    • Création d'un volume Docker nommé nginx_volume.
    • Création d'un fichier index.html dans le volume nginx_volume contenant le code HTML suivant :
html
<h1>Bienvenue sur mon serveur Nginx !</h1>.
spacer
  1. Création et démarrage du conteneur Nginx : Instanciation d'un conteneur Nginx en spécifiant l'option -d pour le lancer en arrière-plan, l'option -p pour mapper le port 80 du conteneur au port de ton choix sur l'hôte, montage du volume nginx_volume dans le répertoire /usr/share/nginx/html du conteneur en utilisant l'option -v. Assure toi de spécifier le nom du conteneur et l'image Nginx à utiliser.
Bravo

Dépose ton script bash comme solution à ce challenge. Nomme le Nginx_prenom_nom.sh

🧐 Critères d'acceptation

Le script est fonctionnel et permet de créer un conteneur qui répond aux demandes. (Un test avec la commande curl permet de récupérer le contenu de la page web personnalisée du conteneur Nginx).