Loupe

Kubernetes - Conteneurs : quelle utilité pour un développeur (dotnetcore) ?

tl;dr : Utiles ? Oui. Absolument nécessaires ? Non. Utiles pour une application seule ? Rien d'extraordinaire... Utilisés par tout le monde avec l'exécution en production en tête ? Là on commence à parler sérieusement :)

À l'époque du tout puissant courant DevOps, il est maintenant quasi-impossible de ne pas avoir entendu parler de Kubernetes et Docker, peu importe le langage de développement que vous utilisez.

Même en tant que développeur dotnet travaillant principalement en environnement Windows, il est très difficile d'ignorer l'existence de ces 2 technologies, bien que provenant à l'origine de l'univers "Linux", tant nous sommes rappelés de leurs existence à chaque conférence Microsoft (la dernière conférence Microsoft Ignite 2019 ne faisant pas exception :))

Dans cet article, je voudrais partager une opinion très personnelle sur les bénéfices et les inconvénients d'utiliser Docker + Kubernetes pour développer nos applications dotnetcore.

DevOps + conteneurs: Une combinaison naturelle

tl;dr : D'un point de vue "purement" développeur, les conteneurs ne sont pas forcément très attrayants. Mais si vous pensez en tant que "Développeur DevOps", le besoin d'utiliser les conteneurs se fait ressentir naturellement.

Selon moi, l'un des plus gros problèmes avec Docker / Kubernetes est que ce sont des outils qui doivent être appropriés par nous, développeurs, pour obtenir les plus gros bénéfices en dehors de la phase de développement...

Cependant, avec la bonne sensibilisation, je pense que ce problème peut éventuellement disparaître:
Je trouve cette problématique très similaire à l'éternel combat pour l'utilisation des tests automatisés. Là pareil, on est sur un sujet que l'on pourrait considérer comme contraignant pour la phase de développement, apportant des bénéfices en dehors de celle-ci ! Cependant, de nos jours, avec la généralisation des méthodes Agiles, nous n'avons (je l'espère) plus besoin de convaincre qui que ce soit de l'utilité d'ajouter ces tests automatisés.

Maintenant avec le courant DevOps, on aimerait cette fois-ci nous responsabiliser avec un nouveau concept (pour nous :D) : exécuter des applications en production !
Du coup on peut reprendre le paradigme des dévelopeurs vs testeurs pour le transposer cette fois-ci en développeurs vs opérateurs. Du coup même formule : en séparant les responsabilités de ces 2 équipes, vous pouvez compter sur les équipes de développement pour relayer les tâches opérationnelles au rang de "Quand on aura le temps...", un peu comme à l'époque lorsque l'on souhaitait rajouter des tests automatisés :)
Par contre, si vous donnez la responsabilité d'exécuter des applications en production à une équipe de développement, bien plus d'attention sera portée sur la réflexion en amont et la prévention des risques sur ces tâches opérationnelles.

Du coup, comme le développeur est par nature "faignant" (dans le bon sens du terme bien entendu :D), on se retrouve avec tout un tas d'automatisations orientées code : Infrastructure as Code, Pipeline as Code, bientôt Monitoring as Code également ?, bref tout ce qui est nécessaire pour simplifier au maximum la mise en production de notre petit morceau de code ! Et dans cette quête de l'automatisation et de la fiabilisation des services déployés, 2 technologies se sont distinguées pour convenir parfaitement à nos cas d'usage: Les Conteneurs (Docker étant le type de conteneur le plus connu), et les Orchestrateurs de conteneurs (Kubernetes semblant être le grand vainqueur de la récente guerre des Orchestrateurs de conteneur)

Utilisation de conteneurs pendant le développement : rien d'exceptionnel ?

Commençons par un simple listing des avantages et inconvénients de l'utilisation des conteneurs durant la phase de développement :

Désavantages :

  • Besoin de s'appuyer sur des outils additionnels (Docker Desktop et/ou minikube), un peu lourds et parfois instables (notamment sur Windows...),
  • Besoin de maintenir des fichiers supplémentaires (Dockerfile, Helm charts) pour builder, tester et déployer,
  • Besoin d'apprendre de nouveaux usages, outils et méthodes (même si ce surcoût est très vite absorbé une fois les équipes habituées)

Avantages :

  • S'appuyer sur des conteneurs existants en quelques secondes (Exécuter un service SQL, SonarQube, ElasticSearch ou autre dans un conteneur sans avoir besoin de l'installer !),
  • Avoir à portée de main notre process de Build / exécution des tests auto, décrit dans le fichier Dockerfile (plus simple pour déboguer la CI !),
  • Exécuter plusieurs environnements avec différentes configurations simultanément sur son propre poste (pratique pour vérifier rapidement plusieurs environnements !)
  • Azure Dev Spaces pour tester et déboguer rapidement quelques conteneurs à l'intérieur d'un système entièrement en micro-services.

C'est principalement ce qui m'est venu à l'esprit... (Si vous voyez d'autres avantages / inconvénient, n'hésitez pas à les mentionner dans les commentaires !)

Le surcoût n'est peut-être pas si énorme à long terme (on est loin des 50% du temps d'un développeur nécessaires pour écrire des tests unitaires, annoncé par Microsoft dans son Pattern and practice), mais le gain n'est pas non plus si énorme si l'on ne regarde que la phase de développement.

Voyons voir maintenant les bénéfices apportés par ces petits efforts au fur et à mesure que l'on s'approche de la phase de production.

Après la phase de développement : Les choses sérieuses commencent

Même si l'utilisation des conteneurs n'apportent pas un gros bénéfice direct sur les équipes de développement, les effets indirects peuvent permettre, sur le long terme, d'avoir au final plus de temps pour se concentrer sur le développement. Mais quels sont ces principaux effets ?

Bien entendu, un des bénéfices les plus reconnus reste la réduction de l'effet ça marche sur mon poste grâce a l'isolation et l'indépendance apportée par les conteneurs et l'embarquement de tout ce qui est nécessaire à leur bonne exécution (dépendances, services, etc.) Quel soulagement de ne pas avoir à s'inquiéter des différentes versions du framework dotnet installées sur l'environnement ou l'on souhaite déployer :)

before devops / after devops geek comic

Si la Build du code source est également effectuée dans votre Dockerfile (ce que je vous recommande fortement de faire), mettre en place un pipeline d'intégration continue est tout ce qu'il y a de plus facile. Encore une fois, pas besoin de se soucier des versions des outils installés sur la machine de Build, étant donné que nous spécifions nous mêmes les versions nécessaires dans le Dockerfile.

Cerise sur le gâteau : on peut s'appuyer sur le cache des étapes de Build Docker pour rendre instantanées les étapes d'installation des dépendances et de restauration des packages, pour avoir un temps de Build correspondant uniquement au temps de Build et a l'exécution des tests autos.

Grâce à l'isolation des conteneurs ainsi qu'à leur faible empreinte mémoire, le tout accompagné de quelques charts helm, on obtient la formule pour être capable de déployer un nouvel environnements en quelques secondes ! Que diriez-vous d'avoir un nouvel environnement déployé automatiquement à chaque Pull Request pour pouvoir facilement tester les nouvelles fonctionnalités ou observer un nouveau design ? Et bien il est temps de regarder du côté des Review Apps, disponibles en public preview pour les environnements Azure Kubernetes Services et qui fera le sujet d'un prochain article de blog :)

Déploiement : pourquoi Kubernetes ?

Attention, pas de magie ici, les concepts liés au déploiement en production ont toujours besoin d'être bien compris. C'est "juste" qu'en utilisant Kubernetes, vous suivez une manière standard et commune de faire ces déploiements, et vous gagnez en bonus quelques comportements built-in et quelques outils pour vous faciliter la tâche.

En partant du principe que l'on a déjà un cluster Kubernetes à notre disposition (Azure Kubernetes Service par exemple ?), de nombreux scénarios sont déjà gérés pour nous :

  • Que faire en cas de crash d'un conteneur ? Laissez juste la fonctionnalité de Self-healing de Kubernetes redémarrer votre conteneur pour vous !
  • Besoin de rajouter un peu de Load Balancing vers votre application, distribuée sur plusieurs noeuds ? Configurez juste la valeur replicas de votre reploiement avec une valeur supérieure à 1 !
  • Envie de déployer sans downtime et avec possibilité d'effectuer un rollback facilement ? Assurez vous juste d'avoir plus d'une instance de votre application, et utilisez Helm pour déployer afin de bénéficier de la fonctionnalité de Rolling upgrades!
  • Et comment tenir quelques pics ponctuels de trafic ? 2 notions sont disponibles pour nous :
    • Horizontal pod autoscale qui va simplement ajouter plus d'instances de votre application pour gérer plus de requêtes,
    • et le Cluster autoscale qui permet d'ajouter plus de nœuds (et donc plus de VM) à votre Cluster, et qui est bien évidemment spécifique à votre service provider (Microsoft Azure dans mon cas)
  • etc,..

Ce sont juste quelques-uns des scénarios qui sont facilités par l'utilisation de Kubernetes et Helm et qui ont su séduire bon nombre de personnes.

Encore une fois pas de magie ici, faire tourner des applications en production nécessite toujours de comprendre quelques concepts, mais avec les conteneurs, nous avons à notre disposition plein d'outils pour gérer ces sujets comme des pro :)

Conclusion : Kubernetes c'est bien gentil, mais et dotnet dans tout ça ?

Au final, la plupart de cet article peut s'appliquer pour n'importe quel développeur utilisant n'importe quel langage (d'où la mise en paranthese de dotnetcore dans le titre haha). Donc finalement pourquoi en tant qu'utilisateur de techno Microsoft je devrais savoir tout ça ?

Et bien au contraire, cet article a tout à voir avec le Microsoft de nos jours. Le temps où Microsoft développait des technologies et vous forçait à n'utiliser que leurs outils est maintenant révolu. Ils essayent de fournir dorénavant des outils qui s'intègrent avec les outils standards open source, ce qui permet à leurs utilisateurs de s'appuyer sur les avancés du monde de l'Open Source également.

Qu'est ce que ça veut dire pour nous, développeur dotnet ?

Et bien cela signifie que notre environnement de développement est maintenant une combinaison d'outils open source et d'outils Microsoft, nous donnant la liberté d'explorer les nouveaux outils open source par nous-mêmes, tout en assurant nos arrières avec de nombreuses intégrations et guidances fournies par Microsoft.

Cependant, cela nous donne également plus de responsabilités lorsque nous essayons de nouvelles utilisations en avance de phase, mais j'ai bien peur que ce format reste le format le plus pertinent dans le monde actuel de la tech, qui évolue à l'heure actuelle à une vitesse folle.

 

Ouah, c'est tout pour cet article. J'ai fait de mon mieux pour résumer tout ce qui me venait à l'esprit sur le pourquoi nous voudrions adopter les conteneurs en tant qu'utilisateur de technos MS, mais entre nous, ce n'était pas une tâche aisée :)

Pour rassurer les développeurs qui ne souhaiteraient pas entendre parler de Linux ou d'Open Source, et se concentrer uniquement sur les technos Microsoft, la plupart des scénarios mentionnés dans cet article sont déjà ou seront prochainement disponibles via des services Azure. En contrepartie, il va falloir attendre quelques jours/mois(/années?) avant de les voir arriver sur la plateforme ^^

N'hésitez pas à exprimer votre désaccord, point de vue additionnel ou n'importe quel autre point dans les commentaires, ou en reply sur mon Twitter @vivienfabing, et que le code soit avec vous !

Photo de profil

Ces billets pourraient aussi vous intéresser

Vous nous direz ?!

Commentaires

comments powered by Disqus