menu
Docker : services en conteneurs

Comprendre à quoi sert Docker, comment l'installer et effectuer un test simple comme exemple.

C'est quoi les conteneurs Docker?

La virtualisation:
Une machine virtuelle est une boite reproduisant une machine physique complète, dans cette boite vous pouvez donc installer n'importe quel OS (Linux Debian, Redhat, Windows, etc)

La conteneurisation:
Un conteneur est une boite reproduisant juste le Noyau/Kernel, dans cette boite vous pouvez executer n'importe quel binaire compatible avec le noyau, tel qu'un simple programme Hello-World
Mais les conteneurs s'appuient le plus souvent sur des OS minimum (qui ne sont après tout qu'un ensemble complet de librairies et programmes) car rares sont les applications qui ne s'appuient sur aucune librairie de l'OS mais uniquement sur les fonctionnalités fournies par le noyau.


Un conteneur Docker est isolé (ou presque) :

Pour parler technique très rapidement, Docker se base sur le standard de conteneur LXC présent nativement dans Linux.
LXC se base sur les namespaces (ce que le process peut voir) et les cgroups (ce que le process peut utiliser en ressources).


Ce qui fait que:

  • il ne peut pas voir les processes des autres conteneurs, ni les processes de la machine qui l'héberge.
  • il a son propre réseau, qui par défaut peut joindre l'extérieur (mais il existe plusieurs modes, et on peut mapper des ports)
  • il ne voit pas les fichiers à l'extérieur, sauf si on lui fait un montage (bind mount)

Image ou conteneur Docker?

Il faut bien différencier une image d'un conteneur.
Une image c'est un tableau que vous avez fait à partir de collages, et que vous avez plastifié à la fin, c'est donc figé.
Un conteneur, c'est vos dessins que vous gribouillez par dessus au feutre lavable, c'est donc éphémère.

Vous pouvez passer un coup de chiffons et refaire de 1000 et une façon différente, celà ne changera rien à votre tableau plastifié, il est immuable.
 
Une image est donc immuable
Sur votre machine de développement, pour créer votre image vous partez par exemple d'une base Debian auquel vous aurez rajouté Apache avec PHP, cette image contiendra donc les librairies et fichiers systèmes nécessaires pour faire tourner le service. Puis vous allez lancer un conteneur à partir de cette image et vérifier que le service tourne correctement.
 
Sur une autre machine vous allez lancer un conteneur Docker à partir de cette même image, ce conteneur tournera exactement de la même façon qu'il tournait sur votre machine de développement.
  • Parce que l'image est figée et contient exactement tous les fichiers nécessaires et pas un de plus
  • parce que le conteneur est isolé de l'OS hôte, donc pas d'effets de bord selon la machine
 

A noter qu'il n'est pas forcément nécessaire de créer son image car il en existe déjà plein sur le Docker Hub qui est public, c'est d'ailleurs là que Docker va les chercher par défaut

Il existe des images officielles (Apache, Nginx, MySQL, etc) mais aussi énormément d'images conçus par d'autres Dockernautes (pas forcément de bonne qualité d'ailleurs), le choix est très large.


Les avantages

Docker offre 3 grands avantages:

  • le conteneur étant bien plus léger qu'une virtualisation, le lancement est instantané, le temps de lancement n'est ni plus ni moins que celui de votre service.
  • La certitude que le service va tourner de la même façon sur n'importe quel machine puisque l'image contient tout et est fixe.
  • la possibilité de lancer ce service sur plusieurs machines à partir de cette même image

Fini les problèmes de configuration mal reportées, les dépendances, les fichiers manquants, les fichiers hosts incomplets, les différences de version entre librairies etc.
Ca marchera exactement de la même façon que sur la machine de développement, point.

Une image contient plusieurs couches:
Aussi il faut savoir qu'une image (bien) conçue l'est sur le principe des couches de l'oignon, c'est à dire qu'elle est générée en enchainant des instructions, par exemple "depuis Linux Debian, ajouter JDK puis Apache puis modifier tel fichier". Donc dans la réalité il y aura 4 couches dans votre image.
Si vous faites une modification dans votre configuration, Docker ne va retélécharger que la dernière couche de l'image car il possède déjà les 3 précédentes (Linux Debian, JDK, Apache) dans son cache local.
 
Quand on lance un conteneur, l'image n'est pas modifiée car toutes ses couches sont en lecture seule, en fait une dernière couche en écriture est créée et contiendra toutes la vie du conteneur, c'est à dire toutes les modifications par rapport à l'image.
 
 
Gain des couches:
Imaginez vous possédez un très gros site web, vous avez 100 conteneurs Apache.
 
Vous changez un paramètre Apache dans l'image, Docker va donc retélécharger juste la dernière couche qui va faire admettons 15 kilo-octets.
Dans le pire cas, vos 100 conteneurs sont sur 100 machines différentes donc votre réseau va subir en tout et pour tout une charge de 1500Ko.
 
Maintenant imaginez que ce n'est pas 100 conteneurs que vous avez mais 100 machines virtuelles.
Dans le meilleur des cas, vos 100 VMs sont sur la même machine (...), ESX va donc retélécharger 500 Mo (admettons pour une VM complète) + le temps de relancer toutes les VMs.
 
Le réseau va donc subir un transfert de 1500 Ko plutôt que 500 Mo
Et si vos VMs font 5 Go et sont sur 5 machines différentes, c'est 25 Go transférés au lieu de 1500Ko, etc.

 

Bref Docker ca va vite, très vite! Et ca rentre parfaitement dans la philosophie DevOps qui consiste à livrer rapidement et régulièrement des nouvelles versions de vos applications.

 

 

Les bonnes pratiques

Un conteneur ne fait qu'un seul service
C'est la philosophie des micro-services voulue par Docker, le principe d'un conteneur Docker est de lancer un seul service (fournir un serveur Web par exemple).
Après rien n'empeche de tout fourrer dans son conteneur (serveur web + proxy + MySQL) mais ce n'est pas une bonne pratique. (Bouuuh!!)

Un conteneur est éphémère
Un conteneur n'a aucune vocation à vivre longtemps.
Si l'application change de version, on met à jour l'image et on relance un nouveau conteneur.
Si l'application doit stocker des données, on fait un montage (bind mount) ou bien on créé un volume Docker (qui lui est persistant) qu'on attache au conteneur.

Une image ne doit être générée que par Dockerfile
Le Dockerfile est un fichier qui indique toutes les instructions pour la création d'une image.
Si vous donnez ce Dockerfile à quelqu'un, il pourra créer exactement la même image que vous.
 


Les orchestrateurs

 
Le fait de pouvoir lancer instantanément et rapidement un conteneur à partir de son image permet d'avoir une forte scalabilité.
Par exemple, si votre serveur web est à la traine, vous pouvez lancer en 10 secondes  5 autres serveurs web à la configuration identique !  (évidemment dans votre architecture il y a un Load Balancer en amont qui réparti la charge)
 
Pour ne pas se farcir ce travail manuellement, c'est là qu'entre en jeu les orchestrateurs comme celui fourni par Docker (Swarm), mais aussi Kubernetes (de Google), Lightwave, Mesos/Chronos, etc
Selon vos règles, ils vont surveiller tout ca et lancer de nouveaux conteneurs (ou les détruire si plus besoin)
 

L'ecosystème Docker

Plusieurs applications (pas indispensables) gravitent dans l'ecosystème Docker

  • UCP - Docker Universal Control Plane (for la version EE, gère Swarm l'orchestrateur maison de Docker)
  • Docker Compose (gérer les applications multi-conteneur)
  • Docker Machine (Permet de pusher l'installation automatique de Docker sur des machines distantes)
  • Docker Notary (signature TLS et vérification des images)
  • Docker Registry (faire son hub privé contenant nos images, c'est fourni sous forme d'une image Docker, évidemment :-) )
  • DTR - Docker Trusted Registry (C'est la version commerciale du Docker Registry, management complet des images, intégration LDAP, signature d'image, scanner de sécurité, intégration UCP, etc)

 

Il existe des distributions Linux dédiées à l'utilisation de Docker (Atomic, Rancheros, etc).
A noter qu'il existe une alternative à Docker qui s'appelle rkt / Rocket. D'ailleurs il existe une distribution Linux qui lui est dédiée : CoreOS.

Docker est également disponible sous Windows.


L'installer

# Installation Centos / Redhat
yum install -y docker

# Installation Debian / Raspbian / Ubuntu
apt-get install -y docker

# Démarrage du service
service docker start

 


un exemple simple

# Lancement d'un serveur NGINX sur le port 8080
docker run -p 8080:80 nginx

Docker va télécharger l'image sur le Docker Hub  (s'il ne la trouve pas dans le cache local), et démarrer un serveur NGINX sur le port 80. Ce port 80 est mappé sur le port 8080 de la machine hôte


N'hésitez pas à consulter le Pense-bête Docker.

 

face Nerd
insert_invitation 17 janvier 2019
folder Articles
label docker
label conteneurs
label LXC

Écrire un commentaire

account_circle
mail
http
mode_edit
lock

rss_feed