Table des matières
Workshop Docker : les conteneurs faciles
Page dédiée à la présentation de Docker
Préliminaires
Installer Docker
Pour installer docker avant de venir :
sudo apt install docker.io
Ou bien vous pouvez suivre la doc d'installation.
Vous devez etre dans le groupe docker pour pouvoir interagir avec le démon Docker sans passer par le user root. Pour cela :
sudo usermod -aG docker MON_USERNAME sudo su - MON_USERNAME id
Vous devez voir apparaitre le groupe docker dans la liste de vos groupes. Sinon, deconnectez votre session et reconnectez-vous pour que votre user aparaisse dans le groupe docker.
Télécharger les images du workshop
Nous aurons besoin de ces images :
docker pull alpine:3.18 docker pull nginx:latest docker pull python:3.8-alpine docker pull python:3.5-alpine docker pull mysql docker pull wordpress
Présentation des concepts
Différence entre Conteneur et VM
Une VM :
- Dispose d'un OS (système d'exploitation dédié) => potentiellement son OS est different de la machine hôte.
- A besoin d'un hyperviseur installé sur la machine physique hôte.
- A des ressources dédiées (RAM, CPU)
Un Conteneur :
- Partage son noyau linux avec celui de la machine physique hôte => Forcément le même OS que la machine hôte.
- Utilise les cgroup linux pour isoler des procéssus.
- Utilise les cgroup pour limiter les ressources attribuées.
Les Images Docker
Ce sont des archives de système de fichier. Elles sont versionnés avec des tags. Une image n'est rien de plus qu'une collection de dossiers et fichiers associée à une configuration de démarrage pour un conteneur.
La norme de nommage des images est la suivante : <registry>/<namespace>/<repository>:<tag>
- La registry par défaut si omise est généralement le dockerhub
- Le namespace par défaut est library, le namespace des images officielles administrés par Docker
- Le repository est le dépôt qui contient tout l'historique des images disponibles
- Le tag est la version de l'image (par défaut latest)
Exemple:
- alpine:3.18
- mysql
- ovhcom/venom:v1.1.0
docker pull alpine:3.18 ### Pull l'image alpine:3.18 sur la registry dockerhub par défaut. Le namespace par défaut est "library". docker images ### Liste les images présentes dans la registry local
Le Docker Hub
Ce qui permet vraiment une adoption très rapide de Docker, c'est son dockerhub. Il permet de partager des images Docker avec la communauté. Cela permet vraiment d'économiser beaucoup d'efforts, et de partager les bonnes idées et bonne pratiques pour construire des images.
Layered FS (Système de fichier multi couche)
Docker utilise les super cool Layered FS pour ses images. Un layered FS est un système de fichier qui enregistre les modifications sous forme de diff (différentiel ou patch). Chaque version peut être vu comme une couche du FS. La version actuelle des fichiers peut être vu comme la fusion de toutes les couches. Chaque image est associé dans Docker a un hash. Lorsque l'on applique une modification à une image, on créé une nouvelle couche par dessus l'image précédente.
Conteneur, runtime, image
Une image n'est pas un conteneur. Une image c'est principalement un FS qui est pré-paramétré. Un conteneur est l'enveloppe qui va être crée lors du runtime (de l’exécution) pour contenir ce FS et démarrer un processus dans cette enveloppe.
docker run alpine:3.18 echo "hello world" ### Démarre un conteneur basé sur l'image alpine:3.18, exécute à l’intérieur la commande 'echo "hello world"' puis rend la main. docker ps -a ### Liste tous les conteneurs sur la machine (démarrés ou arrêtés)
Les volumes
Le FS (systeme de fichier) d'un conteneur n'est pas persistant. A la destruction du conteneur, son FS est également détruit. Si l'on veut migrer un conteneur d'une version à une autre, on est forcé de le remplacer, on ne peut pas récupérer le FS du précédent conteneur. Pour répondre à cette problématique, Docker introduit "les volumes". Avec les volumes, Docker permet de "monter" au runtime n'importe quel répertoire de la machine hôte à l’intérieur d'un conteneur. Ainsi, si l'on configure certain volume, les données de nos conteneurs pourront être persistées en dehors de ceux-ci.
docker volume ls ### Liste les volumes. docker run alpine:3.18 sh -c "touch foo ; ls -l foo" ### Créé et liste un fichier dans un conteneur ls -l foo ### Liste ce fichier sur le host docker run alpine:3.18 ls -l foo ### Liste ce fichier dans un nouveau conteneur docker run -v $PWD:/tmp -w /tmp alpine:3.18 sh -c "touch foo" ### Crée ce fichier dans un conteneur donc le host current dir est monté dans work dir du conteneur (/tmp) ls -l foo ### Liste ce fichier sur le host
Exposition de ports
Chaque conteneur dispose de sa stack réseau. Par défaut, un service qui écoute sur un port dans le conteneur. Cela veut dire que vous devez connaitre l'IP de ce conteneur pour accéder au service depuis votre machine. Un mécanisme d'exposition de port au runtime permet de relier un port de sa machine hôte vers le port du conteneur que l'on démarre pour nous faciliter la vie.
docker run --name web -d -p 8080:80 nginx ### Démarre un conteneur nommé web basé sur l'image nginx:latest et map le port 8080 de l'hote sur le port 80 du conteneur. docker ps ### Liste les conteneurs démarrés sur la machine
Navigué sur l'URL : http://localhost:8080/
docker kill web ### Tue le conteneur nommé web. docker ps -a ### Liste tous les conteneurs sur la machine docker rm web ### Liste les conteneurs démarrés sur la machine docker ps -a ### Liste tous les conteneurs sur la machine
Le Dockerfile
Pour construire une Image Docker, on écrit un fichier Dockerfile. Ce fichier est composé de lignes de commandes qui vont constituer une par une, pour chaque ligne, une nouvelle image, un nouveau layer (une couche). Notre nouvelle image fraîchement construite sera constituée de toutes les couches empilées. Exemple de fichier Dockerfile
Reference
Exemples d'utilisation de Docker
Quelques commandes utiles
Lister tous les containers docker en train de tourner
docker ps
Lister aussi ceux qui sont arrêtés
docker ps -a
Arrêter un container en fonction de son id (première colonne de docker ps)
docker stop --time=20 container_id
Eliminer toutes les images Docker pour lesquelles les containers sont arrêtés et enlever les composantes réseau inutiles
docker system prune
Supprimer des containers en les listant au préalable
docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3975f606c258 collabora/code "/bin/sh -c 'bash st…" 51 minutes ago Exited (137) 17 minutes ago keen_booth b3a2766bbb87 hello-world "/hello" 53 minutes ago Exited (0) 53 minutes ago cranky_kowalevski
docker container rm 3975f606c258
docker network ls NETWORK ID NAME DRIVER SCOPE 107b8ac977e3 bridge bridge local ab998267377d host host local h520032c3d31 jenkins-overlay bridge local 3bc81b63f740 none null local
Virer un composant réseau :
docker network rm h520032c3d31
Supprimer l'interface docker0 définitivement
ip link delete docker0
Hello World
Utiliser un conteneur léger alpine linux pour executer une commande shell qui affiche "Hello World !". Documentation de l'image alpine
docker run --rm alpine:3.18 echo "Hello World !"
Lancer un shell dans un conteneur alpine linux.
docker run --rm -it alpine:3.18 sh
Pour sortir vous pouvez taper la la commande "exit" ou bien le raccourci "CTRL-D".
Executer un shell python v3.8 sans se préocuper de l'installation de python sur sa machine
docker run --rm -it python:3.8-alpine python
Reproduire un bug avec python 3.5 sans avoir à l'installer
docker run --rm -it python:3.5-alpine python
Démarrer un serveur mysql rapido en mode démon
Documentation de l'image mysql Pour démarrer le serveur et exposer le port 3306 du conteneur sur sa machine. _On précise que l'on n'utilise pas de mot de passe admin pour faire simple avec la variable d'environnement MYSQL_ALLOW_EMPTYPASSWORD=true tel qu'indiqué dans la documentation de l'image.
docker run --rm -d -p3306:3306 --name="ma_bd" -e "MYSQL_ALLOW_EMPTY_PASSWORD=true" mysql docker logs -f ma_bd
Pour connecter un client mysql au serveur depuis le conteneur démarré.
docker exec -it ma_bd
Pour tuer le conteneur de la BD.
docker kill ma_bd
Démarrer le dernier wordpress sans rien installer (as usual)
Documentation de l'image wordpress Le wordpress à besoin d'une BD pour fonctionner. On peut néanmoins constater que le service démarre bien.
docker run --rm wordpress
Démarrer un mysql + wordpress
On démarre les 2 conteneurs dans le meme réseau pour leur permettre de se parler. On configure le conteneur wordpress comme demandé sur la documentation de l'image.
docker network create wordpress docker run --rm -d --network=wordpress --name="ma_bd" -e "MYSQL_ALLOW_EMPTY_PASSWORD=true" mysql docker run --rm -d -p8080:80 --network=wordpress --name="mon_wordpress" -e "WORDPRESS_DB_HOST=ma_bd" -e "WORDPRESS_DB_USER=root" wordpress docker ps docker logs -f mon_wordpress
Et visiter la page http://localhost:8080.
Dockerfile
Pour travailler, il faut commencer par cloner le dépôt git d'exemple avec la commande suivante.
cd git clone https://github.com/mxbossard/dockerfile-example.git cd dockerfile-example
Puis vous pouvez suivre le contenu du fichier README.md situé à la racine du dépot git.
Docker compose
Un autre dépot à cloner pour travailler sur le sujet docker-compose avec la commande suivante :
cd git clone https://github.com/mxbossard/docker-compose-example.git cd docker-compose-example
Puis vous pouvez suivre le contenu du fichier README.md situé à la racine du dépot git.
Retours
- A quoi sert Docker ? => Des exemples d'utilisations plus concretes. Un atelier pour des cas d'usages courants ?
- Doc d'install de docker-compose ?