Introduction à Docker

logo-dockerDocker est une plate-forme opensource pour développer, livrer et exécuter des applications. Avec Docker, vous pouvez séparer vos applications de votre infrastructure. Docker permet ainsi de livrer du code plus rapidement, de tester plus rapidement, à déployer plus rapidement et à raccourcir le cycle entre l'écriture de code et l'exécution de code. Pour résumer  : tout va plus vite. Les conteneurs Docker peuvent être directement utilisés dans Kubernetes. J'en parle car cette introduction à Docker s'inscrit dans une série d'article sur Kubernetes. J'ai d'ailleurs publié une présentation de Kubernetes.  Le but de cet article n'est pas de vous expliquer le fonctionnement de Docker mais de présenter comment créer, exécuter et déboguer des conteneurs Docker . J'explique, par l'exemple, comment extraire des images Docker de Docker Hub et de Google Container Regisitry  La virtualisation permet d'isoler un OS sur lequel vous exécuter une application. Docker permet de la conteneurisation d'applications, c'est à dire que l'OS n'est pas isoler. En efffet, Docker utilise les fonctions de l'OS hôte. La conséquence est que le conteneur est "léger" par rapport à une machine virtuelle.   Un schéma pour comprendre : virtualisation-vs-container Les bénéfices de la « containerisation » sont multiples :
  • Lancement beaucoup plus rapide
  • Facilité de migration d’une machine à une autre
Avant de vous lancer, il est nécessaire d'installer Docker. Vous trouverez ci-dessous les commandes que j'ai utilisé pour une installation sur Redhat. Si vous souhaitez en apprendre d'avantage,  ou si vous souhaitez installer Docker sur Windows par exemple, vous devriez pouvoir trouver votre bonheur sur Internet. 
yum install -y yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install docker-ce docker-ce-cli containerd.io
Démarrez Docker.
systemctl start docker
Vérifiez que tout fonctionne :
docker run hello-world
Ce qui donne (si tout se passe bien ) : docker-hello-world-verifie-que-cela-fonctionne Nous venons d’exécuter le conteneur "hello-world"
docker run hello-world
Exécutez la commande ci-dessous pour listes les images  récemment créées :
docker images
docker-image Exécutez maintenant la commande ci-dessous pour lister les images en cours d'exécution :
docker ps
docker-ps Seul le conteneur nginx est en cours d'exécution. Le conteneur  hello-world que vous avez exécuté précédemment est déjà terminé. La commande docker ps -a permet de lister les conteneurs, y compris ceux qui ont terminé leur exécution.
docker ps -a
Pour comprendre les conteneurs, vous avez besoin d'une bonne compréhension des concepts d'état.

Stateful

Dynamique Changements dans le temps Doit être sauvegardé régulièrement

Stateless

Statique Ne change pas ou change rarement Ne doit être sauvegardé qu'une seule fois stateless-vs-stateful Les conteneurs ne sont pas indiqués pour les applications STATFEUL.  En raison de leur nature immuable et éphémère, la conteneurisation des applications avec état présente peu d'avantages. Aussi, la conteneurisation des applications avec "état" est possible mais nécessite un travail et des considérations supplémentaires. Pour que les applications STATFEUL soient conteneurisées, vous devez conserver l'état en dehors du conteneur : Dans une base de données, dans un object Store (par exemple AWS S3), dans un dossier local sur l'hôte docker, dans un dossier partagé (par exemple NFS). Si les données persistantes sont corrompues ... l'environnement est corrompu ... Dans la section suivante, nous allons voir comment persister les données "en dehors du conteneur" Nous allons maintenant exécuter le conteneur Apache pour exécuter un serveur Web . Comme pour le test précédent, on lancer le conteneur avec la commande run :
docker run httpd:2.4
Avant d'exécuter le conteneur, Docker télécharge l'image httpd:2..4: docker-run-apache Une fois téléchargé, Docker lance le conteneur : docker-apache-rend-pas-la-main Mais docker ne rend pas la main.  Si, dans une nouvelle session je lance la commande docker ps je constate que le conteneur tourne bien. Nous avons donc besoin d'une option docker pour que le conteneur tourne en tache de fond. Nous allons voir même que nous avons besoin d'autres options pour que apache fonctionne correctement en conteneur, mais commençons par le début. Exécutons la commande ci-dessous :
docker run -dit --name mon-apache httpd:2.4
Ce qui donne : docker-dit Cette fois Docker a bien rendu la main. la commande docker ps indique que le conteneur tourne et qu'il porte le nom mon-apache :
docker container ls --format "table {{.ID}}\t{{.Names}}\t{{.Image}}\t{{.Status}} \t{{.Size}}"
Ce qui donne : docker-ps-format Concernant les options docker run : -i démarre une session interactive / -t émule un tty  / -d indique dit à Docker de se détacher et de s'exécuter en arrière-plan. Les options sont accessible sur la page docker run usage. Ok, nous avons  lancé un service HTTP en écoute sur le port 80 à l’intérieur du conteneur, mais à aucun moment vous n’avez ouvert un accès vers l’extérieur. En effet, les conteneurs sont isolés les uns des autres et peuvent tous deux utiliser le même port. Vous pouvez lancer 5 conteneurs apache. Chaque conteneur exécutera apache sur la port 80. Les ports à l'intérieur du conteneur sont uniquement disponibles à l'intérieur du conteneur. Les ports ne sont pas disponibles à partir de l'hôte Docker lui-même. conteneur-inside-out On va donc exposer un port entre notre machine et le conteneur docker. Pour cela nous allons utilise l'option -p (ou -publish  pour "Publish a container’s port(s) to the host") :
docker run -dit --name mon-apache-80-p 8080:80 httpd:2.4
Dans la syntaxe 8080:80, le premier port correspond à celui de la machine hôte et le second au port interne du conteneur. conteneur-inside-out-expose La commande docker ps ci-dessous liste les conteneurs exposant le port 80 :
docker ps --filter expose=80/tcp
Notre conteneur est donc accessible depuis la machine hôte sur le port 8080 :
curl -v http://localhost:8080
docker-curl-apache-8080 Dernière étape pour pouvoir utiliser son serveur web, mapper un répertoire du serveur hôte avec le répertoire racine html du serveur apache (/usr/local/apache2/htdocs/) du conteneur. L'objectif étant de pouvoir afficher nos propres fichiers HTML. La commande ci-dessous, via l'option -v  (pour volume) :
docker run -dit --name my-apache-app -p 8080:80 -v "/opt/html/":/usr/local/apache2/htdocs/ httpd:2.4
Le répertoire /usr/local/apache2/htdocs/ à l’intérieur de notre conteneur contient bien nos fichiers sources situés dans /opt/html/ et non plus les fichiers apache par défaut. Portainer (une interface graphique pour gérer votre environnement docker) :est livré nativement dans un container docker. Pour exécuter le conteneur Portainer
docker  run --name portainer.io --restart always -d -p 8888:9000 -v /var/run/docker.sock:/var/run/docker.sock -v /opt/portainer_data/:/data portainer/portainer
Une dois déployé, vous pouvez vous connecter  à l'interface web via l'adresse suivante: http://ip-de-votre-machine:8888 ( ici j'ai positionné 8888 pour le mapping des ports) Portainer  permet de déployer facilement des conteneurs : portainer-1 portainer-2 portainer-3

Nicolas Housset

Passionné d'informatique, je suis Consultant et expert technique SAS VIYA, également co-fondateur de la société Flexcelite. Spécialisé dans les technologies SAS (Viya, 9.4) et les infrastructures associées (Linux, Hadoop, Azure), ce blog est mon espace pour partager mes mémos techniques et retours d'expérience.