Thibault Coupin
§id:sommaire§;
§id:intro§;
Simuler un système “invité” sur un système “hôte”.
On simule le disque dur, la carte mère, les processeurs…§fragment
C’est un peu lourd §fragment
Se poser la question : pourquoi c’est lourd ? Comment ça marche la virtu ?
Limiter la simulation logiciel du matériel, en simulant un matériel similaire au matériel réel et passer directement les instructions au matériel.
C’est un peu moins lourd §fragment
$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 30108 5812 ? Ss 15:26 0:02 /sbin/init
root 2 0.0 0.0 0 0 ? S 15:26 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S 15:26 0:00 [ksoftirqd/0]
root 5 0.0 0.0 0 0 ? S< 15:26 0:00 [kworker/0:0H]
root 7 0.0 0.0 0 0 ? S 15:26 0:05 [rcu_sched]
root 8 0.0 0.0 0 0 ? S 15:26 0:00 [rcu_bh]
root 9 0.0 0.0 0 0 ? S 15:26 0:00 [migration/0]
root 12 0.0 0.0 0 0 ? S 15:26 0:00 [migration/1]
root 13 0.0 0.0 0 0 ? S 15:26 0:00 [ksoftirqd/1]
...
Environ 200 processus actifs…
ça fait beaucoup pour une seule application utile.
Pourquoi c’est lourd ? A quoi servent tous ces processus ?
Docker ne lance qu’un seule processus, c’est plus simple !§fragment
$ docker run --rm alpine ps aux
PID USER TIME COMMAND
1 root 0:00 ps aux
§fragment
Docker Engine est un outil permettant l’exécution d’application packagée de façon isolée, on parle de conteneur.
Pour démarrer une application de façon isolée, on lance un conteneur§fragment basé sur une image§fragment.
Pour stocker des données on peut associer le conteneur à un ou plusieurs volumes§fragment.§fragment
Le conteneur peut être associé à un ou plusieurs réseaux§fragment pour communiquer avec d’autres conteneurs ou avec l’extérieur.§fragment
Docker Engine est composée de 2 éléments principaux :
Docker Engine est disponible en 2 variantes :
Depuis mars 2017, AA.MM avec AA l’année et MM le mois (ex. : 17.04 pour la version d’avril 2017)
La suite de cette présentation aborde les concepts de docker et liste les commandes utiles.
La liste complète est disponible :
docker help
Dans les versions actuelles, 2 API cohabitent. On ne parlera que de la plus récente.
Pour tester les exemples de commandes qui suivent, il faut :
§id:images§;
L’image est le “disque dur”* figée sur lequel va se baser le conteneur.
Elle contient le système d’exploitation, l’application et des métadonnées.
*Le terme “disque dur” n’est pas parfait, à voir juste après dans le chapitre conteneurs
Transfert des images
# Authentification
docker login
# Télécharger une image
docker image pull REGISTRY/IMAGE:TAG
# Téléverser une image
docker image push REGISTRY/IMAGE:TAG
Lister les images locales
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
forumi0721/alpine-armv7h-minidlna latest 8418d491e218 2 weeks ago 44.34 MB
traefik latest a1350c91b51e 3 weeks ago 37.91 MB
portainer/portainer arm dc7e0ee82da9 6 weeks ago 10.27 MB
tcoupin/rpi-gpass latest f8bfd0e5c152 6 weeks ago 193.8 MB
...
Supprimer une image locale
$ docker image rm REGISTRY/IMAGE:TAG
Renommer/retagguer une image
$ docker image tag REGISTRY/IMAGE:TAG REGISTRY/IMAGE:TAG
Construire une image avec un Dockerfile
$ docker image build -t REGISTRY/IMAGE:TAG DOCKERFILE_PATH
Plus de détails dans le chapitre Dockerfile.
Voir les métadonnées d’une image
$ docker image inspect REGISTRY/IMAGE:TAG
Beaucoup de chose !§fragment
§id:containers§;
$ docker container run OPTIONS REGISTRY/IMAGE:TAG COMMANDE
Exemple :
$ docker container run debian:jessie cat /etc/hostname
Le conteneur affiche le contenu du fichier /etc/hostname
et s’arrête.
Exemple :
$ docker container run -it debian:jessie /bin/bash
Démarre un terminal bash dans le conteneur.
Comme si on était dans une VM.
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Mais pourquoi on ne voit pas les conteneurs d’avant ? §fragment
$ docker container ls -a §fragment
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a5b74e24da65 debian:jessie "cat /etc/hostname" 9 seconds ago Exited (0) 6 seconds ago happy_cori
$ docker container stats [NOM]
$ docker container rm NOM
stop
et start
(kill
aussi)restart
pause
et unpause
Il en existe beaucoup d’autres : gestion des ressources, environnement d’exécution…§fragment
Les modifications dans le système de fichier sont stockées dans une surcouche de l’image.
§pelement:style=max-height:35vh§;
§id:networks§;
L’isolation porte aussi sur le réseau.
--net
La commande run offre l’option --net
Les 4 valeurs :
none
: pas de réseauhost
: les réseaux de l’hôtebridge
(par défaut) : un réseau isolé avec un mécanisme de bridgedocker network create
$ docker container run --rm --net none debian:jessie ip a
Seulement l’interface loopback.§fragment
$ docker container run --rm --net host debian:jessie ip a
Toutes les interfaces de la machine hôte (eth0, wlan0…).§fragment
-p
).bridge
+ résolution DNS des autres conteneurs
-p
$ docker container run --rm -p 8080:80 httpd:alpine
Le port 8080 de la machine hôte est redirigé vers le port 80 du conteneur.§fragment
On peut gérer plus finement les réseaux avec des commandes :
$ docker network create ...
$ docker network connect ...
$ docker network ls ...
$ docker network disconnect ...
$ docker network rm ...
§id:volumes§;
Lorsqu’on détruit un conteneur, on supprime aussi les modifications apportées au système de fichier.
Les conteneurs ne partagent pas leur système de fichiers entre-eux.
Les volumes apportent une solution à cela.§fragment
On utilise l’option -v LOCAL_PATH:PATH_ON_CONTAINER:MODE
$ docker container run --rm -it -v /:/monhote:ro debian:jessie /bin/bash
Lister les volumes
$ docker volume ls
DRIVER VOLUME NAME
local 2bd7394a7adebb03f073bd82048048124578e0b506adea3064fda5d38ef7b678
local data-telegraf
local e0c1ad4b13ed61067082a3511feaae14dbdcacd19632594c129548e241575e0c
local minidlna
local mongodb
...
Quand un volume est créé sans nom, docker le nomme un peu étrangement…§fragment
Créer un volume
$ docker volume create --name NAME [OPTS]
On peut préciser le driver à utiliser (dépend du backend, par défaut local).
Créer un volume lors de la création d’un conteneur
$ docker container run -v [NAME]:[PATH_ON_CONTAINER]:[OPTS]
§fragmentUn peu comme pour un volume hôte, mais avec un nom au lieu d’un chemin.
Les métadonnées d’une image peuvent forcer la création d’un volume :
docker image inspect rok4/data-bdortho-d075
[{...
"Config": {...
"Volumes": {
"/rok4/config/pyramids/ORTHO_JPG_PM_D075": {}
}
},
...]
Supprimer un volume
$ docker volume rm NAME
Supprimer un volume lors de la suppression d’un conteneur
$ docker container rm -v CONTAINER_NAME
Ne concerne que les volumes créés automatiquement par les métadonnées d’une image.
L’option --mount
permet des montages plus élaborés :
/etc/fstab
docker volume create
(ex. : pas de création de l’export NFS)
§id:dockerfile§;
Script de création d’image.
Documentation officielle sur le site de docker
Construire une image avec un Dockerfile
$ docker image build DOCKERFILE_PATH
§slide:data-transition=fade§;
Spécifier l’image de base
FROM debian:jessie
§slide:data-transition=fade§;
Modifier les métadonnées
MAINTAINER Thibault Coupin <thibault.coupin@gmail.com>
LABEL mon_tag="ma valeur"
§slide:data-transition=fade§;
Lancer une instruction
RUN command
§slide:data-transition=fade§;
Ajouter des fichiers
ADD <src> <dest>
COPY <src> <dest>
Globalement identiques mais :§fragment
ADD
supporte les URL§fragment
§slide:data-transition=fade§;
Modifier l’environnement d’exécution
ENV #Variable d'environnement
USER #Changement d'utilisateur
WORKDIR #Changement du dossier de travail
§slide:data-transition=fade§;
Modifier l’exécution
CMD #Commande par défaut
EXPOSE #Déclarer un port réseau
VOLUME #Déclarer un volume
§slide:data-transition=fade§;
Paramétriser le Dockerfile
ARG <name>[=<default value>]
Utilisation : ${name:-default_value}
§slide:data-transition=fade§;
Paramétriser le Dockerfile
docker image build --build-arg name=value .
&&
§fragmentMAINTAINER
, EXPOSE
…)§fragment
juste ce qu’il faut
Pour le run§fragment
Rien en rapport avec le dev/build§fragment
Un conteneur de build génère un package à copier sur le conteneur de run §fragment
Exemple :
FROM debian:jessie as monBuilder
RUN apt-get update && apt-get install build-essential BUILD_DEPENDENCIES
ADD https://github.com/...../master.zip /master
RUN make
FROM debian:jessie
RUN apt-get update && apt-get install RUN_DEPENDENCIES
COPY --from=monBuilder /master/monBinaire /opt/bin/
CMD /opt/bin/monBinaire