virli/tutorial/docker-basis/first.md

194 lines
6.3 KiB
Markdown
Raw Normal View History

2016-09-08 01:44:20 +00:00
\newpage
Mon premier conteneur
=====================
2017-10-04 23:42:56 +00:00
Afin de tester la bonne marche de notre installation, lançons notre premier
conteneur avec la commande :
2016-09-08 01:44:20 +00:00
2017-10-17 06:29:07 +00:00
<div lang="en-US">
2016-09-08 01:44:20 +00:00
```
2017-10-04 23:42:56 +00:00
docker container run hello-world
2016-09-08 01:44:20 +00:00
```
2017-10-17 06:29:07 +00:00
</div>
2016-09-08 01:44:20 +00:00
Cette commande va automatiquement exécuter une série de commandes pour nous,
comme indiqué dans le message affiché en retour :
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
2017-10-04 23:42:56 +00:00
`store.docker.com`. Ce site met à disposition un grand nombre d'images : des
2016-09-08 01:44:20 +00:00
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
node.js, etc.
Nous pouvons directement utiliser le client pour rechercher une image sur le
2017-10-16 20:59:22 +00:00
*Store*, en utilisant la commande `search` :
2016-09-08 01:44:20 +00:00
2017-10-17 06:29:07 +00:00
<div lang="en-US">
2016-09-08 01:44:20 +00:00
```
docker search mariadb
```
2017-10-17 06:29:07 +00:00
</div>
2016-09-08 01:44:20 +00:00
Il est possible de mettre à jour les images locales ou simplement
2017-10-04 23:42:56 +00:00
pré-télécharger des images depuis le Store en utilisant la commande `pull` :
2016-09-08 01:44:20 +00:00
2017-10-17 06:29:07 +00:00
<div lang="en-US">
2016-09-08 01:44:20 +00:00
```
2017-10-04 23:42:56 +00:00
docker image pull ubuntu
2016-09-08 01:44:20 +00:00
```
2017-10-17 06:29:07 +00:00
</div>
2016-09-08 01:44:20 +00:00
2017-10-04 23:42:56 +00:00
Remarquez comment on interagit avec chaque *objet Docker* : dans la ligne de
commande, le premier mot clef est le type d'objet (`container`, `image`,
`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` :
2016-09-08 01:44:20 +00:00
2017-10-17 06:29:07 +00:00
<div lang="en-US">
2016-09-08 01:44:20 +00:00
```
2017-10-04 23:42:56 +00:00
docker image ls
2016-09-08 01:44:20 +00:00
```
2017-10-17 06:29:07 +00:00
</div>
2016-09-08 01:44:20 +00:00
2017-10-04 07:00:58 +00:00
Vous devriez constater la présence de plusieurs images « Ubuntu », mais chacune
2017-10-16 20:59:22 +00:00
a un *TAG* différent. En effet, souvent, il existe plusieurs versions d'une même
2017-10-04 07:00:58 +00:00
image. Pour Ubuntu par exemple, nous avons la possibilité de lancer la version
2017-10-04 23:42:56 +00:00
`trusty`, `xenial`, `zesty` ou `artful`.
2016-09-08 01:44:20 +00:00
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
simple de faire référence aux identifiants.
2017-10-04 23:42:56 +00:00
Chaque nom d'image possède au moins un tag associé par défaut : *latest*. C'est
2017-10-16 20:59:22 +00:00
le tag qui est automatiquement recherché lorsque l'on ne le précise pas en
2017-10-04 23:42:56 +00:00
lançant l'image.
2016-09-08 01:44:20 +00:00
## Exécuter un programme dans un conteneur
Maintenant que nous avons à notre disposition l'image d'un conteneur Ubuntu,
lançons-la !
La commande `run` de Docker prend comme derniers arguments le programme à
lancer dans le conteneur ainsi que ses éventuels arguments. Essayons d'afficher
un Hello World :
2017-10-17 06:29:07 +00:00
<div lang="en-US">
2016-09-08 01:44:20 +00:00
```
2017-10-04 23:42:56 +00:00
docker container run ubuntu /bin/echo "Hello World"
2016-09-08 01:44:20 +00:00
```
2017-10-17 06:29:07 +00:00
</div>
2016-09-08 01:44:20 +00:00
Dans notre exemple, c'est bien le `/bin/echo` présent dans le conteneur qui est
appelé. Ce n'est pas le programme `/bin/echo` de la machine hôte qui a été
transféré dans le conteneur.
2017-10-04 07:00:58 +00:00
Pour nous en convaincre, nous pouvons tenter d'exécuter un programme qui n'est
pas présent sur notre machine, mais bien uniquement dans le conteneur. Si vous
n'utilisez pas [Alpine Linux](https://www.alpine-linux.org), vous pourriez
tenter d'utiliser son gestionnaire de paquet `apk`, via :
2016-09-08 01:44:20 +00:00
2017-10-17 06:29:07 +00:00
<div lang="en-US">
2017-10-04 07:00:58 +00:00
```
2017-10-04 23:42:56 +00:00
docker container run alpine /sbin/apk stats
2017-10-04 07:00:58 +00:00
```
2017-10-17 06:29:07 +00:00
</div>
2017-10-04 07:00:58 +00:00
## Modifier une image
### Images vs. conteneurs
À chaque fois que nous lançons un `run`, un nouveau conteneur est créé.
L'image fournie comme argument est utilisée comme un modèle de base pour le
2017-10-08 22:08:33 +00:00
conteneur et est recopiée grâce à un mécanisme de *Copy-On-Write*: c'est donc
2017-10-04 07:00:58 +00:00
très rapide et ne consomme pas beaucoup d'espace disque.
Étant donné que chaque conteneur est créé à partir d'un modèle, cela signifie
que lorsque nous exécutons une commande modifiant les fichiers d'un conteneur,
cela ne modifie pas l'image de base, mais crée une nouvelle image. Que nous
pouvons ensuite utiliser comme image de base.
2016-09-08 01:44:20 +00:00
2017-10-08 22:08:33 +00:00
![Images vs. conteneurs](img-vs-cntr.png "Images vs. conteneurs"){ width=85% }
2016-09-08 01:44:20 +00:00
2017-10-04 07:00:58 +00:00
Dans ce schéma, on considère les images comme étant la partie figée de Docker à
partir desquelles on peut créer des conteneurs.
Si l'on souhaite qu'une modification faite dans un conteneur (par exemple
l'installation d'un paquet) s'applique à d'autres conteneurs, il va falloir
créer une nouvelle image à partir de ce conteneur.
### Les paramètres
Pour créer une image, commençons par entrer dans un nouveau conteneur :
2016-09-08 01:44:20 +00:00
2017-10-17 06:29:07 +00:00
<div lang="en-US">
2016-09-08 01:44:20 +00:00
```
2017-10-04 23:42:56 +00:00
docker container run -it ubuntu /bin/bash
2016-09-08 01:44:20 +00:00
```
2017-10-17 06:29:07 +00:00
</div>
2016-09-08 01:44:20 +00:00
2017-10-04 07:00:58 +00:00
Vous avez remarqué l'utilisation des options `--tty` et `--interactive` ? Avant
le nom de l'image, elles sont gérées par Docker pour modifier le comportement
du `run`. En fait, tout comme `git(1)` et ses sous-commandes, chaque niveau de
commande peut prendre des paramètres :
2017-10-17 06:29:07 +00:00
<div lang="en-US">
2017-10-04 07:00:58 +00:00
```
2017-10-04 23:42:56 +00:00
docker DOCKER_PARAMS container run RUN_OPTS image IMAGE_CMD IMAGE_ARGS ...
2017-10-04 07:00:58 +00:00
```
2017-10-17 06:29:07 +00:00
</div>
2017-10-04 07:00:58 +00:00
Par exemple :
2017-10-17 06:29:07 +00:00
<div lang="en-US">
2017-10-04 07:00:58 +00:00
```
2017-10-04 23:42:56 +00:00
docker -H unix:///var/run/docker.sock container run -it alpine /bin/ash -c "echo foo"
2017-10-04 07:00:58 +00:00
```
2017-10-17 06:29:07 +00:00
</div>
2017-10-04 07:00:58 +00:00
Ici, l'option `-H` sera traitée par le client Docker (pour définir
l'emplacement du point de communication avec le daemon), tandis que les options
`-it` seront utilisées lors du traitement du `run`. Quant au `-c`, il sera
2017-10-16 20:59:22 +00:00
simplement transmis au conteneur comme argument au premier `execve(2)` du
2017-10-04 07:00:58 +00:00
conteneur.
Avec l'option `--interactive`, on s'assure que l'entrée standard ne sera pas
2017-10-04 23:42:56 +00:00
fermée (`close(2)`). Nous demandons également l'allocation d'un TTY,
2017-10-04 07:00:58 +00:00
sans quoi `bash` ne se lancera pas en mode interractif[^bashnointer].
[^bashnointer]: Mais il sera possible de l'utiliser sans allouer de TTY, comme
par exemple en faisant :
2017-10-17 06:29:07 +00:00
<div lang="en-US">
2017-10-04 07:00:58 +00:00
```
42sh$ cat cmd
echo foo
42sh$ cat cmd | docker run -i busybox
foo
```
2017-10-17 06:29:07 +00:00
</div>
2017-10-04 07:00:58 +00:00
L'option `-i` reste néanmoins nécessaire pour que l'entrée standard soit
transmise au conteneur.
2017-10-16 20:59:22 +00:00
### TODO
TODO Nouvelle partie sur `docker container ls`