Héberger une application ASP.Net Core sur le cloud AWS via Docker

Xavier WOLFF

Amazon Web Service est un fournisseur de services cloud lancé en 2006. Il rencontre depuis sa mise en ligne un vif succès auprès des entreprises, grâce à une grande liste de services disponibles pour ses utilisateurs. Son principal concurrent dans les services cloud est Microsoft Azure, mis à disposition des clients à partir de 2010.

Les objectifs de cet article sont dans un premier temps de faire une introduction à AWS. Nous allons nous créer puis nous authentifier sur un compte gratuit, créer notre première machine virtuelle sous Linux et nous connecter en SSH à cette dernière. Dans une deuxième partie, nous allons mettre en place un conteneur Docker afin de pouvoir déployer notre application ASP.NET Core. Pour finir, nous déploierons notre conteneur Docker dans un service AWS appelé Elastic Beanstalk.

Commentez ♪

- Titre : Héberger une application ASP.Net Core sur le cloud AWS via Docker

- Auteur : Xavier WOLFF

- Parution : 13 juin 2016

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2016 Xavier WOLFF. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Introduction

- II. Définitions

- III. Introduction à AWS

- IV. Création d'une machine virtuelle

- V. Connexion SSH à la machine virtuelle

- VI. Configuration de la machine virtuelle

- VI-A. Installation de tous les paquets

- VI-B. Création du projet web à publier

- VII. Mise en place du conteneur Docker

- VIII. Déploiement sous Elastic Beanstalk

- IX. Conclusion

- X. Remerciements

I - Introduction

Le graphique suivant montre la répartition des parts de marchés entre les différents « Cloud Service Provider » sur le troisième trimestre 2015 permettant de mettre en évidence le fossé entre AWS et ses concurrents :

II - Définitions

Avant de commencer la démonstration, je vais définir certains termes afin que la suite de l'article se passe dans les meilleures conditions possible :

ASP.NET Core est la nouvelle plateforme de développement web Microsoft. Il s'agit de l'implémentation open source du Framework .Net permettant de faire du développement web. Microsoft a aussi mis en place un environnement d'exécution multiplateforme appelé « .NET Core ». Cet environnement permet d'exécuter des applications web, mais aussi d'autres types de projets (console par exemple) sur des serveurs Linux. En effet, un serveur IIS n'est plus nécessaire pour héberger et lancer ces applications.

Docker est un logiciel libre permettant de déployer des applications de manière automatisée. Le principe de Docker est d'embarquer une application et toutes ses dépendances dans un conteneur. Ce dernier pourra être déployé et exécuté depuis n'importe quel serveur. Un conteneur se base sur une image, qui est la définition de ce dont l'application a besoin pour s'exécuter correctement. Il existe un grand nombre d'images, dont une pour ASP.NET Core.

Elastic Beanstalk est une solution permettant de déployer facilement des applications sur les serveurs Amazon Web Service. Il est possible de déployer des applications développées avec PHP, Java, .Net, Python, Docker, etc. Étant donné qu'ASP.NET Core est encore récent, il n'est pas aisé de déployer l'application directement sur Elastic Beanstalk, c'est pourquoi la meilleure pratique actuelle est de déployer un conteneur Docker contenant notre application web ASP.NET Core (à l'inverse d'ASP.NET MVC 4 par exemple). Cela permettra aussi de faire une introduction à Docker. L'avantage du service Elastic Beanstalk est que nous n'avons pas à nous préoccuper outre mesure de l'environnement. La scalabilité, l'équilibrage de la charge et les mises à jour applicatives sont gérés par AWS (et totalement configurables par vous-même). Nous avons juste à nous concentrer sur le développement. Un ensemble d'indicateurs permettant de monitorer l'environnement mis en place sont également disponibles.

ASP.NET Core était en version RC1 lors de la publication initiale de l'article. Suite à la publication de la version finale, cet article a été mis à jour afin d'être toujours d'actualité. Les informations actuelles sont en adéquation avec la version 1.0 supprimant ainsi toute notion de « dnx ».

III - Introduction à AWS

La première partie de cet article consiste à introduire et prendre en main la plateforme AWS. La première étape consistera donc à se connecter à la plateforme en ligne.

Pour cet article, vous aurez besoin d'un compte AWS si vous voulez effectuer les opérations de votre côté. Bonne nouvelle, il est totalement gratuit pendant un an. Et même après la durée annoncée, il sera toujours possible d'effectuer un grand nombre d'opérations gratuitement. Toutes les informations sur l'utilisation du compte gratuit sont disponibles ici.

Une fois votre compte créé, vous arrivez sur la page d'accueil du site. Cet écran regroupe une liste non exhaustive de fonctionnalités disponibles avec AWS :

Notez sur la partie supérieure de cet écran, le choix de la région dans laquelle nous effectuerons nos différentes opérations. Il est facilement possible de modifier cette valeur pour héberger des services à l'autre bout du monde. Pour cet article, je vous conseille de vous mettre en Europe.

IV - Création d'une machine virtuelle

Nous allons créer une machine virtuelle AWS nous permettant de créer notre projet et le conteneur Docker. Il sera ensuite déployé avec Elastic Beanstalk.

Depuis l'écran précédent, nous allons cliquer sur « EC2 », qui correspond à « Elastic Compute Cloud ». C'est avec cet outil que nous allons créer et manager nos machines virtuelles. En cliquant ensuite sur le bouton « Launch Instance », nous arrivons dans les écrans de création d'une machine virtuelle. Pour notre tutoriel, nous allons créer une machine virtuelle « Amazon Linux » :

Le choix du type d'instance est limité dans l'offre gratuite, mais cela est largement suffisant pour nos besoins. L'ensemble des propriétés par défaut peut être sélectionné. Si vous le souhaitez, il est facilement possible de configurer votre machine selon vos envies. À l'étape 6, il est par contre nécessaire d'effectuer certaines opérations. Nous allons créer un nouveau groupe de sécurité, et ouvrir les ports SSH (port 22) et HTTP (port 80) :

Le port 22 nous permettra de nous connecter en SSH à la machine dans le cloud, alors que le port 80 est nécessaire pour afficher le site web sur notre navigateur.

En cliquant sur le bouton « Launch », une popup apparaît vous demandant à quelle clé associer cette machine. Un couple de clés permet de générer le mot de passe nécessaire pour se connecter. Ici, nous allons créer une nouvelle paire de clés avec le nom que vous voulez :

Attention, le téléchargement de cette clé n'est possible qu'une seule fois par mesure de sécurité. Une fois l'opération validée, votre machine virtuelle apparaît dans la liste des instances et est en cours de démarrage.

Félicitations, vous venez de créer votre première machine virtuelle sur AWS !

V - Connexion SSH à la machine virtuelle

Créer une VM dans le cloud est bien sympa, mais il va maintenant falloir se connecter à cette dernière. Pour me connecter à ma machine en SSH, j'utilise le logiciel « Putty ».

La première étape consiste à générer une clé privée à partir de la clé obtenue lors de la création de la machine. Pour se faire, Putty installe aussi un logiciel appelé « Putty Key Generator » (ou PUTTYgen). Une fois le logiciel ouvert, cliquez sur le bouton « Load » pour chercher le fichier précédemment téléchargé :

La clé à générer doit être une clé privée (2) de 2 048 bits (1). C'est cette nouvelle clé que nous allons utiliser dans Putty pour nous connecter.

Lancez maintenant Putty, dans la partie « Host Name », renseignez la valeur suivante :

ec2-user@dns

Lorsqu'une machine virtuelle est créée sur AWS, un utilisateur « ec2-user » est automatiquement créé. La seconde partie à renseigner est le nom de votre machine virtuelle. Il se trouve dans la liste des instances EC2 sur le site avec lequel vous avez créé la machine. Voici un exemple de « Host Name » valide :

La dernière opération à effectuer pour se connecter est d'ajouter la clé que nous avons générée précédemment à l'endroit suivant :

Si vous n'avez pas fait d'erreurs, vous devriez avoir l'écran suivant signifiant que vous êtes connecté sur votre serveur :

VI - Configuration de la machine virtuelle

Comme pour toutes les nouvelles machines virtuelles, il n'y a presque aucun paquet préinstallé. Libre à vous, si vous le souhaitez, de mettre à jour votre machine avec la commande :

sudo yum update

VI-A - Installation de tous les paquets

Nous allons donc devoir installer les éléments suivants :

1. Docker ;

2. Dotnet ;

3. Le client Elastic Beanstalk.

Installons Docker :

sudo yum install -y docker

Une fois l'installation achevée, nous allons démarrer le service et nous assurer qu'il redémarre si le serveur doit être redémarré :

sudo service docker start
sudo chkconfig docker on

Installons Dotnet (source : .NET Core installation) :

sudo yum install libunwind libicu
curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=827529
sudo mkdir -p /opt/dotnet && sudo tar zxf dotnet.tar.gz -C /opt/dotnet
sudo ln -s /opt/dotnet/dotnet /usr/local/bin

Et enfin, installons d'Elastic Beanstalk :

sudo pip install awsebcli

VI-B - Création du projet web à publier

Dotnet donne une méthode permettant de créer un projet de type web vide. Tout le squelette est construit et une page d'accueil est créée.

Pour se faire, il faut exécuter les commandes suivantes :

mkdir helloweb && cd helloweb
dotnet new -t web

VII - Mise en place du conteneur Docker

Pour déployer un conteneur Docker, nous avons uniquement besoin d'un fichier « Dockerfile » à la racine du projet (sans extension). La commande cat > Dockerfile permet de créer un fichier et d'y ajouter le contenu suivant :

FROM microsoft/dotnet:latest
COPY . /app
WORKDIR /app

RUN dotnet restore

ENV ASPNETCORE_URLS http://*:5000
EXPOSE 5000

ENTRYPOINT ["dotnet", "run"]

1. La première ligne signifie que Docker va utiliser la dernière version de l'image « Microsoft/dotnet » mise en place par leur équipe permettant de déployer un projet ASP.NET Core.

2. Copy . signifie que tout le contenu du dossier est copié dans le dossierapp. La ligne suivante permet de définir le dossier courant.

3. L'instruction Run permet de lancer une commande dotnet restore qui va se charger d'installer toutes les dépendances du projet et de récupérer tous les packages nuget.

4. L'instruction ENV permet de définir la valeur de la variable d'environnement ASPNETCORE_URLS pour que le site écoute le port 5000 (binding). La commande Expose permet à Docker de préciser que l'image écoute sur le port 5000. Ce numéro de port est important. Notez-le quelque part, nous allons le réutiliser plus tard.

5. Enfin, l'instruction Entrypoint lance le conteneur, le maintient en état de marche et commence à écouter les requêtes HTTP sur le port 5000 défini précédemment.

Pour construire l'image Docker avec ce fichier de configuration, exécutez la commande suivante :

sudo docker build -t helloweb .

Cette opération va exécuter chaque ligne du fichier Dockerfile. Le paramètre -t permet de spécifier le nom de l'image. À noter que la récupération des dépendances du projet peut prendre un certain temps.

La commande sudo docker images liste les images créées par Docker :

Pour lancer le conteneur associé à une image, il faut exécuter la commande suivante :

sudo docker run -d -p 80:5000 -t helloweb

Le port défini dans le fichier de configuration est à entrer à cet endroit-là dans le cas où vous avez précisé un autre. Le paramètre -d indique à Docker de faire tourner le conteneur en tâche de fond. -p permet de faire le lien entre le port 80 du serveur et le conteneur. Quand nous allons appeler l'URL du serveur sur le port 80, nous serons donc redirigés vers notre conteneur. -t permet à nouveau de spécifier de nom de l'image à utiliser.

sudo docker ps permet de lister tous les conteneurs actifs :

L'affichage est certes peu intuitif, mais on comprend aisément que les requêtes entrées par le port 80 sont redirigées vers le 5000 afin d'atteindre le conteneur que nous venons de déployer. Et comme nous avons ouvert le port 80 au début de notre tutoriel, si vous lancez un navigateur sur votre poste et que vous entrez l'adresse DNS du serveur, vous devriez obtenir la page suivante :

Votre site ASP.NET Core est hébergé sur une machine virtuelle Linux depuis Docker dans le cloud ! Le site est fonctionnel en l'état. La partie suivante est optionnelle et parle du produit Elastic Beanstalk permettant de gérer entre autres des problématiques de charge. Le plus dur est derrière nous.

VIII - Déploiement sous Elastic Beanstalk

La dernière étape de l'article consiste donc à déployer ce conteneur Docker dans le service « Elastic Beanstalk » d'AWS.

Comme pour Docker, le service a besoin d'un fichier de configuration à la racine du projet portant le nom Dockerrun.aws.json. Ce fichier de configuration peut prendre un grand nombre d'éléments en paramètre, dont vous trouverez la liste complète ici.

Dans notre cas, nous allons mettre la configuration minimale en place. Les commandes suivantes permettent de créer et remplir le fichier Dockerrun.aws.json :

cat > Dockerrun.aws.json
{
"AWSEBDockerrunVersion": "1"
}

Le fichier doit donc ressembler à quelque chose comme ceci :

La commande suivante va initialiser une instance d'Elastic Beanstalk. Attention, il est possible qu'on vous demande la clé d'accès et la clé d'accès secrète du compte AWS (parce qu'on va automatiquement créer une machine virtuelle en dehors du panel d'administration). Ces clés sont récupérables depuis la console AWS via le guide.

La commande est la suivante :

eb init

Un ensemble de choix va vous être proposé pour initialiser l'environnement :

1. Choix de la région : je vous conseille la même que celle du serveur utilisé précédemment ;

2. Nom de l'application ;

3. Utilisez-vous un multiconteneur Docker ? Non ;

4. Plateforme Docker ;

5. La version la plus récente ;

6. Ne pas mettre en place le SSH sur la nouvelle machine. Ce n'est pas nécessaire dans cet article.

Une fois les différentes options choisies, lancez le déploiement avec la commande :

eb create helloweb-prod

Cette opération dure entre 7 et 10 minutes. Si vous voulez faire une pause-café, c'est le moment !

Pendant ce temps, AWS va créer une nouvelle machine virtuelle, mettre en place le service Elastic Beanstalk sur cette dernière, et déployer le conteneur Docker. Vous verrez apparaître la nouvelle machine utilisée par le service pour héberger votre application dans la liste des instances EC2.

Vous pouvez ensuite, depuis la console AWS, suivre les étapes de déploiement en cliquant sur le service Elastic Beanstalk :

Une fois le déploiement effectué, vous aurez un bloc correspondant à votre application rappelant le nom que vous lui avez précisé :

En cliquant sur le détail, vous aurez des informations complémentaires :

Et enfin, cliquez sur le lien suivant :

Ce lien correspond à l'URL publique mise en place par Elastic Beanstalk lors du déploiement de votre conteneur. Vous aurez ainsi accès au site Internet déployé.

IX - Conclusion

L'objectif de cet article était d'introduire le cloud Amazon à travers un exemple concret, notamment via le déploiement d'une application ASP.NET Core. Il ne fait aucun doute que le système de déploiement que nous avons utilisé sera de plus en plus mis en avant à l'avenir. J'aurais pu entrer plus en détail sur certains points, comme le concept de rôles liés à une machine virtuelle, mais je ne l'ai volontairement pas fait, car il s'agissait essentiellement d'un premier contact avec AWS.

X - Remerciements

La publication de ce tutoriel a été possible grâce à l'aimable autorisation de la société Soat.

Nous tenons également à remercier Zoom61 pour la mise au gabarit et Malick SECK pour la relecture orthographique.