PREMIERS PAS DANS LE MONDE DES CONTAINERS ET DE DOCKER
Les tutos Docker est une mini-série d’articles autour de la technologie Docker (Containers, images, docker-compose, Swarm, Kubernetes …).
L’objectif de cette série n’est pas de fournir une documentation exhaustive sur les usages de Docker (la documentation officielle de Docker est déjà très bien faite).
En trois ans seulement, La technologie Docker a su faire sa place et est déjà mondialement connue.
On peut rapidement la définir comme un ensemble d’outils permettant la création d’un environnement qui va recevoir une ou plusieurs applications pour une exécution isolée sur une machine locale ou dans le Cloud.
A PROPOS DE L’AUTEUR
Eric Duquesnoy vous fait découvrir au travers d’une série de vidéos les bénéfice de l’utilisation de Docker.
LA VIDÉO
La vidéo suivante vous présente sous la forme d’un screencast réalisé par Eric les différents sujets abordés dans cet article. Bon visionnage.
MAIS QU’EST CE QUE DOCKER ?
Docker est une plateforme open-source pour les développeurs et les sysadmins (ops) qui permet de construire, livrer et exécuter des applications distribuées.
Docker permet :
- d’assembler rapidement des composants en application
- d’éliminer les désagréments de passage entre les environnements de développement, de qualité, et de production.
Ainsi, les livraisons sont plus rapides et l’exécution et le comportement de l’application reste inchangé qu’elle soit sur des laptops, des VMs de data center, ou sur n’importe quel cloud.
Cet environnement est très rapide et léger en terme de footprint car le container va utiliser les fonctionnalités du système linux (cgroups, namespaces, …) exécutées par le Host.
Pour rappel, Docker facilite et vulgarise le format de container Linux LXC avec une API qui virtualise les applications de façon isolée.
L’architecture idéale pour Docker est la distribution des applications à travers une ou plusieurs machines en cluster avec une possibilité de gestion des ressources intelligente.
COMMENT FONCTIONNE DOCKER ?
Il s’agit de “containériser” les applications dans un format standard réutilisable. Pour cela Docker est constitué de 2 outils principaux. :
- Docker Engine, un outil de packaging et d’exécution portable, qui construit, gère et exécute les containers.
- Docker Hub, un service cloud permettant de stocker et de partager simplement les containers.
DOCKER ENGINE
Docker utilise une architecture client-serveur, le client Docker et le daemon Docker. C’est ce dernier qui se charge de la construction, de l’exécution et de la distribution des containers Docker.
Le client et le daemon peuvent être sur le même hôte, mais il est possible d’ avoir un client qui se connecte sur un daemon distant. Le client et le daemon Docker communiquent via sockets ou à travers une API RESTful.
LE DAEMON DOCKER
Le daemon Docker tourne sur une machine hôte. L’utilisateur n’interagit pas directement avec le daemon, il passe par le client Docker.
LE CLIENT DOCKER
Le client Docker se présente sous la forme de l’exécutable docker. Il accepte des commandes de l’utilisateur (docker run, docker build, docker push, …..) et les transmet au daemon Docker.
UN CONTAINER C’EST UNE VM FINALEMENT ?
Il ne faut pas confondre les containers et les machines virtuelles. Dans le premier cas nous n’installons pas un nouvel OS dans sa globalité mais nous utilisons une image (sous forme d’un fichier) qui contient toutes les libraires nécessaires à l’exécution des applications, alors que dans le 2ème cas vous installez un OS en surcouche d’un hyperviseur (donc d’un autre OS avec toute la lourdeur que cela comporte).
Lancer une VM est beaucoup plus long et lourd pour le système mais isole mieux les applications les unes par rapport aux autres.
Etant donné, le partage des ressources entre l’OS de la machine et le container, les linux containers ne tournent que sur un Linux et les windows containers ne fonctionnent qu’avec Windows comme système Hôte.
DOCKER , ÇA SERT À QUOI ?
- Aider les développeurs à coder dans un environnement technique identique à la production.
- Aider les ops à déployer les nouvelles applications et les upgrades de version grace à la similitude des environnements .
- Découpler l’infrastructure par rapport aux applications.
- A masquer la complexité des containers (architecture LXC).
LES DIFFÉRENTS MODÈLES DE LICENCE
Docker est disponible en version Communitiy Edition (CE) et Entreprise Edition (EE).
La version EE est orientée Enterprise avec un ensemble d’options et de fonctionnalités payantes (ex: Image Security Scanning).
Docker est disponible en version on-premise (Linux, Windows et Mac) et dans le cloud (AWS, Azure).
Les versions Linux compatibles avec Docker sont : Centos, Debian, Fedora, Oracle Linux, Red Hat, Suse et Ubuntu.
Pour plus de détails concernant les installations, veuillez vous reférer à cette page : https://docs.docker.com/glossary/?term=install
Pour les utilisateurs de Windows, Docker existe en version Docker-toolbox (exécutable qui installe tout, Virtualbox, une VM (Moby Linux), et les clients) et Docker4Windows (comme docker-toolbox, mais en mieux, utilise Hyper-V au lieu de Virtualbox ,seulement compatible à partir de Windows 10 Pro).
LES CONTAINERS
Un container Docker contient tout ce qui est nécessaire à l’exécution d’une application, on peut le comparer à un répertoire.
Chaque container est créé depuis une image Docker et on peut intéragir avec lui facilement grace à différentes commandes d’exploitation.
Il faut bien comprendre que le container est l’instanciation d’une image dans un mode isolé et sécurisé.
Chaque container est une plateforme isolée est sécurisée. Les containers Docker sont les composants d’exécution de Docker.
Après l’installation (voir le site de l’éditeur) du produit en fonction de votre OS , votre 1ère commande sera le lancement de votre premier container
Ce container très basique vous permet de vérifier le bon fonctionnement de tous les composants de votre installation.
Continuons avec 2 commandes indispensables pour lister les containers disponibles sur votre système:
Pour complexifier l’exemple, démarrons maintenant le fameux Nginx (serveur HTTP + reverse proxy) en container et exposons le port 80 sur le port 8000 de notre machine.
et vérifions sa bonne exécution dans un browser :
Great ça fonctionne ! nginx utilise maintenant le port 8000 en local.
La meilleure pratique pour lancer un container est en mode détaché (ou mode daemon).
Mais pour intéragir avec lui ou pour débugger, l’exécution d’un container en mode “exec” ou “attach” est une très bonne solution.
Voici comment “s’attacher” à ce container :
Tips : Nous pouvons vérifier la présence des containers dans notre système en listant ce répertoire : “/var/lib/docker/containers” (Notez les containers ID)
Lorsque vous créez un container , vous avez plusieurs options à votre disposition :
- -w => permet de se positionner dans un répertoire particulier
- –privileged => permet de lancer le container avec plus de droits sur la machine hôte.
- -rm => supprime le container lors de son arrêt
- –log-driver=> permet de personnaliser et modifier la sortie des logs des containers (usage avancé)
Comment nommer un container au moment de sa création ?
LE DOCKERFILE ET LES IMAGES
Ok, nous avons vu comment manipuler les containers mais maintenant interessons-nous à la “source” des containers c’est à dire les images !
Une image Docker est un template en lecture seule. Elle contient tout ce qui est nécessaire à l’exécution de l’application.
Docker fournit une façon simple de créer de nouvelles images ou de modifier les existantes. iÎl est aussi possible de télécharger des images existantes depuis le Docker Hub.
Il faut savoir que la plupart des éditeurs travaillent depuis plusieurs années par une version dockerisée de leurs productions.
L’utilsation des images fournies par ces sociétés sont extrèmement facile à utiliser , il n’y a pas de phase d’installation à proprement dit.
L’avantage par rapport à l’installation complexe d’une application est évident.
Les images Docker sont le composant de construction de Docker. Une image est constituée de couches (layers) qui vont permettre de produire un artéfact cohérent et optimisé pour l’instanciation du container.
Commandes Docker
Suppression des images :
COMMENT CONSTRUIRE UNE IMAGE ?
La construction d’une image est assez simple avec la commande “docker build” et un fichier déclaratif, le fameux Dockerfile !
En effet, le principal avantage d’utilisé des dockerfile est son aspect déclaratif, vous allez “coder” l’architecture de votre image.
A travers un fichier Yaml, sans utiliser un langage particulier de type Groovy vous aller déclarer et décrire tout ce que vous souhaitez installer dans votre image. Ce fichier pourra être la garant des images produites et stocker dans le registry.
La commande “docker build” va produire l’image en quelques minutes en respectant à la lettre les commande du Dockerfile.
Voici quelques options liées à la commande build :
- -t => permet de faire un tag (version) sur l’image produite
- -f => permet de spéficier un Dockerfile ( qui n’est pas dans le répertoire courant
- -rm => force l’effacement des images intermédiaires (voir la commande “docker images -a”)0
Et maintenant au travail !
Entrons en détails dans le fichier Dockerfile pour personnaliser notre image nginx.
Dans cet exemple nous allons prendre la version 1.7 de Nginx
La commande COPY :
Nous allons personnaliser la page index.html de Nginx en copiant un fichier modifié stocké sur notre machine.
Parfait ! nous savons maintenant comment intéragir avec nos containers.
L’instruction ENV (environnement) :
Cette commande permet de créer des variables d’environnement (on l’aurait deviné facilement). Leur utilisation est surtout importante au moment de l’exécution du container.
Imaginons que vous exécutiez un container PostgreSQL ou MySQL, il va falloir définir un user / password en tant qu’administrateur de votre database.
Ce genre d’information indispensable et confidentiel peut être transmis par l’utilisation des instruction ENV (soit dans le dockerfile ou pendant le lancement du container).
LES MODES D’EXÉCUTIONS
Dans les Dockerfiles, il y a deux types d’exécution : soit en mode EXEC ou soit en mode SHELL.
voici le Mode SHELL => /bin/bash “ping www.google.fr”
Nous pouvons voir dans cette commande 2 processes : le bash et la commande ping. Le process Bash aura le PID1 et la commande ping un autre numéro de PID (aléatoire)
Lors de l’arret du container, un arret du PID1 va être envoyé au container mais pas aux autres processes (ex la commande ping dans notre exemple), ce qui peut être problématique si nous souhaitons arreter “proprement” les processus fils (plus d’info ici.).
Tandis que le mode exécutable => CMD [“ping”,”www.google.fr“] permettra à la commande ping d’avoir le PID 1 et donc d’avoir un arret “propre” lors de l’arret du container.
Il est donc préférable d’utiliser le mode EXEC en dernière instruction de notre Dockerfile.
Les commande RUN, ENTRYPOINT et CMD utilisent ces 2 modes .
Exemple avec RUN
Exemple avec CMD et ENTRYPOINT
Tagger une image :
Le “Tag” d’image veut simplement dire versionner notre image et donc pouvoir l’identifier dans une chaine d’intégration continue et de stockage à travers le registry.
Il est indispensable pour tout developpeurs de tagger son code et de gerer le versionning à travers cette commande.
L’historique d’une image (ses différentes layers) est possible avec la commande docker history :
Les differentes commandes de copie utilisables dans un Dockerfile:
Nous utiliserons la plupart du temps l’instruction COPY en place de ADD pour éviter la décompression des fichiers TAR ou ZIP que nous souhaitons copier dans l’image.
La commande LABEL
C’est une instruction très utile pour ajouter des métadata à son image. En effet, rien de plus rageant d’utiliser une image sans avoir des informations
supplémentaires et pertinentes sur son créateur, la date de création, la version commerciale, le descriptif ….
En bref, plus votre image sera “labelisée” plus son contenu sera identifié dans votre registry.
La commande WORKDIR
RECAPITULATIF :
Une image Docker se crée en se basant sur des images Docker OS de référence :
- soit en exécutant un container de l’image Docker OS de référence, puis en l’enrichissant avec les applications à installer et enfin en l’enregistrant en tant qu’image
- soit en créant un Dockerfile utilisant l’image Docker OS de référence et décrivant les applications à installer, puis en laissant construire l’image par Docker avec ce Dockerfile.
DOCKERISATION D’UN MIDDLEWARE
Une recherche rapide sur GitHub, nous permet d’obtenir un Dockerfile et ces dépendances permettant la création d’une image Docker contenant Weblogic 12c :
Attention ce Dockerfile est beaucoup plus complexe mais il vous montre toutes les possibilités d’un tel fichier.
GESTION DES IMAGES
Commiter les modifications effectuées dans une image:
Parfois certaines modifications ne se font pas au sein d’un Dockerfile mais directement dans le shell du container. ll est tout de même possible d’enregistrer toutes ces modifications dans l’image d’origine.
Attention , cette pratique est déconseillée et est utilisable que pour des cas particuliers (Troubleshooting, ..)
Comment sauvegarder une image dans un fichier TAR.
LE REGISTRY DOCKER
Un registry (officiel ou non) est une plateforme qui vous permet de stocker vos images Docker et de les distribuer par la suite.
Un système de versionning des image Docker est intégré dans la plateforme.
C’est un élément important dans votre eco-système Docker car il permet de garantir la sécurité des images utilisées.
Vous pour trouver une très bonne explication du Docker Hub officiel ici : (docker-hub)
Comment renommer une image et stocker une nouvelle image dans un registry privé
Nous venons de voir qu’il est possible de gérer le push/pull d’une image dans le registry de Docker mais aussi en privé et finalement dans le cloud.
LE MONITORING ET L’ADMINISTRATION DE DOCKER
Qui parle d’architecture, parle de monitoring et d’exploitation car la production de toutes ces images necessitent une certaine organisation.
Heureusement Docker nous fournit un ensemble d’outils essentiels pour assurer cette partie.
Comment suivre les logs d’un container ?
Comment surveiller les ressources de mon container ?
Comment surveiller les ressources consommées par mes containers sur mon Hôte ?
Comment limiter les ressources d’un container ?
Bien que bizarre, cette commande est utilise lorsque l’application dockerisée à un processus d’arret assez long (plus que 10s).
Elle évite un kill “tranchant” sur notre application et lui laisse le temps de finir sa procédure de fermeture.
Les bases de données sont souvent visées par ce comportement.
Comment supprimer tous les containers déja stoppés ?
Comment lister la redirection des ports d’un container ?
Comment exécuter une commande shell dans un container en cours d’exécution ?