Tutoriel : Premiers pas de développeur avec Docker, Azure et Visual Studio 2/3
Dans ce tutoriel, nous allons créer une petite application console avec Visual Studio, la déployer d’abord dans un conteneur Linux, puis dans un conteneur Windows, sur Azure.
Les concepts généraux de Docker ont été rappelés sur la page 1/3 de cet article.
Nous utiliserons 2 manières différentes de déployer l’application:
- d’abord vers un conteneur Linux (cette page): en créant les différents composants de manière “manuelle” pour bien comprendre comment fonctionne Docker
- ensuite vers un conteneur Windows (dans la page 3/3 de l’article): en se reposant entièrement sur l’assistant dans Visual Studio qui prendra en charge intégralement les opérations, y compris la création de la VM dans Azure.
Notez que les 2 procédures (manuelle ou auto) fonctionnent aussi bien sur Linux que sur Windows.
Pré-requis
De manière générale pour déployer une application dans un conteneur Docker, il faut:
Il faut | On utilisera |
Une machine serveur avec un OS proposant une technologie de conteneurs, compatible avec Docker | Une VM Linux avec extension Docker ou une VM Windows Server 2016 dans Azure |
Une machine cliente sur laquelle un client Docker est installé | - Notre PC de dev avec Visual Studio + l’extension Docker pour Visual Studio - le client Docker en ligne de commande, pratique pour les tests (package Chocolatey) |
Des certificats OpenSSL qui permettront au client Docker de se connecter au host Docker | - openSSL (pour la partie manuelle du tuto) et/ou - l’extension Docker pour Visual Studio qui les créera pour nous si on part de 0 |
Le code de votre application ainsi qu’un fichier DockerFile | Visual Sudio avec l’extension Docker pour VS qui créera un dockerfile adapté au type de conteneur (c’est à dire l’OS sur lequel il tourne) |
Nous verrons tout cela étape par étape : à ce stade du tutoriel il vous faut simplement:
- un compte Azure
- Visual Studio 2015 RTM (ce tuto a été créé sur la version Enterprise mais cela devrait fonctionner aussi sur la version Community)
- SDK Azure disponible via le Web Platform Installer
Je suis partie d’un Visual Studio vierge en terme d’extensions, ce qui me permettra de vous montrer au fur et à mesure les différents composants à installer pour faire fonctionner ce petit monde-là.
Les étapes
Pour publier une application dans un conteneur Docker sur Azure, vous pouvez très bien n’utiliser qu’un seul outil : Visual Studio. En effet, l’extension Docker pour Visual Studio vous fournit un assistant qui va s’occuper de provisionner la VM, créer et uploader les certificats et y déployer le code sous la forme d’une image Docker.
Soit. Vous aurez votre application qui tourne dans Docker.
Mais vous n’aurez pas compris comment ça marche en dehors de Visual Studio...et ne saurez pas prendre la main dessus avec les outils Docker.
Donc dans ce tutoriel, on va se retrousser les manches et réaliser les différentes étapes nous-même, jusqu’à arriver à la publication du code où nous passerons effectivement la main à l’extension Docker pour le télécharger et démarrer le conteneur.
Nous allons donc:
- Créer une VM Linux avec l’extension Docker dans Azure
- Créer des certificats SSL à ajouter dans la configuration de l’extension Docker
- Ajouter des point de terminaison/endpoints sur la VM pour pouvoir se connecter au docker host depuis le client Docker
- Installer l’extension Docker pour Visual Studio
- Créer une application console ASP.Net 5
- Déployer l’application dans un conteneur linux sur notre VM Linux
- Déployer la même application dans un conteneur Windows d’une nouvelle VM Windows Server 2016 créée cette fois par Visual Studio
- Constater que cela ne fonctionne pas
- Modifier le dockerfile
- Re-déployer l’application dans un conteneur Windows
- Constater que cela fonctionne
1. Création de la VM Linux dans Azure
Depuis le portail, sur la marketplace, choisissez la VM Docker on Ubuntu Server:
C’est en fait une VM Ubuntu classique, avec l’extension docker pré-installée : elle nous permet d’avoir un docker engine sur notre VM.
Cliquez sur “Créer”, puis renseignez le nom de la machine hôte (de préférence, utilisez le rappel “linux” dans le nom pour ne pas confondre les VMs Windows et Linux lors du déploiement à partir de Visual Studio), l’utilisateur et le mot de passe.
Ajout des points de terminaison
Ajoutez un point de terminaison 2376 sur votre VM pour pouvoir vous connecter au Docker host de la manière suivante
Faites de même avec le port 80 pour obtenir
Ouvrir les ports c’est nécessaire mais cela ne suffit pas pour se connecter au docker host.
En effet, Docker est configuré pour fonctionner avec une clé de sécurité SSL. Bon ça va se compliquer un peu car il va falloir générer les certificats SSL. Cette étape est prise en charge par Visual Studio si vous créez la VM depuis l’assistant : c’est ce que l’on verra dans la 2ème partie du tuto où nous laisserons VS prendre tout en charge pour déployer l’application dans un conteneur Windows.
Création des certificats SSL
Le démon Docker sur le serveur est configuré pour utiliser la sécurité TLS. Le client Docker recherche la clé du client (key.pem) et le certificat (cert.pem) par défaut dans le dossier <%userprofile%>\.docker. Si ces éléments ne sont pas présents, il convient de les générer à l'aide d'OpenSSL.
C’est ce que nous allons faire à présent.
Installez OpenSSL depuis un des sites recommandés ici https://wiki.openssl.org/index.php/Binaries
Générez vos certificats ainsi:
echo 01 > ca.srl
openssl genrsa -des3 -out ca-key.pem
openssl req -new -x509 -days 3650 -key ca-key.pem -out ca.pem
openssl genrsa -des3 -out server-key.pem
openssl req -new -key server-key.pem -out server.csr
openssl x509 -req -days 365 -in server.csr -CA ca.pem -CAkey ca-key.pem -out server-cert.pem
echo "Creating client keys..."
openssl genrsa -des3 -out client-key.pem
openssl req -new -key client-key.pem -out client.csr
echo extendedKeyUsage = clientAuth > extfile.cnf
openssl x509 -req -days 365 -in client.csr -CA ca.pem -CAkey ca-key.pem -out client-cert.pem -extfile extfile.cnf
echo "Stripping passwords from keys..."
openssl rsa -in server-key.pem -out server-key.pem
openssl rsa -in client-key.pem -out key.pem
ou selon la doc https://docs.docker.com/engine/articles/https/ et copiez-les dans le répertoire <user>/.docker.
(Oui c’est pénible : si vous préférez sauter cette étape, commencez par la partie 3/3 du tuto où VS génère automatiquement les certificats dans le répertoire adéquat lorsqu’il crée la VM )
Si l’on était parti d’une VM Ubuntu simple, à laquelle on aurait ajouté l’extension docker, nous aurions pu spécifier les certificats dans la configuration de l’extension en précisant les 3 fichiers de certificats nécessaires. <user>/.docker. Les fichiers à utiliser sont ca.pem, server-cert.pem, server-key.pem.
Mais avec la VM incluant une extension déjà configurée, les fichiers sont pris dans le répertoire <user>/.docker.
Si vous voulez modifier les certificats a posteriori, voici une méthode pas très jolie, mais simple et pratique : sélectionnez votre VM et ajoutez une nouvelle fois l’extension Docker en précisant les nouveaux certificats. Validez.
L’installation réussit mais on trouve une erreur dans les détails de l’extension.
Redémarrez la VM : cette fois ça fonctionne.
On a terminé de configurer notre VM avec Docker.
Cliquez sur “Créer” Votre machine est en cours de provisionnement |
Vous pouvez y accéder facilement grâce à la zone de recherche du bandeau et l’épingler sur l’écran d’accueil pour y accéder facilement.
Passons maintenant sur la machine client : celle sur laquelle vous avez installé Visual Studio.
2. Installation de l’extension Docker pour Visual Studio
Installez tout d’abord Microsoft ASP.NET and Web Tools 2015 (Beta8) – Visual Studio 2015 ; choisissez les composants à installer selon les instructions ci-dessous:
Install Instructions
1.
Close all instances of Visual Studio.
2.
Install .NET Version Manager (Beta8) using DotNetVersionManager-x64.msi. For 32 bit machines use DotNetVersionManager-x86.msi.
3.
Update Visual Studio 2015 (Enterprise, Professional or Community) with ASP.NET and Web Tools 2015 (Beta8) by installing WebToolsExtensionsVS14.msi. If you are using Visual Studio 2015 Express for Web, then install WebToolsExtensionsVWD14.msi instead.
Dans Visual Studio, via le menu “Tools>Extensions and Updates”, ajoutez l’extension Visual Studio Tools for Docker (ici en October Preview):
3. Création d’une application Console
Puis créez un nouveau projet de type Web/Console Application.
Ajoutez simplement les 2 lignes de code suivantes dans le Main du fichier Program.cs:
namespace DockerConsoleApp
{
public class Program
{
public void Main(string[] args)
{
Console.WriteLine("I'm running in a container :D");
Console.ReadLine();
}
}
}
Si vous l’exécutez localement sur la machine, vous obtiendrez
4. Déployer l’application dans un conteneur sur notre VM Linux
Faites un click droit sur le projet dans l’explorateur de fichiers et choisissez “Publish”:
Voici l’assistant de publication qui vous propose de publier votre application dans un conteneur docker.
Sélectionnez la cible Docker Containers
Choisissez la souscription Azure et le nom de la VM Linux avec Docker que vous venez de créer puis validez.
Remarquez l’url de votre agent Docker qui utilise le port 2376.
Cliquez sur le bouton “Validate Connection”: normalement, ça devrait bien se passer.
Je vous encourage à installer le client Docker de base via Chocolatey : cela vous permettra de communiquer avec votre Docker host sans Visual Studio et de vous familiariser avec les commandes Docker.
Si vous n’avez pas encore Chocolatey sur votre machine, vous pouvez suivre cette petite vidéo qui vous expliquera comment faire pour installer Chocolatey ainsi que le client Docker.
Vous pouvez tester la connexion à partir du client docker en copiant/collant la commande Preview dans les options avancées de la boite de dialogue.
Je vais utiliser la commande “info”, et vous pouvez utiliser les commandes docker depuis le Command Prompt.
Pour l’instant, je n’ai pas d’image docker et a forciori, pas de conteneur en cours d’exécution.
A présent, cliquez sur le bouton Publish
Plusieurs choses se passent à ce moment (vous pouvez voir le détail dans la fenêtre Output de VS, notamment:
- la création du fichier Dockerfile dans le projet Visual Studio
- la création de l’image correspondant à votre application, en partant du packaging décrit dans le dockerfile
- le transfert de votre app dans le docker host, via le docker engine
- la récupération des “couches du millefeuille” applicatif décrites dans le dockerfile et le point d’entrée du code utilisé pour l’exécution du conteneur
- le démarrage du conteneur
Normalement vous devriez vous retrouver avec ce genre de résultat, à la fin de l’output
VERBOSE: ---> Running in 7bf52b2450c1
VERBOSE: ---> 191d76de7c39
VERBOSE: Removing intermediate container 7bf52b2450c1
VERBOSE: Successfully built 191d76de7c39
VERBOSE(0,0): Warning : You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.
The Docker image "dockerconsoleapp" was created successfully.
VERBOSE: Starting Docker container: dockerconsoleapp
Executing command [docker --tlsverify -H tcp://stephetutodockerlinux.cloudapp.net:2376 run -t -d dockerconsoleapp]
VERBOSE: cc80b00c123b7978695931afcaefe05165876f07a95edb54662513ec9d8a3902
Docker container started with ID: cc80b00c123b7978695931afcaefe05165876f07a95edb54662513ec9d8a3902
To see standard output from your application, open a command line window and execute the following command:
docker --tlsverify -H tcp://stephetutodockerlinux.cloudapp.net:2376 logs --follow cc80b00c123b7978695931afcaefe05165876f07a95edb54662513ec9d8a3902
Publish completed successfully.
========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========
========== Publish: 1 succeeded, 0 failed, 0 skipped ==========
Le fichier Dockerfile
Le dockerfile est créé par Visual Studio en fonction de l’OS – Linux ou Windows - sur lequel est basé le conteneur qui va faire tourner l’app. Il permet à docker de savoir comment reconstituer le contexte : c’est à dire les couches d’images dont votre application a besoin pour s’exécuter. Vous allez comprendre en jetant un œil au dockerfile:
FROM microsoft/aspnet:1.0.0-beta8
ADD . /app
WORKDIR /app/approot
ENTRYPOINT ["./DockerConsoleApp"]
Sur une machine linux, on va partir de l’image Microsoft/aspnet avec la version 1.0.0-beta8, récupérée dans la registry officielle de Docker.
La registry regroupe les images qui y sont poussées par les éditeurs et qui sont ensuite utilisées et notées par les utilisateurs.
Cette image aspnet publiée par Microsoft est elle-même basée sur Mono, l’implémentation x-plat de .Net.
Si vous jetez un œil au dockerfile cette image vous trouverez les couches qui permettent cette fois de retrouver le bon contexte de packaging pour ASP.NET pour linux.
On continue comme ça jusqu’à l’OS (et sa version) : c’est l’illustration des couches du fameux millefeuille, qui permet de retrouver toujours un environnement de déploiement et d’exécution identique.
Dans notre dockerfile, il est précisé l’ajout du package de notre application, le répertoire courant ainsi que le point d’entrée pour l’exécution de l’application.
Le conteneur
Pour vérifier si votre conteneur a bien démarré, on va réexécuter la commande docker info: on y trouve bien 1 conteneur – c’est bon signe
Pour lister les images, on utilise la commande “images”
On retrouve bien l’image Microsoft/aspnet qui a été récupéree par docker dans la registry officielle Docker (celle-ci est fournie par Microsof) utilisée en sous-couche de notre image applicative dockerconsoleapp.
On trouve aussi l’image de notre application dockerconsoleapp qui est la dernière couche du millefeuille.
Pour lister les conteneurs, on utilise la commande “ps”"
Pour voir la sortie standard de notre application, il suffit de copier/coller la commande suggérée par VS dans l’Output:
docker --tlsverify -H tcp://stephetutodockerlinux.cloudapp.net:2376 logs --follow cc80b00c123b7978695931afcaefe05165876f07a95edb54662513ec9d8a3902
Youpi !!
Dans la dernière partie de l’article, nous déploierons la même application dans un conteneur Windows, créé directement depuis Visual Studio et non plus depuis le portail Azure comme nous l’avons fait ici. Si l’on souhaite utiliser la même solution Visual Studio pour déployer l’application sur 2 types de conteneurs différents, nous verrons qu’il y a quelques petites subtilités, en particulier le dockerfile puisque l’application devra tourner sur 2 OS différents.
Références
https://docs.asp.net/en/latest/publishing/docker.html
https://blog.siliconvalve.com/2015/01/07/get-started-with-docker-on-azure/
https://github.com/chanezon/azure-linux
https://azure.microsoft.com/fr-fr/documentation/articles/virtual-machines-docker-with-portal/
https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-docker-ubuntu-quickstart/
Comments
Anonymous
December 28, 2015
j'ai essayé ce tuto, mais après plusieurs tentatives sur la génération des certificats, rien n'y fait. Impossible d'accéder à la VM Docker , impossible de valider la connexionAnonymous
January 03, 2016
Bonjour Archibald, Tu peux essayer la méthode alternative décrite ci-dessus en réaffectant l'extension Docker sur la VM, depuis le portail azure pour renvoyer les certificats. Suis bien les étapes car il faudra redémarrer ta VM. Vérifie également que tu as bien le dossier .docker au bon endroit et contenant les bons fichiers.Anonymous
January 03, 2016
Bonjour et meilleurs vœux, J'ai essayé la méthode alternative et maintenant j'ai "remote error: bad certificate" Avant j'avais "~la VM a explicitement refusé la connexion" N'y a-t-il pas une erreur dans les commandes de génération certficats ? ou Je vois également dans l'article suivant: azure.microsoft.com/.../virtual-machines-docker-with-portal Qu'il serait nécessaire de convertir en base64 les fichiers? Mes premiers pas sous Azur et Docker sont chaotiques.Anonymous
January 04, 2016
Au final j'ai demandé à VS de gérer la création de la VM et des certificats. Au moins suis arrivé au bout.