Bonnes pratiques pour la conteneurisation des applications .NET
Marcelo Oliveira
31 août 2022
0 minutes de lectureLa conteneurisation avec Docker est devenue une tendance majeure dans le développement d’applications web, adoptée par de nombreux développeurs .NET. La conteneurisation des applications .NET présente de nombreux avantages pour les développeurs et les ingénieurs DevOps, même lorsqu’ils travaillent avec les anciennes versions 4.x de .NET Framework. Toutefois, si nous ne savons pas utiliser correctement les conteneurs, nous en tirerons peu d’avantages.
Dans cet article, nous allons présenter quelques bonnes pratiques pour conteneuriser les applications .NET, y compris celles utilisant le framework version 4.x. Nous parlerons également de l’utilisation d’images légères et de l’analyse des images afin de réduire les risques de sécurité et de supprimer les composants inutiles de nos conteneurs.
Prérequis
Avant de commencer, vous aurez besoin de :
Télécharger et installer Visual Studio 2022.
Disposer d’un client Docker local pour exécuter des conteneurs sur votre machine. Vous pouvez utiliser Docker Desktop, qui nécessite Windows 10 ou une version ultérieure. Veillez à choisir l’installation Windows.
Télécharger et installer Snyk Command Line Interface (CLI).
Créer un compte Snyk gratuit.
Pensez à conteneuriser vos applications .NET (même .NET Framework 4.x)
Depuis .NET Core 1.0, les applications web sont multiplateformes, portables et open source. Les développeurs peuvent ainsi les porter vers Docker et tirer pleinement parti de la conteneurisation.
Cependant, si les nouvelles versions de .NET exécutées sous Linux retiennent toute l’attention, les conteneurs Windows prennent en charge les anciennes versions de .NET réservées à Windows, dont dépendent d’innombrables applications d’entreprise. Et toutes les organisations qui assurent la maintenance d’applications web .NET Framework ne sont pas prêtes à les porter vers des versions plus récentes. C’est pourquoi il est judicieux de conteneuriser nos applications .NET Framework 4.x.
Les étapes suivantes montrent comment créer et exécuter une application ASP.NET Web Forms conteneurisée dans Visual Studio 2022.
Commencez par lancer Docker Desktop sur votre machine de développement :

Dans la fenêtre Get started de Visual Studio, sélectionnez Create a new project.

Saisissez « Web Forms » dans la zone de texte Search for templates, puis sélectionnez ASP.NET Web Application (.NET Framework).

Saisissez le nom de votre nouvelle application (par exemple, WebFormsApp), indiquez son emplacement sur le disque, sélectionnez .NET Framework 4.8, puis cliquez sur Create.

Sélectionnez ensuite le type Web Forms.

Vérifiez que les options Web Forms et Docker support sont cochées, puis cliquez sur Create.

Attendez que Visual Studio crée le projet. Voici la structure du projet telle qu’elle apparaît dans Visual Studio :

Ouvrez maintenant Docker Desktop. Vous remarquerez que le conteneur WebFormsApp s’exécute sur le port 61469 :

Ouvrez l’onglet Images pour voir l’image WebFormsApp, à partir de laquelle le conteneur WebFormsApp s’exécute.

Enfin, appuyez sur Ctrl+F5 pour créer votre image Docker et l’exécuter localement. Une fois l’image du conteneur créée et en cours d’exécution dans un conteneur Docker, Visual Studio ouvre l’application web dans votre navigateur par défaut.

Revenez maintenant à Visual Studio et cliquez sur le fichier Dockerfile :

Le fichier Dockerfile s’ouvre. Il configure votre projet pour qu’il s’exécute dans un conteneur.

L’instruction FROM initialise une nouvelle étape de build et définit l’image de base pour les instructions suivantes. Ici, l’image est aspnet:4.8-windowsservercore-ltsc2019, que Docker récupère dans le dépôt d’images de Microsoft.
Bien sûr, il est plus probable que votre projet Web Forms n’ait pas été créé au départ avec la prise en charge de Docker. Pour simuler cette situation, créez un nouveau projet ASP.NET Web Forms, mais cette fois sans prise en charge de Docker :

Ajoutons maintenant un Dockerfile au nouveau projet. Faites un clic droit sur le nom du projet, choisissez le menu Add, puis le sous-menu Docker Support :

Visual Studio crée alors automatiquement le Dockerfile du projet.

Notez que Visual Studio a déjà sélectionné l’image et le chemin du code source à partir desquels le conteneur sera généré.

Votre projet bénéficie dès lors de la prise en charge et des avantages inhérents à la conteneurisation avec Docker : portabilité, agilité, livraison plus rapide, sécurité renforcée et gestion simplifiée.
Réduisez autant que possible la taille des images de conteneur
Les conteneurs Linux et Windows proposent des images de base légères, qui ne contiennent que les applications et les services nécessaires au fonctionnement de votre application. Une image légère avec un minimum de dépendances réduit le nombre de vulnérabilités susceptibles d’être introduites par ces dépendances, et donc la surface d’attaque.
Voyons quelques images de base que les développeurs .NET peuvent envisager pour créer des conteneurs légers. Tout d’abord, si vous utilisez encore ASP.NET Framework 4.x, qui n’est pas pris en charge sous Linux, les conteneurs Windows sont votre seule option. Microsoft recommande les images de base légères Windows Server Core et Nano Server.
Windows Server Core est un système d’exploitation minimal piloté par ligne de commande, destiné à assurer les rôles Windows Server et à exécuter des applications qui n’ont pas besoin de l’interface graphique Windows standard. Nano Server est un système d’exploitation optimisé pour les clouds privés et les centres de données. Nano Server ne permet pas de se connecter localement, est plus léger et redémarre beaucoup plus vite que Server Core.
Pour .NET Core et .NET 5+, les images SDK doivent être utilisées uniquement pour le build, tandis que les images d’exécution sont destinées aux déploiements en production dans le cadre d’un build à plusieurs étapes. Parmi les images de base légères adaptées, citons Debian bullseye-slim-amd64 et Alpine Linux.
Nous pouvons alléger encore les images de base en utilisant des images contenant les dépendances d’exécution .NET et en créant notre application .NET en mode autonome : nous ne récupérons ainsi que les dépendances dont notre application a besoin, sans rien de plus.
Mettons en pratique la création d’une application web .NET 6 avec des images légères. Ouvrez Visual Studio 2022, cliquez sur Create New Project, puis sélectionnez le type ASP.NET Core Web App.

Donnez un nom au projet, par exemple WebApp.

Cliquez sur Next et sélectionnez les options suivantes :
Framework .NET 6.0
Type d’authentification : Aucun
Configurer HTTPS : coché
Activer Docker : coché
Système d’exploitation Docker : Linux

Cliquez sur le bouton Create et observez le nouveau projet dans Visual Studio.

Appuyez maintenant sur F5 pour exécuter l’application web hébergée dans votre conteneur Docker local.

Exécutez maintenant la commande docker images pour obtenir la liste des images Docker de votre système :
Cette commande renvoie un résultat similaire à celui-ci :
Notez que l’application s’exécute dans un conteneur Linux et que l’image webapp ci-dessus fait 208 Mo.
Réduisons maintenant la taille de l’image du conteneur de notre application web.
Arrêtez l’application dans Visual Studio et ouvrez le fichier Dockerfile. Vous verrez le bloc suivant, qui indique à Docker de récupérer les images dotnet/aspnet:6.0 et dotnet/sdk:6.0 dans Microsoft Container Registry (mcr), puis de les utiliser comme images de base pour le conteneur de votre application :
Appuyez ensuite sur F5 pour relancer l’application. Une fois l’application web démarrée, exécutez la commande docker images pour obtenir la liste des images Docker de votre système :
La liste de vos images ressemblera à ceci :
Notez que l’image webapp a été reconstruite et qu’elle fait désormais 100 Mo, soit 108 Mo de moins que l’image d’origine.
Analysez les images pour détecter les vulnérabilités
Mettre régulièrement à jour la base de code constitue en soi une bonne pratique. Parmi les avantages les plus évidents : l’accès à de nouvelles fonctionnalités, aux corrections de bugs, à une meilleure interface utilisateur et à des performances améliorées. Mais les mises à jour de sécurité sont tout aussi importantes.
Le système d’exploitation ou les bibliothèques de l’image de base peuvent présenter des vulnérabilités non corrigées. Les scripts, le code et les applications ajoutés à cette image peuvent également contenir des vulnérabilités que nous ne voulons pas déployer par inadvertance en production.
L’analyse des conteneurs à la recherche de vulnérabilités est indispensable pour évaluer les risques de sécurité potentiels et prendre les mesures qui s’imposent. Pour cet exemple, choisissons une ancienne image .NET : mcr.microsoft.com/dotnet/core/aspnet:2.2.
Ouvrons le projet dans Visual Studio et ajoutons un Dockerfile au nouveau projet. Faites un clic droit sur le nom du projet, choisissez le menu Add, puis cliquez sur le sous-menu Docker Support.
Ouvrez maintenant le fichier Dockerfile et remplacez son contenu par le code suivant :
Voyons maintenant comment analyser une image pour découvrir les vulnérabilités de notre conteneur. Commencez par exécuter la commande CLI docker images pour répertorier vos images locales actuelles :
Exécutez ensuite la commande snyk auth pour vous authentifier auprès de Snyk CLI :
Une fois votre compte authentifié, vous pouvez utiliser Snyk CLI. Exécutons la commande snyk container test <repository>:<tag> pour analyser l’image créée localement et disponible dans notre daemon Docker local :

La commande snyk container test génère une liste des composants installés dans l’image, l’envoie au service Snyk, puis renvoie la liste des vulnérabilités présentes dans notre image.
Au final, l’analyse de l’image a détecté 193 vulnérabilités :

Pour surveiller l’image, exécutez la commande snyk container monitor <repository>:<tag> :

La commande snyk container monitor génère une liste des composants installés dans l’image, l’envoie au service Snyk et renvoie un lien vers le service Snyk à l’adresse http://app.snyk.io/org/{YOUR-ACCOUNT}/, où vous pouvez consulter les résultats :

Nos 3 meilleurs conseils pour la conteneurisation
Nous avons vu les nombreux avantages que la conteneurisation des applications .NET présente pour les développeurs et les ingénieurs DevOps. Toutefois, les conteneurs ne sont pas une solution miracle à tous les problèmes. Nous devons toujours appliquer certaines bonnes pratiques pour démystifier les conteneurs et savoir comment en tirer le meilleur parti.
Malgré l’idée reçue persistante selon laquelle les conteneurs sont réservés aux applications .NET Core, nous avons vu qu’ils peuvent également profiter aux applications .NET Framework 4.x.
Pour la taille des images de conteneur, plus elles sont petites, mieux c’est. Nous avons heureusement appris que certaines images de base sont suffisamment légères pour ne contenir que le nécessaire à l’exécution de notre application, tout en réduisant la surface d’attaque du conteneur.
Enfin, nous avons vu comment atténuer les risques de sécurité en analysant les images de conteneur et en les maintenant à jour. Les commandes Snyk container test et Snyk container monitor sont des outils précieux pour analyser nos conteneurs .NET et les surveiller en continu afin d’y détecter les vulnérabilités. Utilisée correctement, la conteneurisation peut apporter une couche supplémentaire de sécurité et de flexibilité à nos applications, quel que soit leur âge.
La sécurité des conteneurs, pensée pour les développeurs
Snyk détecte et corrige automatiquement les vulnérabilités dans les images de conteneurs et les workloads Kubernetes.
