Home .NET Introduction à Docker – La théorie

Introduction à Docker – La théorie

  Nolan VIEIRA Développeur .NET/Angular 15 min 9 mars 2020

Docker

La conteneurisation est une pratique en vogue en ce moment, nous allons donc vous présenter Docker.

Docker est une solution qui permet de s’affranchir de l’utilisation de virtualisation de machine, qui demande une configuration conséquente contrairement à Docker.

Machine Virtuel vs Conteneur

Pour comprendre docker, nous pouvons faire l’analogie avec la Virtualisation, car l’idée est la même mais sans système d’exploitation.

Machines Virtuelles

Dans ce schéma, nous retrouvons les deux types d’architecture: la virtualisation classique et les conteneurs.
Les machines virtuelles reposent sur des hyperviseurs qui sont souvent de type 1 (Natif, ou encore appelé « Bare metal »). Pour faire simple, c’est une couche de type Système d’exploitation (Citrix Hypervisor (anciennement XenServer), Hyper-V, ESXI) qui partage totalement la partie matérielle avec les machines virtuelles hébergées dessus. Vous connaissez sans doute le type 2 avec VirtualBox, VMWare Workstation Player, ou encore Hyper-V de votre Windows 10 Pro.

Une machine virtuelle permet de simuler un ordinateur dans l’ordinateur, ce qui permet d’installer des systèmes d’exploitation dessus et qui est isolé des autres machines virtuelles (et du système qui exécute la machine virtuelle). Vous pouvez bien entendu communiquer avec via le réseau et les outils des hyperviseurs.

Comme vous pouvez le voir sur le schéma, les machines virtuelles sont beaucoup plus lourdes en place et en ressources matériel:

  • Une installation d’un Windows demande 40 Go de disque dur
  • 4 Go de RAM et un CPU dual core
  • Coût de licence Windows

Ce qui est une configuration relativement conséquente. N’oublions pas que nous n’avons pas pris en compte la partie applicative, ce qui peut demander plus de RAM ou de puissance CPU.

Un système basé sur Linux demande moins de ressources, mais cela reste une perte énorme comparé à l’utilisation de conteneur.

Conteneurs

Les conteneurs demandent beaucoup moins de ressources. Nous utilisons un système d’exploitation Windows ou Linux (on va en parler en détail plus bas !) avec une solution de conteneurisation (Docker, Kubernetes, Apache MESOS, RKT, LXD, etc). Dans nos articles, on restera avec Docker pour le moment.

Comme pour les Machines Virtuelles, les containeurs sont en mode « sandbox » et nous ne pouvons pas communiquer aussi simplement avec pour plus de sécurité (nous pouvons bien entendu prendre la main en mode terminal avec les outils Docker). Pour la communication avec l’extérieur, nous devons ouvrir les ports manuellement (on va voir cela plus tard dans un exemple).

Une notion importante à savoir et qui permet de ne pas avoir de système d’exploitation, c’est que les composants du système de base (Host) sont utilisés, si besoin, dans le conteneur de l’application pour éviter de prendre du poids dans la partie applicative. Cette information nous emmène sur le point suivant !

Base Windows ou Linux ?

Oui, la partie système est partagée avec le système, ce qui ne nous permet pas d’exécuter des conteneurs fait pour Windows sur du Linux. Et j’ajoute aussi que nous ne pouvons pas avoir les deux sur un serveur ! Donc c’est quoi le mieux ?

De manière générale nous recommandons de toujours prendre une base Linux. Cependant, si vous avez besoin de conteneuriser des application .NET Framework legacy, vous devez prendre un Windows Server Core. Il n’est pas recommandé d’utiliser une base Windows pour les applications .NET Core et .NET 5 (qui sortira cette fin d’année 2020). Il est recommandé de partir sur du Linux.

Pour le reste, sans conteste Linux ! Il est en effet plus simple de maintenir et de créer une image de conteneur sur Linux grâce aux dépôts des systèmes d’exploitation (Debian, Alpine, etc). Nous en reparlerons également plus bas sur la personnalisation et la construction d’image de Docker.

Les avantages de Docker (et autres dérivés Linux) sont multiples:

  • Un conteneur est super léger (5Mo + votre application, contre 30Go + votre application avec une Machine Virtuel).
  • La sécurité et la simplicité d’utilisation:
    • Votre application en mode « sandbox ».
    • Pas de limitation matérielle pour votre serveur, la compatibilité est plus simple à gérer.
  • Moins de configuration matérielle nécessaire car, un conteneur ne consomme pas beaucoup de ressources comparées à une Machine virtuelle.
  • Pas de licence pour Docker (et autres, si vous hébergez sur votre serveur)

Contexte d’utilisation

Les conteneurs, c’est bien. Mais qu’elles sont les choses à savoir pour son utilisation ?

Voici une illustration des possibilités:

Développement

Cette formidable outils permet bien des choses, notamment la simplification des environnements pour les développeurs. En effet, nous pouvons également développer et exécuter du code directement depuis un containeur Docker avec des IDE (Visual Studio, Visual Studio Code, etc).

Ce qui permet:

  • D’avoir aucune dépendance requise sur le PC hormis Docker
  • De simplifier le travail en collaboration avec un autre corps de métier, par exemple les Intégrateurs :
    • « F5 » (Lancer le projet) pour faire les modifications et commit les modifications sur un GIT
    • La fin des dossiers zip et modifications non-sourcées sur GIT, ce qui devient fort intéressant pour le management du projet

Je reparlerais dans un autre article sur l’utilisation de Docker en phase de développement, la création d’une image et le déploiement d’une application depuis Azure DevOps.

Hébergement d’un site

Héberger un site avec des conteneurs est extrêmement simple, le rendre disponible l’est encore plus !
Je ne vais pas rentrer dans les détails techniques maintenant, mais une image docker expose un ou plusieurs ports. Avec un outil comme Traefik, nous pouvons rediriger les noms de domaine sur ses ports comme un proxy. La gestion des certificats SSL peut être aussi dynamique et automatique, ce qui est merveilleux. Un exemple vous attend plus tard sur l’utilisation de Traefik, mais la configuration réseau est devenu extrêmement simple.

Avant de parler de l’hébergement, je dois vous donner des informations sur les conteneurs. Dans la partie développement, nous pouvons créer une image Docker de notre application (plus d’info dans le prochain article). Une image peut être exécutée sur un serveur qui possède Docker, ce qui est logique. Mais une notion importante à savoir c’est que pour avoir une haute disponibilité de votre application, vous pouvez faire ajouter autant d’instances que vous voulez.

Restons dans la théorie. Nous verrons la pratique dans un autre article.

Site Simple

Dans le cas d’un site simple, vous pouvez lancer une instance de votre image docker. Mais vous pouvez aussi lancer deux instances de la même application sur le même serveur. Pourquoi ?

Il y a deux raisons à cela :

  • La mise à jour de votre image docker sur votre serveur, va éteindre le site. Cependant, avoir plusieurs instances de votre image Docker va permettre d’appliquer les mises à jour des images des instances une par une pour une haute disponibilité de votre application.
  • Nous pouvons répartir la charge sur les instances de votre application avec un outil de répartition de la charge (Load Balancing) avec traefik, plus d’information dans un prochain chapitre !

Site important

Pour la haute disponibilité d’une application, nous devons utiliser plusieurs serveurs de conteneur.
C’est d’ailleurs une recommandation de base d’avoir plusieurs serveurs pour avoir une réplication. Pour synchroniser plusieurs serveurs Docker, nous pouvons utiliser Docker Swarm. Cependant, la meilleure solution est Kubernetes. Le principe est le même entre les deux, il y a un serveur maitre qui permet d’installer les conteneurs et qui demande de dupliquer sur les autres serveurs la configuration. La répartition de charge est transparente avec Kubernetes.

Les avantages :

  • Redémarrage automatique des applications s’il y a une extinction de service
  • Répartition de la charge avec des options intéressantes (autoscaling)
  • De nombreux hébergeurs proposent cette solution : Azure, Google et Amazon

Architecture des applications

Nous pouvons utiliser Docker pour des applications monolithiques, mais ce n’est malheureusement pas la plus pertinente des solutions. Il est fortement recommandé de faire une architecture en micro-services.

Comme vu précédemment, nous pouvons lancer plusieurs instances d’une image docker. Nous pouvons donc optimiser la ressource avec la demande actuelle en ajoutant des instances à des services importants.

Sécurité

Nous avons une notion de sécurité déjà importante avec les conteneurs. Nous pouvons améliorer encore la sécurité de manière simple. En effet, avec Docker, vous pouvez créer des réseaux de communication. Par défaut, vous devez créer un réseau et l’exposer pour utiliser votre application sur internet ou votre intranet. Cette partie est souvent liée avec le Proxy pour la redirection des domaines sur vos applications.

Si vous utilisez une architecture micro-service, ou que vous utilisez plusieurs images Docker (votre application + une base de données par exemple), vous pouvez créer un autre réseau pour ne pas exposer les parties non pertinentes.

Le schéma ci-dessus montre une bonne façon de faire son architecture. Nous devons exposer le moins de conteneurs possible, pour cela nous pouvons faire des réseaux privés. Nous pouvons aussi voir que certains projets partagent des Web Services et des bases de données. Pour ce faire, il suffit d’ajouter deux réseaux privés sur le Service qui va être utilisé par le site 1 et le site 2. Nous aborderons ces détails dans la partie pratique dans un autre article.

Les images docker

Nous pouvons récupérer des images Docker sur des Hubs public ou privé (que vous allez choisir pour vos projets d’entreprise). Le plus connu est le Docker Hub, c’est ici que vous allez trouver de la ressource pour vos projets.

Pour la création d’une image Docker pour votre application, vous allez devoir choisir une image de base et la modifier pour ajouter les dépendances de votre projet. Pour finir vous allez copier votre application dans un dossier pour que le runtime de votre techno l’exécute. Il y a de nombreuses images Docker, si vous utilisez des langages connus, il est recommandé de prendre les versions officielles.

Voici un exemple des images disponibles pour .NET Core, nous retrouvons différentes versions basées sur des images Docker différentes (Debian, Alpine et Ubuntu). Nous retrouvons souvent ce trio pour les projets Docker.

Je ne vais pas tourner autour du pot, la version basée sur Alpine sera forcément plus légère et réactive comparé à Debian et Ubuntu. Alpine Linux est un système qui a vraiment le strict minimum vital, ce qui lui permet d’être le plus léger et réactif de tous. Cependant, il a un gestionnaire d’application différent (mais simple) apk et le dépôt du système à un peu moins de choix qu’une base Debian/Ubuntu, mais pas de soucis pour faire une image Docker personnalisée.

Par ailleurs, si vous regardez la première ligne du tableau ci-dessus, vous allez voir un « latest ». Il est à bannir de vos projets ! Vous devez par exemple choisir « 3.1-buster-slim » ou « 3.1 », ou mieux « 3.1-alpine ». La construction de ces images sont dynamiques et inclut des patchs de sécurité. Il suffira juste de relancer votre création d’image Docker pour prendre ces modifications. Libre à vous d’automatiser cette tâche depuis Azure DevOps ou toute autre solution de déploiement.

Nous allons maintenant passer à la pratique dans le chapitre suivant !

Lire les articles similaires

Laisser un commentaire

Social Share Buttons and Icons powered by Ultimatelysocial