Vous êtes sur la page 1sur 20

1 La virtualisation

1.1 Le fonctionnement de la virtualisation


Le fonctionnement de la virtualisation reste assez simple, c’est qu’au lieu d’avoir un serveur avec
un système d’exploitation faisant tourner une ou plusieurs application(s), on préférera mutualiser
plusieurs serveurs virtuels depuis un serveur physique grâce à un logiciel nommé l’hyperviseur.
L’hyperviseur permet d’émuler intégralement les différentes ressources matérielles d'un serveur
physique (tels que l'unité centrale, le CPU, la RAM, le disque dur, carte réseau etc., ...), et permet
à des machines virtuelles de les partager.
Ainsi ces machines virtuelles nommées aussi VM (Virtual Machine) bénéficieront de ressources
matérielles selon leurs besoins (par exemple plus de puissance processeur et plus de mémoire
vive mais avec moins d’espace disque). L'avantage c'est qu'il est possible de modifier les
ressources physiques de ces VMs en quelques clics. De plus elles possèdent leur propre système
d’exploitation ainsi que leurs propres applications.

1.2 Les avantages de virtualisation


 Consacrer les ressources adaptées selon les applications qu'on souhaite mettre en place.
 Les machines virtuelles restent simples à manier. Il est possible par exemple de basculer
une VM d'un lieu à l'autre voir même de sauvegarder et de dupliquer une VM à volonté
sans aucun impact visible pour les utilisateurs.
 La virtualisation réduit les dépenses en abaissant le besoin de systèmes matériels
physiques. Elle permet ainsi de réduire la quantité d'équipement nécessaire et les coûts de
maintenance d'alimentation et de refroidissement des composants.
 Les machines virtuelles apportent également une aisance à l'administration car un
matériel virtuel n'est pas sujet aux défaillances. Les administrateurs profitent des
environnements virtuels pour faciliter les sauvegardes, la reprise après catastrophe.

1.3 Les inconvénients de la virtualisation


 Le fait d’accéder aux ressources de façon virtuelle affaiblie les performances, cela est dû
car on passe par une couche d’abstraction matérielle qui malheureusement doit faire des
interprétations entre le matériel en place et celui simulé dans la machine virtuelle.
 Comme expliqué plus haut la virtualisation consiste à faire fonctionner sur un seul
ordinateur physique plusieurs VMs avec différents systèmes d'exploitation, comme s'ils
fonctionnaient sur des ordinateurs distincts. Mais malheureusement cette couche
d'OS consomme à lui tout seul énormément de ressources alors qu’au final, ce qui nous
intéresse c’est la ou les applications qui vont tourner dessus.

2 La conteneurisation

2.1 Qu’est-ce qu’un conteneur ?

Un conteneur est un environnement faiblement isolé qui nous permet de générer et


d’exécuter des packages de logiciels. Ces packages de logiciels incluent le code et toutes
les dépendances permettant d’exécuter des applications de façon rapide et fiable dans
n’importe quel environnement informatique. Nous appelons ces packages des images
conteneur.

L’image conteneur devient l’unité que nous utilisons pour distribuer nos applications.

2.2 Qu’est-ce que la conteneurisation d’une application?

La conteneurisation d’une application est une méthode de virtualisation de système


d’exploitation utilisée pour déployer et exécuter des conteneurs sans utiliser de machine
virtuelle. Les conteneurs peuvent s’exécuter sur du matériel physique, dans le cloud, sur
des machines virtuelles et sur plusieurs systèmes d’exploitation.

2.3 La conteneurisation vs virtualisation


2.3.1 L'isolation
Dans le cas de la virtualisation l’isolation des VMs se fait au niveau matérielles
(CPU/RAM/Disque) avec un accès virtuel aux ressources de l'hôte via un hyperviseur. De plus,
généralement les ordinateurs virtuels fournissent un environnement avec plus de ressources que la
plupart des applications n'en ont besoin.
Cependant dans le cas de la conteneurisation, l’isolation se fait au niveau du système
d’exploitation. Un conteneur va s'exécuter sous Linux de manière native et va partager le
noyau de la machine hôte avec d'autres conteneurs. Ne prenant pas plus de mémoire que tout
autre exécutable, ce qui le rend léger.
2.3.2 Utilisation des ressources
La machine virtuelle intègre elle-même un OS pouvant aller jusqu’à des Giga-octets.
Alors que, le conteneur appel directement l'OS pour réaliser ses appels système et
exécuter ses applications. Il est beaucoup moins gourmand en ressources

2.3.3 Portabilité
Le déploiement est un des points clés à prendre en compte de nos jours. On peut déplacer
les conteneurs d’un environnement à l’autre très rapidement (en réalité c'est encore plus
simple et rapide avec Docker, car il suffit juste de partager des fichiers de config qui sont
en général très légers).

2.4 Pourquoi Docker est si populaire ?


La conteneurisation est loin d'être une technologie récente. En réalité les conteneurs ne sont pas si
nouveaux que ça, comme on pourrait le croire. Je peux en citer quelques technologies comme
Chroot sur Unix (1982), Jail sur BSD (2000), conteneurs sur Solaris (2004), LXC (Linux
conteneurs) sur Linux (2008). La célébrité de docker vient du fait qu'il a su permettre aux
utilisateurs de gérer facilement leurs conteneurs avec une interface en ligne de commande simple.
Les conteneurs ne sont pas nouveaux, mais leur utilisation pour déployer facilement des
applications l'est.

3 Docker

3.1 Qu’est-ce que Docker ?


Docker est une plateforme de conteneurisation utilisée pour développer, livrer et exécuter des
conteneurs.
Docker n’utilise pas d’hyperviseur, et vous pouvez l’exécuter sur votre station de travail ou votre
portable.
La version pour station de travail de Docker (Docker Desktop) prend en charge Linux, Windows
et MacOs.

3.2 Architecture de Docker

La plateforme Docker est constituée de plusieurs composants que nous utilisons pour
générer, exécuter et gérer nos applications conteneurisées.

3.2.1 Moteur Docker

Le moteur Docker est constitué de plusieurs composants configurés selon une


implémentation client-serveur, dans laquelle le client et le serveur s’exécutent
simultanément sur le même hôte. Le client communique avec le serveur en utilisant une
API REST, qui permet au client de communiquer également avec une instance de serveur
distante.
Le diagramme montre un carré qui représente Docker Hub avec des images conteneur et
un autre carré qui représente un hôte Docker. Une flèche affiche la communication entre
Docker Hub et un hôte Docker.

L’hôte Docker contient deux objets. L’un représente le moteur Docker et le second les
conteneurs Docker en cours d’exécution. L’objet de l’hôte Docker contient quatre objets :
le serveur Docker, l’API REST Docker, le client Docker et les images conteneur
stockées.

Des flèches montrent la communication entre le serveur Docker, l’API REST et le client
Docker. Ces flèches indiquent la façon dont l’utilisateur communique avec le serveur
Docker via l’API REST.

Des flèches montrent la communication entre le serveur Docker, les conteneurs exécutés
et les images conteneur stockées. Ces flèches indiquent comment le serveur Docker
charge les images conteneur stockées et gère les conteneurs exécutés.

Le client Docker

Le client Docker est une application en ligne de commande nommée docker, qui nous
fournit une interface en ligne de commande pour interagir avec un serveur Docker. La
commande docker utilise l’API REST de Docker pour envoyer des instructions à un
serveur local ou distant, et est l’interface principale que nous utilisons pour gérer nos
conteneurs.

Le serveur Docker

Le serveur Docker est un démon nommé dockerd. Le démon dockerd répond aux


demandes du client via l’API REST de Docker et peut interagir avec d’autres démons. Le
serveur Docker est également responsable du suivi du cycle de vie de nos conteneurs.

Objets Docker
Vous allez créer et configurer plusieurs objets pour prendre en charge les déploiements
de vos conteneurs. Il s’agit de réseaux, de volumes de stockage, de plug-ins et autres
objets de service. Nous ne couvrirons pas tous ces objets ici, mais il est bon de garder à
l’esprit que ces objets sont des éléments que nous pouvons créer et déployer en fonction
des besoins.

3.2.2 Docker Hub

Docker Hub est un registre de conteneurs Docker SaaS (Software-as-a-Service). Les


registres Docker sont des référentiels que nous utilisons pour stocker et distribuer les
images conteneur que nous créons. Docker Hub est le registre public par défaut utilisé par
Docker pour la gestion des images.

Gardez à l’esprit que vous pouvez créer et utiliser un registre Docker privé ou utiliser une
des nombreuses options de fournisseur cloud disponibles. Par exemple, vous pouvez
utiliser Azure Container Registry pour stocker les conteneurs Docker à utiliser dans
plusieurs services Azure compatibles avec les conteneurs.

4 Éditions Docker
Docker est principalement disponible en deux éditions Community et Enterprise édition. L'édition
communautaire est livrée avec un ensemble gratuit de produits Docker. En revanche, l'édition
entreprise est une plate-forme de conteneur certifiée qui facilite les utilisateurs commerciaux avec
des fonctionnalités complémentaires telles que la sécurité des images, la gestion des images,
l'orchestration et la gestion de l'exécution des conteneurs, mais à un coût raisonnable.
Nous commencerons notre apprentissage avec Community Edition. Les conteneurs Docker
exécutés sur un système d'exploitation particulier partagent le noyau du système d'exploitation
sous-jacent. Cela signifie que nous ne pouvons pas utiliser le noyau Windows (hôte) pour
exécuter des conteneurs Linux ou vice versa. Pour surmonter cela, nous avons Docker Desktop
pour Windows et MAC.

5 Version de Docker
La version de l'édition communautaire Docker Desktop est disponible en deux versions.
 Stable : Comme son nom l'indique, Stable Edition est minutieusement testée et peut être
utilisée pour développer des applications plus fiables. Ses versions sont entièrement
synchronisées avec les versions de Docker Engine. Sur le canal stable, il existe une
option pour choisir d'envoyer ou non les statistiques d'utilisation.
 Bord : Ces versions comprennent toutes les fonctionnalités nouvelles et expérimentales
du moteur Docker. Il y a plus de chances que des bogues, des plantages et des
problèmes se produisent. Cependant, les utilisateurs auront l'occasion de se familiariser
avec les fonctionnalités à venir.
6 Installer Docker Desktop sur Windows
1. Double-cliquez sur Docker Desktop Installer.exe pour exécuter le programme
d'installation. Si vous n'avez pas encore téléchargé le programme d'installation (Docker
Desktop Installer.exe), vous pouvez l'obtenir à partir de Docker Hub.
2. Lorsque vous y êtes invité, assurez-vous que l'option Activer les fonctionnalités
Windows Hyper-V ou Installer les composants Windows requis pour WSL 2 est
sélectionnée sur la page Configuration.
3. Suivez les instructions de l'assistant d'installation pour autoriser le programme
d'installation et poursuivez l'installation.
4. Une fois l'installation réussie, cliquez sur Fermer pour terminer le processus
d'installation.
5. Si votre compte administrateur est différent de votre compte utilisateur, vous devez
ajouter l'utilisateur au groupe docker-users. Exécutez Gestion de l'ordinateur en tant
qu'administrateur et accédez à Utilisateurs et groupes locaux > Groupes > docker-users.
Cliquez avec le bouton droit pour ajouter l'utilisateur au groupe. Déconnectez-vous et
reconnectez-vous pour que les modifications prennent effet.

7 Démarrer Docker Desktop


Docker Desktop ne démarre pas automatiquement après l'installation. Pour démarrer Docker
Desktop, recherchez Docker et sélectionnez Docker Desktop dans les résultats de la recherche.

Lorsque l'icône de la baleine dans la barre d'état reste fixe, Docker Desktop est opérationnel et
accessible depuis n'importe quelle fenêtre de terminal.

Si l'icône de la baleine est masquée dans la zone Notifications, cliquez sur la flèche vers le haut
de la barre des tâches pour l'afficher. Pour en savoir plus, voir Paramètres Docker.

Une fois l'initialisation terminée, Docker Desktop lance le didacticiel d'intégration. Le didacticiel
comprend un exercice simple pour créer un exemple d'image Docker, l'exécuter en tant que
conteneur, envoyer et enregistrer l'image sur Docker Hub.
8 Exercices
8.1 Récupérer une image Docker existante et la déployer localement

Un bon point de départ pour générer et exécuter vos propres images Docker consiste à
prendre une image existante dans Docker Hub et à l’exécuter localement sur votre
ordinateur.

Comme preuve de concept pour les applications de l’entreprise, vous décidez d’essayer
d’exécuter un exemple d’image à partir de Docker Hub. L’image que vous avez
sélectionnée implémente une application web ASP.NET .NET Core de base. Une fois que
vous avez établi un processus pour le déploiement d’une image Docker, vous pouvez
exécuter une des applications web de votre entreprise à l’aide de Docker.

Dans cet exercice, vous allez tirer une image de Docker Hub et l’exécuter. Vous allez
examiner l’état local de Docker pour mieux comprendre les éléments qui sont déployés.
Enfin, vous allez supprimer le conteneur et l’image de votre ordinateur.

8.1.1 Tirer un exemple d’application de Docker Hub et l’exécuter

1. Ouvrez une fenêtre d’invite de commandes sur votre ordinateur local.


2. Tirez l’image d’application ASP.NET Sample du registre Docker Hub.
Cette image contient un exemple d’application web développée par
Microsoft. Il repose sur le modèle ASP.NET par défaut disponible dans
Visual Studio.

docker pull mcr.microsoft.com/dotnet/core/samples:aspnetapp

3. Vérifiez que l’image a été stockée localement.


docker image list

Vous devez voir un dépôt nommé mcr.microsoft.com/dotnet/core/samples et


ayant l’étiquette aspnetapp.

4. Créer un container à partir de l’image téléchargée :

docker run -d -p 8080:80 mcr.microsoft.com/dotnet/core/samples:aspnetapp

 -d pour l’exécuter en tant qu’application non interactive d’arrière-


plan.
 -p pour mapper le port 80 dans le conteneur qui est créé au
port 8080 localement.

5. Ouvrez un navigateur web et accédez à la page de l’exemple d’application


web à l’adresse http://localhost:8080. La page ressemble à la capture
d’écran suivante.

8.1.2 Examiner le conteneur dans le registre Docker local

1. Depuis l’invite de commandes, affichez les conteneurs en cours d’exécution


dans le registre local.

docker ps

La sortie doit être semblable à ce qui suit.


CONTAINER ID IMAGE COMMAND CREATED
STATUS PORTS NAMES
bffd59ae5c22 mcr.microsoft.com/dotnet/core/samples:aspnetapp "dotnet aspnetapp.dll"
12 seconds ago Up 11 seconds 0.0.0.0:8080->80/tcp competent_hoover
Le champ COMMAND indique le conteneur démarré à l’aide de la
commande dotnet aspnetapp.dll. Cette commande appelle le runtime .NET
Core pour démarrer le code dans le fichier aspnetapp.dll (le code de
l’exemple d’application web). Le champ PORTS indique que le port 80 dans
l’image a été mappé au port 8080 sur votre ordinateur. Le
champ STATUS indique que l’application est toujours en cours d’exécution.
Notez le nom (NAME) du conteneur.

2. Arrêtez le conteneur Docker. Spécifiez le nom du conteneur de l’application


web dans la commande suivante, à la place de <NAME>.

docker container stop <NAME>

3. Vérifiez que le conteneur n’est plus en cours d’exécution. Exécutez la


commande suivante pour afficher l’état du conteneur Quitté. L’indicateur -
a indique que la commande affiche l’état de tous les conteneurs, pas
uniquement ceux qui sont en cours d’exécution.

docker ps -a

4. Revenez au navigateur web et actualisez la page de l’exemple d’application


web. Elle doit échouer avec une erreur Connection Refused (Connexion
refusée).

8.1.3 Supprimer le conteneur et l’image du registre local

1. Bien que le conteneur se soit arrêté, il est toujours chargé et peut être
redémarré. Supprimez-le en exécutant la commande suivante. Comme
auparavant, remplacez <NAME> par le nom de votre conteneur.

docker container rm <NAME>

2. Vérifiez que le conteneur a été supprimé en exécutant la commande


suivante. La commande ne doit plus lister le conteneur.

docker ps -a

3. Listez les images disponibles sur votre ordinateur.

docker image list

4. Supprimez l’image du registre.

docker image rm mcr.microsoft.com/dotnet/core/samples:aspnetapp

5. Listez à nouveau les images pour vérifier que l’image de l’application


web microsoft/dotnet-samples a disparu.
docker image list

8.2 Personnaliser une image Docker pour qu’elle exécute votre propre
application web

Le déploiement d’une application sous un container se fait via un fichier portant


le nom Dockerfile (Sans extension et sous la même casse), ce fichier contient les
étapes de la génération d’une image Docker personnalisée.

Application à déployer : Une application web simple qui implémente une API web
pour un site web de réservations d’hôtel. L’API web expose les opérations HTTP
POST et GET qui créent et récupèrent les réservations du client.

Notes : Dans cette version de l’application web, les réservations ne sont pas
réellement conservées et les requêtes retournent des données factices.

Dans cet exercice, vous allez créer un fichier Dockerfile pour une application qui
n’en possède pas. Ensuite, vous allez générer l’image et l’exécuter localement.

8.2.1 Créer un fichier Dockerfile pour l’application web

1. Dans une fenêtre d’invite de commandes sur votre ordinateur local,


exécutez la commande suivante afin de télécharger le code source de
l’application web.

git clone https://github.com/MicrosoftDocs/mslearn-hotel-


reservation-system.git

2. Accédez au dossier src.

cd mslearn-hotel-reservation-system/src

3. Dans ce répertoire, créez un fichier Dockerfile sans extension de


fichier et ouvrez-le dans un éditeur de texte. Sur Windows, vous
pouvez exécuter les commandes suivantes.

copy NUL Dockerfile


notepad Dockerfile

Notes : La commande ci-dessus vous propose un fichier texte à


enregistrer. Cependant, si vous utilisez cette méthode, vous pouvez
quand même être amené à accéder au dossier et à supprimer
l’extension .txt. Enregistrez-le en tant que Dockerfile (et NON
Dockerfile.txt)

4. Ajoutez les commandes suivantes au fichier Dockerfile. Ces


commandes récupèrent une image contenant le SDK .NET Core
Framework. Les fichiers projet de l’application web
(HotelReservationSystem.csproj) et le projet de bibliothèque
(HotelReservationSystemTypes.csproj) sont copiés dans le dossier /src
du conteneur. La commande *dotnet restore* télécharge les
dépendances requises par ces projets à partir de NuGet.

FROM mcr.microsoft.com/dotnet/core/sdk:2.2
WORKDIR /src
COPY ["HotelReservationSystem/HotelReservationSystem.csproj",
"HotelReservationSystem/"]
COPY
["HotelReservationSystemTypes/HotelReservationSystemTypes.csproj",
"HotelReservationSystemTypes/"]
RUN dotnet restore
"HotelReservationSystem/HotelReservationSystem.csproj"

5. Ajoutez les commandes suivantes au fichier Dockerfile. Ces


commandes copient le code source de l’application web dans le
conteneur, puis exécutent la commande dotnet build pour générer
l’application. Les DLL qui en résultent sont écrites dans le dossier
/app du conteneur.

COPY . .
WORKDIR "/src/HotelReservationSystem"
RUN dotnet build "HotelReservationSystem.csproj" -c Release -o
/app

6. Ajoutez la commande suivante au fichier Dockerfile. La


commande dotnet publish copie les fichiers exécutables pour le site
web dans un nouveau dossier et supprime tous les fichiers
temporaires. Les fichiers de ce dossier peuvent ensuite être déployés
sur un site web.

RUN dotnet publish "HotelReservationSystem.csproj" -c Release -


o /app

7. Ajoutez les commandes suivantes au fichier Dockerfile. La première


commande ouvre le port 80 dans le conteneur. La deuxième
commande accède au dossier /app contenant la version publiée de
l’application web. La dernière commande spécifie que quand le
conteneur s’exécute il doit exécuter la commande dotnet
HotelReservationSystem.dll. Cette bibliothèque contient le code
compilé de l’application web.

EXPOSE 80
WORKDIR /app
ENTRYPOINT ["dotnet", "HotelReservationSystem.dll"]

8. Enregistrez le fichier, puis fermez votre éditeur de texte.

8.2.2 Générer et déployer l’image à l’aide du fichier Dockerfile

1. Depuis l’invite de commandes, exécutez la commande suivante afin


de générer l’image pour l’exemple d’application à l’aide du fichier
Dockerfile. N’oubliez pas le caractère (.) à la fin de la commande.
Cette commande génère l’image et la stocke localement. Le
nom reservationsystem est attribué à l’image. Vérifiez que l’image est
générée correctement. Un avertissement à propos des autorisations
de fichier et de répertoire s’affiche quand le processus est terminé.
Vous pouvez ignorer ces avertissements dans le cadre de cet
exercice.

docker build -t reservationsystem .

2. Exécutez la commande suivante pour vérifier que l’image a été créée


et stockée dans le registre local.

docker image list

L’image aura le nom reservationsystem. Vous verrez également une


image nommée microsoft/dotnet. Cette image contient le SDK .NET
Core et a été téléchargée quand l’image reservationsystem a été
générée à l’aide du fichier Dockerfile.

REPOSITORY TAG IMAGE ID


CREATED SIZE
reservationsystem latest d2501f0f2ced About
a minute ago 1.76GB
microsoft/dotnet 2.1-sdk c17aa78d71c2 8 days
ago 1.73GB
8.2.3 Tester l’application web

1. Exécutez un conteneur utilisant l’image reservationsystem à l’aide de


la commande suivante. Docker répond avec une longue chaîne de
chiffres hexadécimaux ; le conteneur s’exécute en arrière-plan sans
aucune interface utilisateur. Le port 80 dans le conteneur est mappé
au port 8080 sur la machine hôte. Le conteneur est
nommé reservations.

docker run -p 8080:80 -d --name reservations reservationsystem

2. Démarrez un navigateur web et accédez


à http://localhost:8080/api/reservations/1 . Vous devriez voir un
document JSON contenant les données pour la réservation numéro 1
retournées par l’application web. Vous pouvez remplacer « 1 » par
n’importe quel numéro de réservation, et vous verrez alors les détails
de la réservation correspondante.

3. Examinez l’état du conteneur en exécutant la commande suivante.

docker ps -a

Vérifiez que l’état du conteneur est Up.

CONTAINER ID IMAGE COMMAND


CREATED STATUS PORTS
NAMES
07b0d1de4db7 reservationsystem "dotnet HotelReserva…" 5
minutes ago Up 5 minutes 0.0.0.0:8080->80/tcp
reservations

4. Arrêtez le conteneur réservations en exécutant la commande


suivante.

docker container stop reservations

5. Supprimez le conteneur reservations du registre local.

docker rm reservations

6. Laissez reservationsystem dans le registre local. Vous utiliserez cette


image dans l’exercice suivant.

Vous avez créé une image pour votre application web et l’avez exécutée à l’aide
d’un conteneur Docker.
8.3 Conteneuriser une application web Python
Dans ce qui suit, vous allez créer une application Web Python simple exécutée sur Docker.
L'application se composera de deux containers :

- Un container Python pour la page web en Python exécuté sur le Framework Flask
- Un container Redis qui représente un cache Redis pour gérer le compteur d'accès.

Dans ce qui suit les étapes :

1. Créer un répertoire Python :


mkdir Python
cd Python
2. Créez un fichier appelé app.py et coller dedans :
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I have been seen {} times.\n'.format(count)

Dans cet exemple, redis est le nom d'hôte du conteneur. Nous utilisons le port par défaut
pour Redis, 6379.
3. Créer un fichier requirements.txt et coller dedans:
flask
redis
4. Créer un fichier Dockerfile et coller dedans :
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]
Cela indique à Docker de:

 Créer une image à partir de Python 3.7


 Définir le répertoire de travail sur /code
 Définir les variables d'environnement
 Installer gcc et d'autres dépendances
 Copier requirements.txt
 Installer les dépendances Python
 Spécifier que le conteneur écoute sur le port 5000
 Copier le répertoire actuel dans le répertoire de travail
 Exécuter la commande : flask run.

5. Créer le container Python :

Exécuter les commandes suivantes :

docker build -t imgpython .


docker run -d -p 5000:5000 –-name python imgpython

6. Créer le container Redis :

Créer un répertoire Redis :


mkdir Redis
cd Redis

Créer un fichier Dockerfile et copier dedans :

FROM redis:alpine

Exécuter les commandes suivantes :

docker build -t imgredis .

docker run -d –-name redis imgredis

7. Créer un réseau Docker :


docker network create my-network

Maintenant, connectons les deux containers :

docker network connect my-network python

docker network connect my-network redis

8. Aller à http://localhost:5000 pour voir l'application en cours d'exécution.


Vous devriez voir un message dans votre navigateur disant :

Actualiser la page. Le nombre doit augmenter.

8.4 Utiliser un container pour un modèle Machine Learning


Afin de commencer à créer un conteneur Docker pour un modèle Machine Learning, on aura
besoin de cinq fichiers :train.py, inference.py, train.csv, test.csv et Dockerfile.

8.4.1 Fichier train.py


Le train.py est un script python qui ingère et normalise les données EEG dans un fichier csv
(train.csv) et entraîne deux modèles pour classer les données (à l'aide de scikit-learn). Le script
enregistre deux modèles : Linear Discriminant Analysis (clf_lda) et Neural Networks multi-layer
perceptron (clf_NN).
#!/usr/bin/python3
# train.py
# Xavier Vasques 13/04/2021

import platform; print(platform.platform())


import sys; print("Python", sys.version)
import numpy; print("NumPy", numpy.__version__)
import scipy; print("SciPy", scipy.__version__)

import os
import numpy as np
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.neural_network import MLPClassifier
import pandas as pd
from joblib import dump
from sklearn import preprocessing

def train():

# Load directory paths for persisting model

MODEL_DIR = os.environ["MODEL_DIR"]
MODEL_FILE_LDA = os.environ["MODEL_FILE_LDA"]
MODEL_FILE_NN = os.environ["MODEL_FILE_NN"]
MODEL_PATH_LDA = os.path.join(MODEL_DIR, MODEL_FILE_LDA)
MODEL_PATH_NN = os.path.join(MODEL_DIR, MODEL_FILE_NN)

# Load, read and normalize training data


training = "./train.csv"
data_train = pd.read_csv(training)

y_train = data_train['# Letter'].values


X_train = data_train.drop(data_train.loc[:, 'Line':'# Letter'].columns, axis = 1)

print("Shape of the training data")


print(X_train.shape)
print(y_train.shape)

# Data normalization (0,1)


X_train = preprocessing.normalize(X_train, norm='l2')

# Models training

# Linear Discrimant Analysis (Default parameters)


clf_lda = LinearDiscriminantAnalysis()
clf_lda.fit(X_train, y_train)

# Save model
from joblib import dump
dump(clf_lda, MODEL_PATH_LDA)

# Neural Networks multi-layer perceptron (MLP) algorithm


clf_NN = MLPClassifier(solver='adam', activation='relu', alpha=0.0001, hidden_layer_sizes=(500,), random_state=0, max_iter=1000)
clf_NN.fit(X_train, y_train)

# Record model
from joblib import dump, load
dump(clf_NN, MODEL_PATH_NN)
import json
import os

from joblib import dump


import matplotlib.pyplot as plt
import numpy as np
from sklearn import ensemble
from sklearn import datasets
from sklearn.utils import shuffle
from sklearn.metrics import mean_squared_error

# #############################################################################
# Load directory paths for persisting model and metadata

MODEL_DIR = os.environ["MODEL_DIR"]
MODEL_FILE = os.environ["MODEL_FILE"]
METADATA_FILE = os.environ["METADATA_FILE"]
MODEL_PATH = os.path.join(MODEL_DIR, MODEL_FILE)
METADATA_PATH = os.path.join(MODEL_DIR, METADATA_FILE)

# #############################################################################
# Load and split data
print("Loading data...")
boston = datasets.load_boston()

print("Splitting data...")
X, y = shuffle(boston.data, boston.target, random_state=13)
X = X.astype(np.float32)
offset = int(X.shape[0] * 0.9)
X_train, y_train = X[:offset], y[:offset]
X_test, y_test = X[offset:], y[offset:]

# #############################################################################
# Fit regression model
print("Fitting model...")
params = {'n_estimators': 500, 'max_depth': 4, 'min_samples_split': 2,
'learning_rate': 0.01, 'loss': 'ls'}
clf = ensemble.GradientBoostingRegressor(**params)
clf.fit(X_train, y_train)
train_mse = mean_squared_error(y_train, clf.predict(X_train))
test_mse = mean_squared_error(y_test, clf.predict(X_test))
metadata = {
"train_mean_square_error": train_mse,
"test_mean_square_error": test_mse
}

# #############################################################################
# Serialize model and metadata
print("Serializing model to: {}".format(MODEL_PATH))
dump(clf, MODEL_PATH)

print("Serializing metadata to: {}".format(METADATA_PATH))


with open(METADATA_PATH, 'w') as outfile:
json.dump(metadata, outfile)

8.4.2 Fichier inference.py


Le fichier inference.py sera appelé pour effectuer l'inférence par lots en chargeant les deux
modèles précédemment créés. L'application normalisera les nouvelles données EEG provenant
d'un fichier csv (test.csv), effectuera une inférence sur l'ensemble de données et imprimera la
précision et les prédictions de la classification.
import os

from joblib import load


import numpy as np
from sklearn import datasets
from sklearn.utils import shuffle

MODEL_DIR = os.environ["MODEL_DIR"]
MODEL_FILE = os.environ["MODEL_FILE"]
METADATA_FILE = os.environ["METADATA_FILE"]
MODEL_PATH = os.path.join(MODEL_DIR, MODEL_FILE)
METADATA_PATH = os.path.join(MODEL_DIR, METADATA_FILE)

def get_data():
"""
Return data for inference.
"""
print("Loading data...")
boston = datasets.load_boston()
X, y = shuffle(boston.data, boston.target, random_state=13)
X = X.astype(np.float32)
offset = int(X.shape[0] * 0.9)
X_train, y_train = X[:offset], y[:offset]
X_test, y_test = X[offset:], y[offset:]
return X_test, y_test

print("Running inference...")

X, y = get_data()

# #############################################################################
# Load model
print("Loading model from: {}".format(MODEL_PATH))
clf = load(MODEL_PATH)

# #############################################################################
# Run inference
print("Scoring observations...")
y_pred = clf.predict(X)
print(y_pred)

8.4.3 Fichier train.csv


https://raw.githubusercontent.com/xaviervasques/EEG-letters/main/train.csv
8.4.4 Fichier test.csv
https://raw.githubusercontent.com/xaviervasques/EEG-letters/main/test.csv

8.4.5 Fichier Dockerfile


Le fichier Dockerfile va contenir le script de la conteneurisation du modèle en utilisant l'image
jupyter/scipy-notebook comme image de base.
Dans cette image il faut :

- Installer joblib pour permettre la sérialisation et la désérialisation de notre modèle formé.


- Copier les fichiers train.csv, test.csv, train.py et inference.py
- Ensuite, exécuter train.py qui adaptera et sérialisera les modèles ML.
FROM jupyter/scipy-notebook

RUN pip install joblib

RUN mkdir model


ENV MODEL_DIR=/home/jovyan/model
ENV MODEL_FILE=clf.joblib
ENV METADATA_FILE=metadata.json

COPY train.py ./train.py


COPY inference.py ./inference.py

RUN python3 train.py

Afin de construire l'image, exécuter la commande suivante :


docker build -t docker-ml-model -f Dockerfile .

Il est temps d'effectuer l'inférence sur les nouvelles données (test.csv) :


docker run docker-ml-model python3 inference.py

Pour aller loin : https://mlinproduction.com/docker-for-ml-part-4/

Vous aimerez peut-être aussi