Premiers pas avec Docker

Publié le 25 juin 2015 par François Vantomme | système

Cet article est publié sous licence CC BY-NC-SA

Premiers pas avec Docker

Docker logo

Première semaine chez Synbioz et j’attaque tout de suite avec un sujet passionnant. Le projet sur lequel je suis amené à travailler repose sur Docker. Pour moi c’est une première dans le cadre d’un vrai projet et qui plus est dans un environnement OSX. Oui, quitte à découvrir Docker, autant se rajouter quelques contraintes supplémentaires pour pimenter l’expérience !

Mais qu’est-ce que Docker ?

Docker est un gestionnaire de containers offrant la possibilité de construire, délivrer et exécuter des applications distribuées. Né du mouvement DevOps, Docker présente aux programmeurs que nous sommes la boîte à outils dont nous avons besoin pour tirer parti du caractère distribué des applications modernes.

Dit autrement, Docker nous permet de travailler dans des environnements isolés appelés container capables de communiquer entre eux et pouvant être déployés facilement sur nos serveurs.

Pourquoi des containers ?

L’une des problématiques à laquelle Docker souhaite répondre est la suivante : comment être certain que mon application, qui fonctionne parfaitement en local sur ma machine de développement, fonctionnera tout aussi bien sur mon serveur qui a une architecture et une configuration très différentes de celles de mon environnement de développement ?

C’est exactement le même problème que pour le transport de marchandises. Avant 1960, les marchandises étaient transportées en vrac. Ce qui représentait des difficultés de transbordement, d’un bateau à un camion par exemple, on peut s’en douter. On ne manipule pas un piano à queue comme un tonneau de bière. D’où l’invention du container : une caisse aux dimensions standardisées contenant des marchandises, quelles qu’elles soient. Le container est muni de pièces de préhension permettant de l’arrimer et de le transborder d’un véhicule à l’autre. De cette manière, nous savons ce que nous manipulons : des containers, et uniquement des containers. Et surtout comment les manipuler !

Docker s’inspire de ce principe et le transpose dans le domaine du logiciel. Il offre donc la possibilité de manipuler des containers qui contiendront un serveur web, une base de données, un proxy ou un service quelconque, peu importe. Et ces containers exposent certains ports afin de pouvoir communiquer entre eux et avec l’extérieur. Ainsi, en local comme sur nos serveurs, nous sommes certains d’obtenir le même fonctionnement car nous manipulons les mêmes containers dont les comportements sont totalement indépendants de l’hôte qui les héberge.

Un container n’est pas une VM

On pourrait être tenté de penser qu’un container n’est finalement ni plus ni moins qu’une machine virtuelle (VM). En effet, il y a un peu de ça. Mais des différences substantielles sont à noter.

Containers vs. VMs

Tout comme pour une VM, un container évolue dans un environnement isolé. Mais la comparaison s’arrête là. Le container va partager le système d’exploitation, et quand cela est possible, les bibliothèques et binaires de l’hôte. Cela signifie que nous ne pouvons pas lancer un container embarquant un windows par exemple si notre hôte fait tourner une distribution GNU/Linux. Nos containers devront donc avoir un hôte GNU/Linux, ce que nous obligera à rajouter une couche supplémentaire pour une machine de développement sous OSX par exemple.

C’est ainsi qu’il est possible de faire tourner une centaine de containers sur un ordinateur portable et un millier sur un serveur. Un container Docker utilise de 2 à 30 fois moins de ressources qu’une machine virtuelle traditionnelle. Et pour ne rien gâcher, à l’intérieur d’un container, les logiciels tournent aussi vite que s’ils étaient lancés sur l’OS hôte.

Docker & OSX

Je disais en introduction que faire tourner docker dans un environnement OSX n’est pas forcément ce qu’il y a de plus aisé. En effet, Docker nécessite un hôte GNU/Linux car il utilise des fonctionnalités spécifiques au noyau non présentes dans OSX. Qu’à cela ne tienne, nous n’avons qu’à exécuter Docker dans une VM !

Bon, là vous allez me dire que ça devient compliqué, qu’il faut installer VirtualBox, configurer une VM, etc… Alors oui, il va falloir installer VirtualBox, mais ça s’arrête là. Grâce à Boot2Docker la virtualisation est transparente.

Docker host

Docker Machine

Avant d’écrire d’obscures lignes de commandes dans le terminal, poussons un peu plus loin. Autour de Docker gravite tout un écosystème d’outils pour nous simplifier la vie. Parmi ces outils on trouve Docker Machine. Ce dernier va nous permettre de créer des hôtes Docker non seulement sur notre machine (en s’appuyant sur Boot2Docker), mais également dans le cloud ou au sein de votre réseau d’entreprise. Docker Machine crée des serveurs, installe Docker dessus puis configure le client docker pour leur parler.

Mise en place

Maintenant que nous en savons un peu plus sur Docker et son utilité, essayons de voir à quoi ça peut bien ressembler dans la pratique. Nous allons donc installer les prérequis et créer notre premier container Docker.

❯ brew cask install virtualbox
❯ brew install docker docker-machine

Voilà VirtualBox, Docker et Docker Machine installés. Nous allons donc créer un environnement Docker en local à l’aide de Docker Machine.

❯ docker-machine create --driver virtualbox dev
❯ eval "$(docker-machine env dev)"

La première ligne va créer notre environnement Docker. La seconde quant à elle va exporter les variables nécessaires au bon fonctionnement de Docker dans le terminal courant.

À noter : Il sera nécessaire de réexécuter cet eval dans chaque nouveau terminal pour pouvoir utiliser les commandes Docker.

❯ docker-machine ls
NAME   ACTIVE   DRIVER       STATE     URL                         SWARM
dev    *        virtualbox   Running   tcp://192.168.99.127:2376

Nous pourrions très bien avoir un second environnement Docker dans le cloud par exemple.

❯ docker-machine create -d digitalocean --digitalocean-access-token=secret staging
❯ docker-machine ls
NAME      ACTIVE   DRIVER         STATE     URL                          SWARM
dev                virtualbox     Running   tcp://192.168.99.127:2376
staging   *        digitalocean   Running   tcp://104.236.253.181:2376

Grâce à Docker Machine, passer de l’un à l’autre est un jeu d’enfant, il suffit d’exécuter la commande eval ci-dessus en adaptant le nom de l’environnement bien entendu.

eval "$(docker-machine env staging)"

Cette capacité à changer facilement d’environnement Docker peut s’avérer très pratique lorsque l’on travaille sur plusieurs projets comme ici chez Synbioz.

Revenons sur notre environnement dev et créons notre premier container. Ici rien de bien compliqué.

❯ docker run busybox echo 'So long, and thanks for all the fish!'
Unable to find image 'busybox:latest' locally
511136ea3c5a: Pull complete
df7546f9f060: Pull complete
ea13149945cb: Pull complete
4986bf8c1536: Pull complete
So long, and thanks for all the fish!

Que s’est-il passé ?

Nous avons demandé à l’exécutable docker de lancer la commande run. Cette commande instancie un container. Nous lui avons précisé le nom d’une image, ici busybox. Lorsque l’on spécifie une image, Docker regarde d’abord si elle est disponible sur l’hôte. S’il ne peut pas la trouver, il la télécharge depuis le registry Docker Hub, lieu où sont enregistrés tous les containers publics.

Vous voulez une base de données MongoDB ? Un server Nginx ? Il y a un container pour ça !

Expert : Il est également possible de mettre en place un registry privé au sein de son entreprise.

Ensuite nous précisons à Docker quelle commande nous souhaitons exécuter au sein de notre container. Ici, nous faisons un simple echo qui va afficher la chaîne de caractères qu’on lui passe en paramètre. D’où la dernière ligne :

So long, and thanks for all the fish!

Qu’arrive-t-il ensuite à notre container ?

Les containers dockers restent opérationnels tant que la commande que l’on a spécifié reste active. Dans le cas présent, aussitôt la phrase affichée, le container s’arrête.

❯ docker ps -a
CONTAINER ID    IMAGE           COMMAND                 CREATED         STATUS
d0696763d09f    busybox:latest  "echo 'So long, and…    1 minute ago    Exited (0) 1 minute ago

Astuce : Nous aurions pu détruire notre container aussitôt son exécution terminée en précisant l’option --rm à la commande docker run.

Un echo et c’est tout ?

Non, bien sûr ! Nous n’avons fait ici que survoler le sujet, il y a tellement à dire à propos de Docker que je n’aurai pas assez d’un article pour en faire le tour !

Dans les prochains articles nous verrons comment utiliser Docker dans le cadre du développement d’une application web et quels sont les pièges à éviter. Nous apprendrons également à utiliser les volumes, à faire communiquer plusieurs containers entre eux, à mettre en place un DNS pour accéder facilement à nos containers, et plein d’autres choses tout aussi sympathiques !

L’équipe Synbioz.

Libres d’être ensemble.