TP1 WIP
This commit is contained in:
parent
fe77666200
commit
7a1d5d9981
|
@ -3,7 +3,7 @@
|
||||||
Faire le ménage
|
Faire le ménage
|
||||||
===============
|
===============
|
||||||
|
|
||||||
Au fur et à mesure de vos tests, la taille utilisée par les données de Docker
|
Au fur et à mesure de nos tests, la taille utilisée par les données de Docker
|
||||||
peut devenir conséquente et son interface peut commencer à déborder
|
peut devenir conséquente et son interface peut commencer à déborder
|
||||||
d'informations dépréciées.
|
d'informations dépréciées.
|
||||||
|
|
||||||
|
@ -11,31 +11,32 @@ Dans la mesure du possible, Docker essai de ne pas encombrer inutilement votre
|
||||||
disque dur avec les vieilles images qui ne sont plus utilisées. Il ne va
|
disque dur avec les vieilles images qui ne sont plus utilisées. Il ne va
|
||||||
cependant jamais supprimer une image encore liée à un conteneur ; il ne
|
cependant jamais supprimer une image encore liée à un conteneur ; il ne
|
||||||
supprimera pas non plus les conteneurs qui n'auront pas été démarrés avec
|
supprimera pas non plus les conteneurs qui n'auront pas été démarrés avec
|
||||||
`--rm`.
|
l'option `--rm`.
|
||||||
|
|
||||||
|
|
||||||
## Conteneurs
|
## Conteneurs
|
||||||
|
|
||||||
Vous pouvez afficher l'ensemble des conteneurs, quelque soit leur état (en
|
Vous pouvez afficher l'ensemble des conteneurs, quelque soit leur état (en
|
||||||
cours d'exécution, arrêté, ...) avec la commande suivante :
|
cours d'exécution, arrêtés, ...) avec la commande suivante :
|
||||||
|
|
||||||
```
|
```
|
||||||
42sh$ docker ps -a
|
42sh$ docker container ls -a
|
||||||
CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES
|
CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES
|
||||||
552d71619723 hello-world "/hello" 4 days ago Exited (0) 4 days ago dreamy_gates
|
552d71619723 hello-world "/hello" 4 days ago Exited (0) 4 days ago dreamy_gates
|
||||||
0e8bbff6d500 debian "/bin/bash" 2 weeks ago Exited (0) 2 weeks ago cranky_jones
|
0e8bbff6d500 debian "/bin/bash" 2 weeks ago Exited (0) 2 weeks ago cranky_jones
|
||||||
```
|
```
|
||||||
|
|
||||||
IL y a de fortes chances pour que vous n'ayez plus besoin de ces vieux
|
Il y a de fortes chances pour que vous n'ayez plus besoin de ces vieux
|
||||||
conteneurs. Pour les supprimer, utilisez la commande :
|
conteneurs. Pour les supprimer, utilisez la commande :
|
||||||
|
|
||||||
```
|
```
|
||||||
docker rm 0e8bbff6d500 552d71619723
|
docker container rm 0e8bbff6d500 552d71619723
|
||||||
```
|
```
|
||||||
|
|
||||||
ou encore :
|
ou encore :
|
||||||
|
|
||||||
```
|
```
|
||||||
docker rm cranky_jones dreamy_gates
|
docker container rm cranky_jones dreamy_gates
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,12 +45,18 @@ docker rm cranky_jones dreamy_gates
|
||||||
Les vieilles images qui n'ont plus de références sur elles (ni tag, ni
|
Les vieilles images qui n'ont plus de références sur elles (ni tag, ni
|
||||||
conteneur lié) sont automatiques supprimées. Vous n'avez généralement pas à
|
conteneur lié) sont automatiques supprimées. Vous n'avez généralement pas à
|
||||||
vous occuper de faire du nettoyage dans les images. Néanmoins, vous pouvez les
|
vous occuper de faire du nettoyage dans les images. Néanmoins, vous pouvez les
|
||||||
lister avec la commande `docker images` et en supprimer grâce à la commande
|
gérer de la même manière que les conteneurs, avec les sous-commandes `docker
|
||||||
`docker rmi`.
|
image`.
|
||||||
|
|
||||||
|
|
||||||
|
## `prune`
|
||||||
|
|
||||||
|
Dans la plupart des menus permettant de gérer les objets Docker, vous trouverez
|
||||||
|
une commande `prune` qui supprimera les objets inutilisés.
|
||||||
|
|
||||||
|
|
||||||
## `docker-gc`
|
## `docker-gc`
|
||||||
|
|
||||||
Vous pouvez également utiliser l'image <https://github.com/spotify/docker-gc>
|
Vous pouvez également utiliser l'image <https://github.com/spotify/docker-gc>
|
||||||
pour effectuer le ménage de manière automatique, plus fréquemment. Attention à
|
pour effectuer le ménage de manière automatique, plus fréquemment. Mais
|
||||||
vos données !
|
attention à vos données !
|
||||||
|
|
|
@ -5,10 +5,10 @@
|
||||||
|
|
||||||
## Mon premier conteneur ... par `Dockerfile`
|
## Mon premier conteneur ... par `Dockerfile`
|
||||||
|
|
||||||
Pour construire une image, vous n'êtes pas obligé de passer par une série de
|
Pour construire une image, nous ne sommes pas obligés de passer par une série
|
||||||
commits. Docker dispose d'un mécanisme permettant d'automatiser la construction
|
de commits. Docker dispose d'un mécanisme permettant d'automatiser la
|
||||||
de nouvelles images. Vous pouvez arriver au même résultat que ce que l'on a
|
construction de nouvelles images. Vous pouvez arriver au même résultat que ce
|
||||||
réussi à faire précédemment en utilisant le Docker file suivant :
|
que l'on a réussi à faire précédemment en utilisant le `Dockerfile` suivant :
|
||||||
|
|
||||||
```
|
```
|
||||||
FROM ubuntu:latest
|
FROM ubuntu:latest
|
||||||
|
@ -30,14 +30,14 @@ contenant que votre fichier `Dockerfile`, placez-vous dedans, puis utilisez la
|
||||||
commande `build` :
|
commande `build` :
|
||||||
|
|
||||||
```
|
```
|
||||||
docker build --tag=my_editor .
|
docker image build --tag=my_editor .
|
||||||
```
|
```
|
||||||
|
|
||||||
Une fois la construction de l'image terminée, vous pouvez la lancer et
|
Une fois la construction de l'image terminée, vous pouvez la lancer et
|
||||||
constater l'existence de notre éditeur favori :
|
constater l'existence de notre éditeur favori :
|
||||||
|
|
||||||
```
|
```
|
||||||
docker run -it my_editor /bin/bash
|
docker container run -it my_editor /bin/bash
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -91,8 +91,8 @@ redirection de port aléatoire sur la machine hôte vers votre
|
||||||
conteneur :
|
conteneur :
|
||||||
|
|
||||||
```
|
```
|
||||||
docker build --tag=my_webserver .
|
docker image build --tag=my_webserver .
|
||||||
docker run -it -P my_webserver /bin/bash
|
docker container run -it -P my_webserver /bin/bash
|
||||||
service nginx start
|
service nginx start
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -116,8 +116,8 @@ CMD nginx -g "daemon off;"
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
docker build --tag=my_nginx .
|
docker image build --tag=my_nginx .
|
||||||
docker run -d -P my_nginx
|
docker container run -d -P my_nginx
|
||||||
```
|
```
|
||||||
|
|
||||||
L'option `-d` passée au `run` lance le conteneur en tâche de
|
L'option `-d` passée au `run` lance le conteneur en tâche de
|
||||||
|
@ -134,38 +134,6 @@ des instructions reconnues.
|
||||||
|
|
||||||
## Rendu
|
## Rendu
|
||||||
|
|
||||||
### Exercice
|
|
||||||
|
|
||||||
Rendez le fichier `Dockerfile` et son contexte (`index.html`, fichiers de conf
|
Rendez le fichier `Dockerfile` et son contexte (`index.html`, fichiers de conf
|
||||||
éventuels, ...) que vous avez utiliser pour réaliser votre image
|
éventuels, ...) que vous avez utiliser pour réaliser votre image
|
||||||
`my_webserver`.
|
`my_webserver`.
|
||||||
|
|
||||||
### Questions
|
|
||||||
|
|
||||||
1. De combien de couches de systèmes de fichiers est composé votre image
|
|
||||||
`my_webserver` ? Justifiez votre décompte. Comment pourriez-vous en avoir
|
|
||||||
moins ?
|
|
||||||
|
|
||||||
1. On a vu comment créer une nouvelle image à partir d'une image existante
|
|
||||||
(`FROM`). Mais comment sont créés ces images de bases (comme debian ou
|
|
||||||
ubuntu) ?
|
|
||||||
|
|
||||||
1. Quels sont les avantages de ce `RUN` :
|
|
||||||
|
|
||||||
```
|
|
||||||
RUN apt-get update && \
|
|
||||||
apt-get install -y \
|
|
||||||
nginx \
|
|
||||||
php5-fpm \
|
|
||||||
php5-mysql \
|
|
||||||
php5-gd \
|
|
||||||
&& apt-get clean && \
|
|
||||||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
|
||||||
```
|
|
||||||
|
|
||||||
par rapport aux précédents exemples :
|
|
||||||
|
|
||||||
```
|
|
||||||
RUN apt-get update
|
|
||||||
RUN apt-get install -y nginx php5-fpm php5-mysql php5-gd
|
|
||||||
```
|
|
||||||
|
|
|
@ -3,10 +3,11 @@
|
||||||
Mon premier conteneur
|
Mon premier conteneur
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
Afin de tester la bonne marche de votre installation, exécutons la commande :
|
Afin de tester la bonne marche de notre installation, lançons notre premier
|
||||||
|
conteneur avec la commande :
|
||||||
|
|
||||||
```
|
```
|
||||||
docker run hello-world
|
docker container run hello-world
|
||||||
```
|
```
|
||||||
|
|
||||||
Cette commande va automatiquement exécuter une série de commandes pour nous,
|
Cette commande va automatiquement exécuter une série de commandes pour nous,
|
||||||
|
@ -14,45 +15,59 @@ comme indiqué dans le message affiché en retour :
|
||||||
|
|
||||||
D'abord, le daemon va rechercher s'il possède localement l'image
|
D'abord, le daemon va rechercher s'il possède localement l'image
|
||||||
*hello-world*. Si ce n'est pas le cas, il va aller la récupérer sur
|
*hello-world*. Si ce n'est pas le cas, il va aller la récupérer sur
|
||||||
`hub.docker.com`. Ce site met à disposition un grand nombre d'images : des
|
`store.docker.com`. Ce site met à disposition un grand nombre d'images : des
|
||||||
systèmes de base comme Ubuntu, Debian, Centos, etc. jusqu'à des conteneurs
|
systèmes de base comme Ubuntu, Debian, Centos, etc. jusqu'à des conteneurs
|
||||||
prêts à l'emploi : le serveur web nginx, la base de données MySQL, un serveur
|
prêts à l'emploi : le serveur web nginx, la base de données MySQL, un serveur
|
||||||
node.js, etc.
|
node.js, etc.
|
||||||
|
|
||||||
Nous pouvons directement utiliser le client pour rechercher une image sur le
|
Nous pouvons directement utiliser le client pour rechercher une image sur le
|
||||||
hub, en utilisant la commande `search` :
|
Store, en utilisant la commande `search` :
|
||||||
|
|
||||||
```
|
```
|
||||||
docker search mariadb
|
docker search mariadb
|
||||||
```
|
```
|
||||||
|
|
||||||
Il est possible de mettre à jour les images locales ou simplement
|
Il est possible de mettre à jour les images locales ou simplement
|
||||||
pré-télécharger des images depuis le hub en utilisant la commande `pull` :
|
pré-télécharger des images depuis le Store en utilisant la commande `pull` :
|
||||||
|
|
||||||
```
|
```
|
||||||
docker pull ubuntu
|
docker image pull ubuntu
|
||||||
```
|
```
|
||||||
|
|
||||||
Pour consulter la liste des images dont nous disposons localement (soit parce
|
Remarquez comment on interagit avec chaque *objet Docker* : dans la ligne de
|
||||||
qu'on les a téléchargées, soit parce que nous les avons créées nous-même), on
|
commande, le premier mot clef est le type d'objet (`container`, `image`,
|
||||||
utilise la commande `images` :
|
`service`, `network`, `volume`, ...) ; ensuite, vient l'action que l'on
|
||||||
|
souhaite faire dans ce cadre.[^oldcall]
|
||||||
|
|
||||||
|
[^oldcall]: cela n'a pas toujours été aussi simple, cette syntaxe n'existe que
|
||||||
|
depuis la version 1.13 (janvier 2017). C'est pourquoi, lorsque vous ferez
|
||||||
|
des recherches sur internet, vous trouverez de nombreux articles utilisant
|
||||||
|
l'ancienne syntaxe, sans le type d'objets : `docker images` au lieu de
|
||||||
|
`docker image ls`, `docker run` au lieu de `docker container run`, ...
|
||||||
|
|
||||||
|
L'ancienne syntaxe est dépréciée, mais il reste actuellement possible de
|
||||||
|
l'utiliser.
|
||||||
|
|
||||||
|
Par exemple, pour consulter la liste des images dont nous disposons localement
|
||||||
|
(soit parce qu'on les a téléchargées, soit parce que nous les avons créées
|
||||||
|
nous-même), on utilise la commande `ls` sous le type d'objets `image` :
|
||||||
|
|
||||||
```
|
```
|
||||||
docker images
|
docker image ls
|
||||||
```
|
```
|
||||||
|
|
||||||
Vous devriez constater la présence de plusieurs images « Ubuntu », mais chacune
|
Vous devriez constater la présence de plusieurs images « Ubuntu », mais chacune
|
||||||
a un *TAG* différent. En effet, souven, il existe plusieurs versions d'une même
|
a un *TAG* différent. En effet, souven, il existe plusieurs versions d'une même
|
||||||
image. Pour Ubuntu par exemple, nous avons la possibilité de lancer la version
|
image. Pour Ubuntu par exemple, nous avons la possibilité de lancer la version
|
||||||
`precise`, `trusty`, `xenial` ou `yakkety`.
|
`trusty`, `xenial`, `zesty` ou `artful`.
|
||||||
|
|
||||||
Chaque image est identifiable par son *Image ID* unique ; les noms d'images
|
Chaque image est identifiable par son *Image ID* unique ; les noms d'images
|
||||||
ainsi que leurs tags sont, comme les tags Git, une manière humainement plus
|
ainsi que leurs tags sont, comme les tags Git, une manière humainement plus
|
||||||
simple de faire référence aux identifiants.
|
simple de faire référence aux identifiants.
|
||||||
|
|
||||||
Chaque nom d'image possède au moins un tag associé : *latest*. C'est le tag qui
|
Chaque nom d'image possède au moins un tag associé par défaut : *latest*. C'est
|
||||||
est automatiquement recherché lorsque l'on ne le précisez pas en lançant
|
le tag qui est automatiquement recherché lorsque l'on ne le précisez pas en
|
||||||
l'image.
|
lançant l'image.
|
||||||
|
|
||||||
|
|
||||||
## Exécuter un programme dans un conteneur
|
## Exécuter un programme dans un conteneur
|
||||||
|
@ -65,7 +80,7 @@ lancer dans le conteneur ainsi que ses éventuels arguments. Essayons d'afficher
|
||||||
un Hello World :
|
un Hello World :
|
||||||
|
|
||||||
```
|
```
|
||||||
docker run ubuntu /bin/echo "Hello World"
|
docker container run ubuntu /bin/echo "Hello World"
|
||||||
```
|
```
|
||||||
|
|
||||||
Dans notre exemple, c'est bien le `/bin/echo` présent dans le conteneur qui est
|
Dans notre exemple, c'est bien le `/bin/echo` présent dans le conteneur qui est
|
||||||
|
@ -78,7 +93,7 @@ n'utilisez pas [Alpine Linux](https://www.alpine-linux.org), vous pourriez
|
||||||
tenter d'utiliser son gestionnaire de paquet `apk`, via :
|
tenter d'utiliser son gestionnaire de paquet `apk`, via :
|
||||||
|
|
||||||
```
|
```
|
||||||
docker run alpine /sbin/apk stats
|
docker container run alpine /sbin/apk stats
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -111,7 +126,7 @@ créer une nouvelle image à partir de ce conteneur.
|
||||||
Pour créer une image, commençons par entrer dans un nouveau conteneur :
|
Pour créer une image, commençons par entrer dans un nouveau conteneur :
|
||||||
|
|
||||||
```
|
```
|
||||||
docker run -it ubuntu /bin/bash
|
docker container run -it ubuntu /bin/bash
|
||||||
```
|
```
|
||||||
|
|
||||||
Vous avez remarqué l'utilisation des options `--tty` et `--interactive` ? Avant
|
Vous avez remarqué l'utilisation des options `--tty` et `--interactive` ? Avant
|
||||||
|
@ -120,13 +135,13 @@ du `run`. En fait, tout comme `git(1)` et ses sous-commandes, chaque niveau de
|
||||||
commande peut prendre des paramètres :
|
commande peut prendre des paramètres :
|
||||||
|
|
||||||
```
|
```
|
||||||
docker DOCKER_PARAMS run RUN_OPTS image IMAGE_CMD IMAGE_ARGS ...
|
docker DOCKER_PARAMS container run RUN_OPTS image IMAGE_CMD IMAGE_ARGS ...
|
||||||
```
|
```
|
||||||
|
|
||||||
Par exemple :
|
Par exemple :
|
||||||
|
|
||||||
```
|
```
|
||||||
docker -H unix:///var/run/docker.sock run -it alpine /bin/ash -c "echo foo"
|
docker -H unix:///var/run/docker.sock container run -it alpine /bin/ash -c "echo foo"
|
||||||
```
|
```
|
||||||
|
|
||||||
Ici, l'option `-H` sera traitée par le client Docker (pour définir
|
Ici, l'option `-H` sera traitée par le client Docker (pour définir
|
||||||
|
@ -136,11 +151,9 @@ simplement tranmis au conteneur comme argument au premier `execve(2)` du
|
||||||
conteneur.
|
conteneur.
|
||||||
|
|
||||||
Avec l'option `--interactive`, on s'assure que l'entrée standard ne sera pas
|
Avec l'option `--interactive`, on s'assure que l'entrée standard ne sera pas
|
||||||
fermée (`close(2)`)[^whyclose]. Nous demandons également l'allocation d'un TTY,
|
fermée (`close(2)`). Nous demandons également l'allocation d'un TTY,
|
||||||
sans quoi `bash` ne se lancera pas en mode interractif[^bashnointer].
|
sans quoi `bash` ne se lancera pas en mode interractif[^bashnointer].
|
||||||
|
|
||||||
[^whyclose]: TODO
|
|
||||||
|
|
||||||
[^bashnointer]: Mais il sera possible de l'utiliser sans allouer de TTY, comme
|
[^bashnointer]: Mais il sera possible de l'utiliser sans allouer de TTY, comme
|
||||||
par exemple en faisant :
|
par exemple en faisant :
|
||||||
|
|
||||||
|
@ -155,11 +168,10 @@ sans quoi `bash` ne se lancera pas en mode interractif[^bashnointer].
|
||||||
transmise au conteneur.
|
transmise au conteneur.
|
||||||
|
|
||||||
|
|
||||||
### Modification interractive
|
### Modification interactive
|
||||||
|
|
||||||
Nous voilà maintenant dans le conteneur ! Il est assez épuré, il n'y a rien
|
Nous voilà maintenant dans le conteneur ! Il est assez épuré, il n'y a rien de
|
||||||
de superflu : il n'y a même pas d'éditeur de texte : ni vim, ni emacs, même pas
|
superflu : même pas d'éditeur de texte : ni vim, ni emacs, même pas `vi` !
|
||||||
`vi` !
|
|
||||||
|
|
||||||
La première chose à faire est de télécharger la liste des paquets. En effet,
|
La première chose à faire est de télécharger la liste des paquets. En effet,
|
||||||
afin de ne pas livrer de superflu, la liste des paquets et son cache ne sont
|
afin de ne pas livrer de superflu, la liste des paquets et son cache ne sont
|
||||||
|
@ -199,7 +211,7 @@ Sauvegardez votre image modifiée avec la commande `commit` pour pouvoir
|
||||||
commencer directement de votre image avec `nano` :
|
commencer directement de votre image avec `nano` :
|
||||||
|
|
||||||
```
|
```
|
||||||
docker commit CONTAINER my_nano
|
docker container commit CONTAINER my_nano
|
||||||
```
|
```
|
||||||
|
|
||||||
En remplaçant `CONTAINER` par le nom ou l'identifiant de votre
|
En remplaçant `CONTAINER` par le nom ou l'identifiant de votre
|
||||||
|
@ -207,7 +219,7 @@ container. `my_nano` est le nom que vous voudrez utiliser à la place
|
||||||
d'`ubuntu` :
|
d'`ubuntu` :
|
||||||
|
|
||||||
```
|
```
|
||||||
docker run -it my_nano /bin/bash
|
docker container run -it my_nano /bin/bash
|
||||||
```
|
```
|
||||||
|
|
||||||
Vous constatez cette fois que vous pouvez lancer `nano`, alors que vous ne
|
Vous constatez cette fois que vous pouvez lancer `nano`, alors que vous ne
|
||||||
|
|
|
@ -23,7 +23,7 @@ x86_64
|
||||||
Assurez-vous également d'avoir un noyau récent, avec la commande `uname -r` :
|
Assurez-vous également d'avoir un noyau récent, avec la commande `uname -r` :
|
||||||
|
|
||||||
```
|
```
|
||||||
4.7.2-gentoo
|
4.13.4-gentoo
|
||||||
```
|
```
|
||||||
|
|
||||||
Vous ne pourrez pas utiliser Docker avec un noyau antérieur à la version 3.10.
|
Vous ne pourrez pas utiliser Docker avec un noyau antérieur à la version 3.10.
|
||||||
|
@ -40,9 +40,33 @@ version déjà bien éprouvée, pour ce cours, nous allons avoir besoin de la
|
||||||
dernière version disponible. Référez-vous à la documentation officielle
|
dernière version disponible. Référez-vous à la documentation officielle
|
||||||
correspondant à votre distribution :
|
correspondant à votre distribution :
|
||||||
|
|
||||||
<https://docs.docker.com/engine/installation/linux/>
|
<https://docs.docker.com/engine/installation/linux/docker-ce/debian/>
|
||||||
|
|
||||||
Installez également le paquet `docker-compose`.
|
|
||||||
|
### Versions de Docker
|
||||||
|
|
||||||
|
Historiquement, Docker est un projet open-source. Depuis peu, le business-model
|
||||||
|
de la société a évolué et ils proposent désormais deux éditions : *Community
|
||||||
|
Edition* et *Enterprise Edition*. La seconde est payante et possède un certain
|
||||||
|
nombre d'atouts pour faciliter son adoption en entreprise (notamment pas mal
|
||||||
|
d'interface graphique, etc.). Le cœur de la technologie est quant à lui
|
||||||
|
entièrement présent dans l'édition communautaire.
|
||||||
|
|
||||||
|
Depuis mars dernier, les numéros de version de Docker sont tirés de l'année et
|
||||||
|
du mois de parution (comme on a l'habitude avec Ubuntu 16.04 par exemple). Le
|
||||||
|
rythme actuel de parution est d'une version par trimestre (mars, juin,
|
||||||
|
septembre, décembre).[^versions]
|
||||||
|
|
||||||
|
[^versions]: Tous les détails sur les versions (CE/EE et numérotation,
|
||||||
|
fréquences, ...) sont résumés dans cette annonce :
|
||||||
|
<https://blog.docker.com/2017/03/docker-enterprise-edition/>
|
||||||
|
|
||||||
|
|
||||||
|
## Évaluation en ligne
|
||||||
|
|
||||||
|
Si vous rencontrez des difficultés pour vous lancer, le projet
|
||||||
|
[Play With Docker](https://play-with-docker.com/) vous donne accès à
|
||||||
|
un bac à sable dans lequel vous pourrez commencer à faire ce TP.
|
||||||
|
|
||||||
|
|
||||||
## Vérifier la bonne marche de l'installation
|
## Vérifier la bonne marche de l'installation
|
||||||
|
@ -57,20 +81,21 @@ Une sortie similaire au bloc suivant devrait apparaître sur votre écran :
|
||||||
|
|
||||||
```
|
```
|
||||||
Client:
|
Client:
|
||||||
Version: 1.12.1
|
Version: 17.09.0-ce
|
||||||
API version: 1.24
|
API version: 1.32
|
||||||
Go version: go1.7
|
Go version: go1.9
|
||||||
Git commit: 23cf638
|
Git commit: cec0b72
|
||||||
Built:
|
Built: Thu Sep 14 19:57:50 2017
|
||||||
OS/Arch: linux/amd64
|
OS/Arch: linux/amd64
|
||||||
|
|
||||||
Server:
|
Server:
|
||||||
Version: 1.12.1
|
Version: 17.09.0-ce
|
||||||
API version: 1.24
|
API version: 1.32 (minimum version 1.12)
|
||||||
Go version: go1.7
|
Go version: go1.9
|
||||||
Git commit: 23cf638
|
Git commit: cec0b72
|
||||||
Built:
|
Built: Thu Sep 14 21:50:58 2017
|
||||||
OS/Arch: linux/amd64
|
OS/Arch: linux/amd64
|
||||||
|
Experimental: false
|
||||||
```
|
```
|
||||||
|
|
||||||
### `no such file or directory`?
|
### `no such file or directory`?
|
||||||
|
@ -95,14 +120,3 @@ sudo gpasswd -a $USER docker
|
||||||
|
|
||||||
**Attention :** cette action n'est pas anodine d'un point de vue sécurité :
|
**Attention :** cette action n'est pas anodine d'un point de vue sécurité :
|
||||||
<https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface>
|
<https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface>
|
||||||
|
|
||||||
|
|
||||||
## Rendu
|
|
||||||
|
|
||||||
### Questions
|
|
||||||
|
|
||||||
1. Dans quel langage Docker a-t-il été écrit ?
|
|
||||||
|
|
||||||
1. Décrivez une méthode permettant à un utilisateur (non-root), présent dans le
|
|
||||||
groupe `docker`, d'effectuer une action privilégiée impactant la machine
|
|
||||||
hôte.
|
|
||||||
|
|
|
@ -3,34 +3,7 @@
|
||||||
Lier les conteneurs
|
Lier les conteneurs
|
||||||
===================
|
===================
|
||||||
|
|
||||||
En plus de vouloir partager des répertoires entre deux conteneurs, il est
|
|
||||||
souvent nécessaire de partager des ports.
|
|
||||||
|
|
||||||
Pour automatiser le partage d'informations sur les IP et ports exposés, la
|
|
||||||
commande `run` possède l'option `--link` qui permet de définir dans les
|
|
||||||
variables d'environnement du conteneur que l'on va lancer.
|
|
||||||
|
|
||||||
Le détail des variables ajoutées dans cette situation est disponible dans
|
|
||||||
[la documentation de Docker](https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/#environment-variables).
|
|
||||||
|
|
||||||
On utilise généralement cette liaison pour fournir au conteneur hébergeant un
|
## Le pont `docker0`
|
||||||
site web dynamique l'IP et le port où trouver la base de données :
|
|
||||||
|
|
||||||
```
|
|
||||||
docker run -e MYSQL_ROOT_PASSWORD=mysecretpassword -d --name db1 mysql
|
|
||||||
docker run --link db1 my_nginx
|
|
||||||
```
|
|
||||||
|
|
||||||
## Ambasador
|
|
||||||
|
|
||||||
Afin d'abstraire le plus possible l'infrastructure sous-jacente et d'autoriser
|
|
||||||
les migrations de conteneurs, on utilise le modèle *ambassador*.
|
|
||||||
|
|
||||||
On lancera systématiquement un conteneur entre deux conteneurs que l'on veut
|
|
||||||
lier : l'ambassadeur. Celui-ci s'occupera de router correctement le trafic. En
|
|
||||||
cas de changement de route (si l'un des conteneurs change de machine hôte par
|
|
||||||
exemple), on a simplement à redémarrer l'ambassadeur plutôt que le conteneur
|
|
||||||
principal.
|
|
||||||
|
|
||||||
La documentation officielle pour ce modèle est disponible à
|
|
||||||
<https://docs.docker.com/engine/admin/ambassador_pattern_linking/>.
|
|
||||||
|
|
|
@ -26,8 +26,8 @@ programme à lancer et ses arguments.
|
||||||
|
|
||||||
## Modalité de rendu
|
## Modalité de rendu
|
||||||
|
|
||||||
Un service automatique s'occupe de réceptionner vos rendus, de faire les
|
Un service automatique s'occupe de réceptionner vos rendus, de faire des
|
||||||
vérifications nécessaires et de vous envoyer un accusé de réception (ou de
|
vérifications élémentaires et de vous envoyer un accusé de réception (ou de
|
||||||
rejet).
|
rejet).
|
||||||
|
|
||||||
Ce service écoute sur l'adresse <virli@nemunai.re>, c'est donc à cette adresse
|
Ce service écoute sur l'adresse <virli@nemunai.re>, c'est donc à cette adresse
|
||||||
|
@ -35,19 +35,18 @@ et exclusivement à celle-ci que vous devez envoyer vos rendus. Tout rendu
|
||||||
envoyé à une autre adresse et/ou non signé et/ou reçu après la correction ne
|
envoyé à une autre adresse et/ou non signé et/ou reçu après la correction ne
|
||||||
sera pas pris en compte.
|
sera pas pris en compte.
|
||||||
|
|
||||||
|
Par ailleurs, n'oubliez pas de répondre à
|
||||||
|
[l'évaluation du cours](https://www.epitaf.fr/moodle/mod/quiz/view.php?id=20).
|
||||||
|
|
||||||
|
|
||||||
## Tarball
|
## Tarball
|
||||||
|
|
||||||
Tous les fichiers identifiés comme étant à rendre pour ce TP sont à
|
Tous les fichiers identifiés comme étant à rendre pour ce TP sont à
|
||||||
placer dans une tarball (pas d'archive ZIP, RAR, ...).
|
placer dans une tarball (pas d'archive ZIP, RAR, ...).
|
||||||
|
|
||||||
Les réponses aux questions sont à regrouper dans un fichier `questions.txt` à
|
|
||||||
placer à la racine de votre rendu.
|
|
||||||
|
|
||||||
Voici une arborescence type:
|
Voici une arborescence type:
|
||||||
|
|
||||||
```
|
```
|
||||||
login_x-TP1/questions.txt
|
|
||||||
login_x-TP1/webserver
|
login_x-TP1/webserver
|
||||||
login_x-TP1/webserver/Dockerfile
|
login_x-TP1/webserver/Dockerfile
|
||||||
login_x-TP1/webserver/index.html
|
login_x-TP1/webserver/index.html
|
||||||
|
@ -100,8 +99,8 @@ gpg: Can't check signature: No public key
|
||||||
C'est que votre clef publique n'est pas dans mon trousseau et que les méthodes
|
C'est que votre clef publique n'est pas dans mon trousseau et que les méthodes
|
||||||
de récupérations automatiques n'ont pas permis de la trouver. Uploadez votre
|
de récupérations automatiques n'ont pas permis de la trouver. Uploadez votre
|
||||||
clef sur un serveur de clefs (et attendez quelques minutes sa propagation) ou
|
clef sur un serveur de clefs (et attendez quelques minutes sa propagation) ou
|
||||||
envoyez un courriel avec votre clef publique en pièce-jointe, avant de retenter
|
envoyez un courriel au service avec votre clef publique en pièce-jointe, avant
|
||||||
votre rendu.
|
de retenter votre rendu.
|
||||||
|
|
||||||
|
|
||||||
#### Not explicit username
|
#### Not explicit username
|
||||||
|
@ -115,3 +114,16 @@ Si vous recevez un rapport avec l'erreur suivante :
|
||||||
Votre clef ne contient sans doute pas vos noms et prénoms ou l'adresse
|
Votre clef ne contient sans doute pas vos noms et prénoms ou l'adresse
|
||||||
électronique associée à la clef n'est pas celle que j'ai dans ma base de
|
électronique associée à la clef n'est pas celle que j'ai dans ma base de
|
||||||
données.
|
données.
|
||||||
|
|
||||||
|
|
||||||
|
#### I've decided to skip your e-mail
|
||||||
|
|
||||||
|
Si vous recevez un rapport concluant ainsi :
|
||||||
|
|
||||||
|
```
|
||||||
|
After analyzing your e-mail, I've decided to SKIP it.
|
||||||
|
```
|
||||||
|
|
||||||
|
Cela signifie que la lecture de votre courriel qui a été de préférée n'est pas
|
||||||
|
celle d'un rendu. Vérifiez que vous n'envoyez pas votre clef publique avec
|
||||||
|
votre rendu.
|
||||||
|
|
|
@ -8,7 +8,7 @@ date: Jeudi 5 octobre 2017
|
||||||
|
|
||||||
Durant ce premier TP, nous allons apprendre à utiliser Docker !
|
Durant ce premier TP, nous allons apprendre à utiliser Docker !
|
||||||
|
|
||||||
Tous les éléments de ce TP (exercices et questions) sont à rendre à
|
Tous les éléments de ce TP (exercices et projet) sont à rendre à
|
||||||
<virli@nemunai.re> au plus tard le jeudi 19 octobre 2017 à 8 h 42. Consultez la
|
<virli@nemunai.re> au plus tard le jeudi 19 octobre 2017 à 8 h 42. Consultez la
|
||||||
dernière section de chaque partie pour plus d'information sur les éléments à
|
dernière section de chaque partie pour plus d'information sur les éléments à
|
||||||
rendre.
|
rendre.
|
||||||
|
|
|
@ -1,33 +1,7 @@
|
||||||
\newpage
|
\newpage
|
||||||
|
|
||||||
Volumes
|
Stockage de données applicatives
|
||||||
=======
|
================================
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
Le concept principal de Docker est de concevoir des conteneurs applicatifs : on
|
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
|
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
|
en créant un groupe de conteneur, partageant des données entre-eux par des
|
||||||
volumes.
|
volumes.
|
||||||
|
|
||||||
Une lecture intéressante sur ce sujet est sans doute [cet article de Michael
|
Il est possible d'utiliser la dernière couche en lecture/écriture pour inscrire
|
||||||
Crosby](http://crosbymichael.com/advanced-docker-volumes.html).
|
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
|
## 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 :
|
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
|
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 !
|
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
|
Les volumes sont des espaces créés via Docker (il s'agit d'objets Docker). Ils
|
||||||
l'application, et donc d'avoir un conteneur exécutant l'application et un
|
permettent de partager facilement des données entre conteneurs, sans avoir à se
|
||||||
second stockant les données.
|
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
|
Comme il s'agit d'un objet, la première chose à faire va être de créer notre
|
||||||
avec un conteneur dont le seul rôle est de stocker les données.
|
volume :
|
||||||
|
|
||||||
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 :
|
|
||||||
|
|
||||||
```
|
```
|
||||||
docker create -v /var/lib/mysql --name dbdata busybox /bin/true
|
docker volume create prod_db
|
||||||
docker run --volume-from dbdata -e MYSQL_ROOT_PASSWORD=mysecretpassword -d mysql
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Le premier conteneur, sans commande passée, va s'arrêter dès son
|
Ensuite, nous pouvons démarrer un conteneur l'utilisant, par exemple :
|
||||||
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.
|
|
||||||
|
|
||||||
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
|
Lorsque le volume est vide, si des données sont présentes à l'endroit du point
|
||||||
seront pas perdues (et s'il y avait besoin de migrer les données entre les deux
|
de montage, celles-ci sont recopiées dans le volume.
|
||||||
versions des conteneurs, un conteneur intermédiaire pourrait parfaitement s'en
|
|
||||||
charger).
|
|
||||||
|
|
||||||
Cela facile également les sauvegardes, qui peuvent s'exécuter dans un conteneur
|
Si plus tard, vous souhaitez créer un conteneur chargé de faire des
|
||||||
distinct, dédié à la tâche de sauvegarde.
|
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
|
## Rendu
|
||||||
|
|
||||||
### Exercice
|
### Exercice
|
||||||
|
|
||||||
Modifiez le `Dockerfile` de l'exercice précédent pour que votre application web
|
Modifiez le `Dockerfile` de l'exercice précédent pour que les logs de votre
|
||||||
(ok, c'est juste un `index.html` ...) soit contenue dans un *data volume
|
application web (ok, c'est juste un `index.html` ...) soient contenus dans un
|
||||||
container*.
|
*volume*.
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
|
@ -8,13 +8,17 @@ Docker est un écosystème d'outils de haut niveau, permettant d'utiliser des
|
||||||
|
|
||||||
Docker est composé d'un daemon lancé au démarrage de votre machine, avec lequel
|
Docker est composé d'un daemon lancé au démarrage de votre machine, avec lequel
|
||||||
vous interagissez via un client (le programme `docker`). La communication entre
|
vous interagissez via un client (le programme `docker`). La communication entre
|
||||||
le daemon et le client s'effectuant au travers d'une socket, le client peut ne
|
le daemon et le client s'effectuant sur une API REST au travers d'une
|
||||||
pas être sur la même machine qui exécutera effectivement les conteneurs.
|
socket. D'ailleurs, le client peut ne pas être sur la même machine qui
|
||||||
|
exécutera effectivement les conteneurs.
|
||||||
|
|
||||||
C'est ce qu'il se passe lorsqu'on utilise *Docker4Windows* ou *Docker4Mac* :
|
C'est ce qu'il se passe lorsqu'on utilise *Docker4Windows* ou *Docker4Mac* :
|
||||||
une machine virtuelle Linux est lancé parallèlement au système de base et
|
une machine virtuelle Linux est lancé parallèlement au système de base et
|
||||||
chaque commande `docker` tappée est passée au deamon dans la machine virtuelle.
|
chaque commande `docker` tappée est passée au deamon dans la machine virtuelle.[^dockermachine]
|
||||||
|
|
||||||
|
[^dockermachine]: Il suffit de modifier la variable d'environnement
|
||||||
|
`DOCKER_HOST` ou de passer le paramètre `-H` suivi de l'URL de la socket à
|
||||||
|
`docker`. Voir aussi : <https://docs.docker.com/machine/overview/>
|
||||||
|
|
||||||
## `runc` et `containerd`
|
## `runc` et `containerd`
|
||||||
|
|
||||||
|
@ -65,6 +69,6 @@ Les registres sont des plates-formes de stockage, publiques ou privées,
|
||||||
contenant des images. Ils permettent de récupérer des images, mais également
|
contenant des images. Ils permettent de récupérer des images, mais également
|
||||||
d'en envoyer.
|
d'en envoyer.
|
||||||
|
|
||||||
Le registre utilisé de base est le [Docker Hub](https://hub.docker.com/) : il
|
Le registre utilisé de base est le [Docker Store](https://store.docker.com/) :
|
||||||
contient à la fois des images officielles (ubuntu, debian, nginx, ...) et des
|
il contient à la fois des images officielles (ubuntu, debian, nginx, ...) et
|
||||||
images crées par des utilisateurs.
|
des images crées par des utilisateurs.
|
||||||
|
|
|
@ -201,6 +201,16 @@ privilèges particuliers.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Fixer des limites
|
||||||
|
|
||||||
|
Au delà de la simple consultation,
|
||||||
|
|
||||||
|
|
||||||
|
## OOM-killer
|
||||||
|
|
||||||
|
<!-- https://lwn.net/Articles/590960/ -->
|
||||||
|
|
||||||
|
|
||||||
## Pour aller plus loin
|
## Pour aller plus loin
|
||||||
|
|
||||||
Pour tout connaître en détails, [la série d'articles de Neil Brown sur les
|
Pour tout connaître en détails, [la série d'articles de Neil Brown sur les
|
||||||
|
|
Loading…
Reference in New Issue
Block a user