Onyx Solution – Une Mini-Formation sur l’Architecture Logiciel

Onyx Solution https://github.com/YannVasseur35/Onyx Onyx Solution Une solution Microsoft .net 7.0 / C# permettant l’apprentissage de concepts de software design, d’architecture, de clean code, de tests… Permet de partir sur de bonnes bases pour un petit/moyen projet, basé sur quelques années d’expériences dans le software design. Onyx est une pierre précieuse de couleur noire. J’ai donnée ce nom à ce projet d’apprentissage car il est court, facilement identifiable, abstrait, et j’aime bien donner des « noms de code » à un projet. On va prendre comme exemple une application de météo (qui est d’ailleurs l’exemple par défaut d’une application .net web) on aura donc Une API qui expose des données une base de données SQLite avec EntityFramwork (code first) Une clean architecture avec de nombreux tests + code coverage CI/CD avec une pipeline AzureDevops Introduction On a tous commencé par écrire un seul projet c# et tout mettre dedans, sans vraiment rien structurer. Alors oui, ça marche et honnêtement vu les ambitions de cette app méteo c’est ce que l’on devrait faire. Et puis comme tout bon projet, il évolue, en quelques années tout un tas de nouvelles fonctionnalités se sont ajoutés, plusieurs devs sont passés dessus, avec du code plus ou moins clair. De plus avec le temps, l’infrastructure a changé, on a fait évoluer la base de données, certain services sont directement sur le cloud et on a du faire face à de la montée en charge. On a du « scaler » l’application, recoder des parties, ajouter du cache etc…Et bien entendu rien n’est testé automatiquement. Bref la vie d’une application dans pas mal de boite en France et ailleurs dans le monde. Je développe avec .net depuis plus de 20 ans. Et j’ai vu un certain nombre d’application (un bon paquet à vrai dire) finir dans ce que l’on appelle un « monolith legacy », très très dure à maintenir. Ces applications existent encore à l’heure ou j’écris ces lignes. Parfois on en est au deuxième projet de « refonte ». Un cas typique est celui du projet ou l’on retrouve toute la logique métier dans les procédures SQL. Car c’est ce qui faisait vraiment gagner en pref à l’époque (et encore aujourd’hui). Mais seule la personne en charge de ces procédures stockées, souvent indéchiffrable et intestable, est en mesure de travailler dessus. Autre cas bancale, on a de la logique métier dans les pages web. Du coup on se retrouve à gérer à plusieurs endroits, du code qui fait plus ou moins la meme chose, au risque qu’un jour il ne fasse plus la même chose ! Heureusement aujourd’hui on a énormement plus de techniques, d’outils et de services qui permettent d’appréhender les projets autrement. Les entreprises comprennent les enjeux et les risques de garder trop longtemps du code legacy en production et s’engagent dans de gigantesque chantier de « renovation » voir même de ré-écriture complète. J’ai moi aussi contribuer à ces erreurs et je contribue aussi à leurs résolutions. Ce projet tente modestement de répondre à certaines problématiques couramment vues en entreprise. Je ne prétends pas tout résoudre mais apporter quelques réponses à des questions que moi même je me suis posé. Et à vrai dire, le meilleurs moyen d’y répondre pour moi est de tenter de le faire comprendre à quelqu’un d’autre. J’ai donc entrepris ce projet Onyx. Progression Vous avez deux façons de voir les choses : la rapide. Restez sur la branche master, la plus à jour et dernière en date. Vous avez tout le code source et tous les tests. Regardez le code et inspirez-en vous, prennez ce qui vous intéresse. l’apprentissage. Ce sera plus lent, mais j’explique tous les concepts pas à pas. On démarre gentillement et on progresse par étape (step). C’est une sorte de TP (travaux pratique) qu’on faisait à l’école. Pour suivre ce TP il faudra « naviguer » avec Git de branche en branche. C’est simple, toutes les branches s’appellent ‘step’ suvit d’un numéro. Chaque step aura sa propre doc (ex: step2.md). Suffit de s’y référer pour comprendre ce qu’y a été fait à chaque étape. Sommaire Step1 : Structure de solution Step2 : Premier endpoint Api Step3 : Test endpoint Api Rest Step4 : Application Service et Tests Step5 : DataService et Tests Step6 : Mapping et Tests Step7 : ORM (Entity Framework) et Tests Step8 : Entity Framework Step9 : Finalisation de la chaine de données Step10 : Code Coverage Step11 : CRUD : Implémentation et Tests Step12 : Tests d’intégration Step13 : CI/CD AzureDevops Pipeline Step14 : Pipeline avec Code Coverage Git Repo : https://dev.azure.com/ReactorLab/_git/Onyx Vous devrez connaitre quelques commandes git de base très simple pour « naviguer » dans les branches de ce repo. Pour changer de branche : git checkout step1 Si vous avez fait des modifications et que vous souhaitez changer de branche, git va vous obliger à faire un commit ou à vous débarraser de ces changements. Comme vous ne contribuez pas au projet, débarrassez vous de vos changements avec la commande stash, puis faites votre checkout git stash git checkout step2 Documentations Annexes Vous trouverez des informations complémentaires sur différents concept d’architecture ici (en anglais): Main Architecture Hexagonal Architecture DDD CQRS AND ES SOLID Tout est dans le répertoire docs.

Azure Devops Pipeline (CI/CD) – Environnement

Problème du dernier post Je me suis bien pris la tête sur le dernier billet au sujet d’un nouveau problème qui est apparu lorsque j’ai voulu diviser mon site web en 2, une partie staging et une partie prod. Ca pourrait tout aussi bien être "preprod", "recette" etc… Avant j’avais qu’un seul site web: blazordemo.reactor.fr. Celui ci a sa config Nginx et son service systemd qui fait tourner Kernel via un proxy sur le port 7777. (voir article ) J’en ai créé un nouveau "staging.blazordemo.reactor.fr".  L’idée est de faire comme les pros, un site web de "staging" et un de "prod".  dev : locale, tambouille de developeur, avec une base de données crado, des machins bricolés, des trucs à jours ou pas… staging:  distante, même environnement que la prod (meme serveur de base de données, même OS, même TOUT, sauf les données qui sont normalement copiés et anonymisés dans le meilleurs des mondes) prod: distante, le site qu’on update le vendredi soir 🙂 Donc j’ai crée "staging.blazordemo.reactor.fr". Sauf que j’ai pas modifié mon service qui fait tourner Kestrel via proxy sur port 7777.  Et j’ai mis un temps fou à m’en apercevoir. (j’ai été jusqu’a faire un gros delete de mon repertoire www. Nginx continuait à me servir un beau site web… même après un reboot. car le service était le meme…) Donc il me faut 2 services… Un de staging, l’autre de prod. Le tout sur un port proxy différent bien évidement.  Bien entendu, ce problème n’existe pas si le staging et la prod ne sont pas sur le meme serveur, ce qui est TRES recommandé. Cependant, je trouve l’exercice intéressant car il pousse dans les retranchements et force à de bonnes pratiques. Mon ancienne technique Dans le projet Blazor Server, dans Program.cs j’ajoutais ceci  Une ligne de compilation conditionnelle qui me changait le port si on était en release (ce que je considèrais comme mon unique prod).  Je pourrais ajouter une condition STAGING avec un port 7776 et m’en servir pour la version staging. A mon sens une directive de compilation n’a rien a voir avec les environnements, je veux dire c’est liés, mais c’est pas son but de définir du paramétrage de port…  Je pense qu’on peut faire mieux, avec les fichiers de conf appsettings.js. Créeons deux autres fichiers de config, un pour la prod et l’autre pour le staging. Normalement vous avez déjà par défaut un fichier appsettings.Development.json launchSettings.json Si vous travaillez avec Visual Studio ou VS Code vous devez savoir que vous avez des options de lancement de votre app qui sont configurable dans le fichier Properties/launchSettings.json Encore un fichier de config qui sème le doute… { « iisSettings »: { « windowsAuthentication »: false, « anonymousAuthentication »: true, « iisExpress »: { « applicationUrl »: « http://localhost:54778 », « sslPort »: 44382 } }, « profiles »: { « BlazorDemo.Server »: { « commandName »: « Project », « dotnetRunMessages »: true, « launchBrowser »: true, « inspectUri »: « {wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri} », « applicationUrl »: « https://localhost:7249;http://localhost:5249 », « environmentVariables »: { « ASPNETCORE_ENVIRONMENT »: « Development » } }, « IIS Express »: { « commandName »: « IISExpress », « launchBrowser »: true, « inspectUri »: « {wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri} », « environmentVariables »: { « ASPNETCORE_ENVIRONMENT »: « Development » } } } } Comme on peut le voir dans la section "profiles", je peux lancer mon app soit : Via IIS Express  Via la commande dotnet run La première est historique, je pense qu’on en parlera plus dans qq temps. Avant .net core on était obliger de lancer un server utilisant le .net Framework sous IIS qui est le serveur de Windows. La version Express est la version de dévelopement. Pour moi c’est voué à mourrir, mais certains ont des habitudes et Microsoft les forces pas à les changers.  Depuis .net Core (et donc .net 5 et 6), on peut executer nos app sur n’importe quel OS et serveur web comme apache ou nginx sous linux. On a un serveur web intermédiaire appelé Kestrel qui fait le job. D’ailleurs c’est lui que l’on utilise en dévelopement.  En executant une commande dotnet run sur notre projet serveur, on lance un Kestrel. C’est lui que l’on veut paramétrer pour avoir une config dev, staging, prod.  C’est possible d’éditer en développement ce fichier pour changer de port. Mais c’est uniquement un fichier de conf pour une execution en dev local. C’est pas un fichier de configuration plateforme de prod.  Je place ça là car c’est un fichier qui peut vous semer le doute lors de vos devops et test local. AppSettings.{ENV}.json On va modifier le fichier appSettings.Developement.json et lui rajouter ceci  { « Plateform »: « Dev », « Kestrel »: { « EndPoints »: { « Http »: { « Url »: « http://localhost:1234 » } } }, « Logging »: { « LogLevel »: { « Default »: « Information », « Microsoft.AspNetCore »: « Warning » } } } Perso je rajoute une ligne "Environment" qui me permet de voir dans sur quel type d’environement je suis (et plus tard de l’afficher dans l’app).  Ce qui nous intéresse c’est la section Kestrel. On ajoute un EndPoints et on lui précise un port.  Faites un dotnet run sur votre projet à présent : On a un warning qui nous dit que l’adresse utilisé va écrasé celle du launchsetting.json. C’est ce qu’on veut. On voit bien la nouvelle adresse http://localhost:1234.  C’était pour la démo, en dev ça sert a rien de faire cela, autant utiliser le launchSettings.json qui est la pour ça. Donc enlever la ligne Kestrel, c’était pour la démo. Par contre on va mettre ces configs pour appsettings.staging.json  { « Plateform »: « Staging », « Kestrel »: { « EndPoints »: { « Http »: { « Url »: « http://localhost:7776 » } } }, « Logging »: { « LogLevel »: { « Default »: « Information », « Microsoft.AspNetCore »: « Warning » } } } et appsettings.prod.json { « Plateform »: « Prod », « Kestrel »: { « EndPoints »: { « Http »: { « Url »: « http://localhost:7777 » } } }, « Logging »: { « LogLevel »: { « Default »: « Information », « Microsoft.AspNetCore »: « Warning » } } } ASPNETCORE_ENVIRONMENT Encore une chose à savoir. Pour déterminer sur quel environement .net se trouve, il utilise une variable d’environement ASPNETCORE_ENVIRONMENT Elle est d’ailleurs clairement définie dans le fichier launchSettings.json à "Development". Donc en dev, le fichier de config appsettings utilisé sera appsettings.development.json Pour que ce mécanisme fonctionne en prod, soit on définie la variable ASPNETCORE_ENVIRONMENT à "Production" soit par défaut, si elle n’existe pas, c’est déjà le cas (attention moi j’ai nommé mon appsettings prod et non production). Le problème c’est que une variable d’environement est définie pour tout…

Azure Devops Pipeline (CI/CD) – Deploy

Objectif : déploiement en production Dans la précédente partie on a déployé une pipeline sur Azure DevOps. Celle ci nous permet de lancer une build dès que la branche master de notre repo Blazor Sandbox reçoit un nouveau commit. De cette manière on s’assure que le build fonctionne ou pas. On est prévenu du résultat par email.  Ce qui serait intéressant, c’est de pouvoir la déployer sur un serveur web automatiquement en cas de succès.  Ma config J’ai un serveur VPS chez iKoula pour 4€/mois, avec une debian linux.  Ca tourne plutot bien. Mais bon, j’ai pas beaucoup de traffic 🙂 Donc j’ai un site web https://dev.blazordemo.reactor.fr et https://blazordemo.reactor.fr qui tournent tous les deux sous Nginx. Derrière chez deux services kestrel asp.net core sous .net 6.0. (pour faire bien, il aurait fallut dissocier la prod de mon dev (ou recette, staging). Petit budget… Dans /var/www/blazordemo.reactor.fr et /var/www/dev.blazordemo.reactor.fr j’ai mes publications de site web asp.net core Blazor WASM (le serveur et le client WASM "all in one"). L’idée est de dire à Azure Devops Pipeline, lorsque la branche master reçoit un nouveau commit, tu publies une version du serveur et tu balances le tout via SSH (sftp). Pipeline YAML On est fixé sur les objectifs. Maintenant il faut traduire cela en YAML. Voici un bout de doc : https://docs.microsoft.com/fr-fr/azure/devops/pipelines/tasks/deploy/copy-files-over-ssh?view=azure-devops En premier lieu, je vais reprendre la précédente pipeline et modifier build par publish. La différence est notable pour Blazor Server WASM. (voir mon article) Un petit commit + push et on voit que Azure Devops lance un nouveau job. On attend qu’il termine et passe au vert. Je pense qu’on va procédé ainsi, à taton. Petit pas par petit pas.  Une modif + commit + push + retour du Job.  Point SSH/SFTP Pour accéder à mon serveur en toute sécurité, je me connecte via SSH. Je prends donc la main à distance depuis mon poste windows sur mon serveur debian linux, qq part en France. J’ai un mot de passe et un login. Et roule ma poule.  Mais on peut faire mieux. J’ai ajouté une paire de clé privée/publique et une passphrase. Ainsi, il faut avoir la clé privée + la passphrase pour accéder.  C’est plus sécurisant pour moi. Je laisse l’accès SSH classique pour des opérations plus ponctuelles. J’ai de mon côté une serie de fichier .bat qui lance une commande de publication .net core et des commandes winscp (permet de lancer des commandes SFTP depuis Windows). La connection se fait via cette clé et cette passphrase. Ainsi, je peux en un double clic mettre à jour ma prod/staging/recette/dev depuis mon poste, sans lacher mon mdp. Au lieu de le faire à la main depuis un client sftp. Ca marche ! C’est moins rapide qu’un client sftp (car les fichiers uplodé ne sont pas lancés en parrallele). J’ai deux types de scripts. La totale, qui met a jour toute la publication : et un autre "rapide" qui ne mets a jours que le minimum pour aller vite : et son fichier .bat  Donc l’idée, c’est de faire pareil sous Azure Devops. Yaml On va rajouter une nouvelle tâche dans notre pipeline YAML avec CopyFilesOverSSH 4 éléments sont à renseigner : sshEndPoint : c’est le nom de notre connexion SSH que l’on va configurer plus loin sourceFolder : le chemin relatif de votre publish. L’agent de build va s’occuper de récupérer votre publish au bon endroit. Attention au majuscule et minuscule si l’agent est sur linux !!! targetFolder: le chemin de destination de votre publication sur la machine cible.  cleanTargetFolder : facultatif, mais effacer le contenu de la destination fait pas de mal.  Service Connections Le sshEndpoint de tout à l’heure est à configurer dans les "project settings" dans la section Pieplines/Service Connections  Il reste plus qu’à créer la votre en cliquant sur le bouton new connection Sélectionnez SSH : puis remplissez selon votre config, en uploadant votre clé privée. Attention, celle ci doit être au format .pem. Et voila. C’est tout.  Relancer votre pipeline avec un petit git add commit push.  Normalement vous devriez avoir que du vert !

Blazor .net 6.0 – décollage

Découverte de Blazor J’ai été très très emballé lorsque j’en ai entendu parlé pour la premiière fois de Blazor. Bien que j’attendais à ce qu’il soit tué dans l’oeuf. Car au début, c’était un side project Microsoft sans prétention. Quelle idée, faire du web avec du C# ? et pourquoi pas VbScript tant qu’on y est… 🙂 Nan mais sans déconner, le js ça va deux minutes. Donc faire une web app en C# je signe.  J’ai donc taté du blazor en mode tuto au début. Puis j’ai oublié. Et me revoila ! Je vais présenter ici mes découvertes. En fait j’ai fait des erreurs et je voulais les écrires pour que qq évite de galérer comme moi.  Blazor .net 6.0 Bon la ça déconne plus. Blazor est officiellement inclu dans .net (depuis .net Core 3.1 il me semble) et donc on peut code pour de vrai, pour de vrai client. Et la ça change tout. Fini les tutos. Alors on  commence avec un nouveau projet sous VS2022. Et celui ci nous propose deux solutions :  Blazor WebAssembly  Balzor Server Blazor Server Ce type de projet est n’y plus n’y moins qu’un projet ASP.net Core avec du Razor en couche de présentation. Si auparavent vous avez fait du web.form pour les plus vieux, du MVC5 ou de l’Asp.net Core vous allez pas être trop perdu.  Pour les autres, on est sur une application classique de type Client (browser) Server (IIS, Apache, Nginx, Kernel…) En ajoutant une couche SignalR vous avez un site web qui déboite. Mais qui ne gère pas le offline. Blazor WebAssembly Le vrai plus est la pour moi. On peut envisager de faire une application web PWA avec .net. Et ça pour un dev Microsoft de 20 ans, c’est juste de la bombe pour moi. Et qui plus est, qui peut tourner sur un OS Linux. (voir articles sur les coûts) Donc Blazor Wasm pour les intimes et une tuerie. On va pouvoir utiliser la puissance du language C#, les outils VS et VS Code, et toutes les libs qu’on a l’habitude d’utiliser depuis des années.  Je vais parler dans le reste de l’article que de Blazor Wasm.      Comment ça marche ? L’objectif de l’article est de vous amener à bien comprendre comment Balzor fonctionne. D’un point de vue architecture applicative et d’un point de vue réseau/serveur.  Lorsque l’on créer un nouveau projet, VS2022 nous demande si on souhaite héberger le site via Asp.net Core. (kernel) Il nous demande aussi si l’on souhaite utiliser des fonctionnalités PWA. Pour ma part oui pour les deux.  Voici la différence entre un projet WASM sans serveur (à droite) et un projet avec : Le projet BlazorApp1.Client et BlazorApp2 (sans server) constituent l’application web PWA. On y trouve du code C#. Mais au final on aura que du code html/css/js pure en sortie et un dossier _framework, qui lui par contre contient qq dll indispensable au bon fonctionnement de blazor.  Voici une publication : On a un webconfig et un repertoire wwwroot qui contient ceci:     C’est la que ca devient chelou. Si on se place coté browser, et surtout en mode déconnecté, on a pas besoin d’un serveur (web, pure static de fichier), (sauf bien entendu lors du premier chargement). Ensuite on peut très bien s’en passer de ce serveur. D’ailleurs pourquoi pas héberger ce client sur un CDN (content delivery Network) Mais alors on a quoi si on se place coté serveur ? Bonne question. C’est la que l’hôte Asp.net Core intervient.  Comme on peut le voir dans le premier projet, on a un projet Server et un projet Shared. Shared est juste un projet de classe, rien de méchant on partage du code commun avec les deux autres projets.  Le projet Server par contre est le code qui va gérer la partie serveur, comme son nom l’indique. Et lui aura aussi la partie cliente. Regarder les sorties d’une publication du projet serveur :  On retrouve bien wwwroot de la partie cliente ! Ceux sont ces fichiers static que le serveur va gérer par la suite avec le browser. Donc pour résumer : On a un projet Blazor Server : projet classique client/serveur (rendu server sur chaque page) avec une liaison SignalR.  On a un projet Blazor WASM : projet PWA (client web autonome) qui peut avoir des options d’hébergement avec l’ajout d’un projet Server + Share. J’avoue qu’on s’y perds avec le terme « Server ». A mon avis les équipes de microsoft on du aussi gamberger pas mal sur le naming. Mais en fait, quand on sait, c’est clair. (complètement conne cette phrase…)   Mes erreurs Sotrie de build Lorsque l’on travaille en debug local, on ne fait pas trop attention à tout cela. Mais dès lors qu’on passe en prod c’est plus la même histoire.  La ou j’ai merdé, c’est de considérer le dossier bin/Release comme ma sortie pour la prod. Erreur ! Allez y faire un tour, on a uniquement la génération du projet courant. Ce qui est logique. Mais la petite nouveauté c’est la publication qui intègre le projet Client dans la sortie du projet Server.  Autre erreur, les ports.  En local on peut configurer les ports des projets Client et Server via le fichier properties/launchSettings.json.Et on peut executer les deux projets. Modifier les ports de ces fichiers et lancer un run.  Mais dans tous les cas ceux qui comptent pour la prod sont ceux du projet serveur. Et moi comme un con, j’avais le projet Client comme projet de démarrage. A éviter car j’ai perdu beaucoup de temps à rien comprendre.  Voila, j’y ai passé presque deux jours (config Ngix sur linux). Donc je résume un peu. Je me disais que ca valait bien un billet. ++

AWS – Elastic Beanstalk – DevOps

Elastic Beanstalk est un service AWS gratuit (on ne paie que ce qu’on consomme sur les instances) qui permet de manager facilement un bout de cloud. Ce service s’adresse à ceux qui souhaitent deployer dans le cloud une application rapidement en laissant le soin du scaling à AWS (ça se se fait automatiquement). Donc si vous n’avez pas de besoin crucial de finesse de config sur vos environnements, EB est un bon choix. Objectif de cet article : déployer un site web en quelques lignes de commande sur AWS – EB. Staging et Prod. Je ne sais pas vous, mais d’habitude, pour lancer un POC ou un petit site rapide, je passe pas mal de temps à configurer et gérer mon environnement de production, et surtout mes déploiements. J’ai un VPS sur OVH qui me sert pour le moment de dev/prod (ce site étant sur ce serveur). Je passe par un classique sFTP pour uploader mes builds. J’ai toujours voulu automatiser ces tâches. C’est relativement facile depuis un mac ou linux, mais ça a longtemps été galère sur Windows. En ce qui concerne les outils en ligne de commande, j’y arrivais pas ou mal. De plus, mon VPS n’est pas du tout scalable. Du coup, j’ai mis un pied dans le cloud via Azure. Perso je trouve que c’est bien le bordel. Ca évolue régulièrement et j’ai pas de formation Azure. J’ai l’impression qu’il fait sortir l’artillerie lourde dès le début. Pour un dev comme moi, j’ai besoin d’un accès gratuit ou peu cher avec maitrise des coûts dès le départ. Azure dispose d’une CLI, on peut jouer avec. J’ai testé la création de deux instances VM avec du kubernetes, du docker, et tout un tas de trucs qui au final me coute un bras. Ya bien une offre Azure avec qq crédits, mais pour le moment j’ai pas encore trouvé qq chose à moins de 20 balles/mois (et c’est déjà trop !). Moi développeur, je veux tester avant tout, lancer un produit, monter en charge facilement, maitriser mes coûts et ensuite commencer à réfléchir à une architecture/infra « long life ». Amazon propose une offre gratuite sur 12 mois pour tester ses services. En gros on a le droit à des services, mais pour savoir « combien, comment, où, avec qui, tout ça », c’est pas simple (faut attendre la fin du mois, perso j’ai 18$ en 14 jours juste a tester ce qui suit…). On peut monter ses VMs comme je l’ai fait sur Azure, avec une CLI AWS ou sur la Console AWS, mais c’est vraiment long et au départ on a pas besoin d’une armada de trucs. Elastic Beanstalk est la pour ça. AWS EB va s’occuper de tout ce que je ne maitrise pas ou mal. Ce que je veux, c’est deux environnements de staging et de prod. Un site web + une base de données SQL. On couvre l’essentiel de mes besoins pour le moment et à mon avis, les vôtres aussi. Mise en bouche : Avant de commencer à jouer avec la CLI je vous propose deux vidéos intéressantes qui m’ont mis le pied à l’étrier : La première vidéo permet de créer un site web asp.net core mvc tout simple et de l’uploader sur AWS – EB en utilisant la console de management AWS. Cette dernière mal nommé car on pense à une console en ligne de commande. Il n’en est rien. C’est une interface web. Il est intéressant de commencer à se former via celle ci car elle permet de se faire une idée des services et fonctionnalités disponibles. De plus, lorsque nous passerons sur la CLI, c’est un bon moyen de s’assurer du résultat de nos commandes. Faut savoir qu’on peut aussi passer via une API web, donc programmer des trucs avec… La seconde vidéo nous montre comment connecter une base de données à notre site web. En gros le strict minimum pour un site web assez basique, le tout sur le cloud. Il vous faudra bien sur un compte AWS et une carte bancaire. Il existe des offres gratuites sur 12 mois. Il faut faire attention à ce qu’on choisit pour rester dans le pack « gratos ». La CLI – eb La commande line interface d’Elastic Beanstalk (doc officielle) permet d’administrer votre cloud EB comme si vous êtiez sur la console AWS, mais en ligne de commande… L’intérêt est d’automatiser certaines tâches. Le but est de pouvoir coder en dev sur une machine local et de deployer son code en 2 deux trois mouvements sur un environnement cloud Staging et Prod. Je pars du principe que vous avez votre site web de prêt (pour moi ce sera un site asp.net core). On se met à la racine de celui ci via votre terminal préféré. Ci dessus, la console AWS EB qui liste mes environnements et mes applications. Si vous avez fait les tutos des deux vidéos précédentes, vous allez reconnaitre Netcoredemo Le but est de refaire exactement la même chose en ligne de commande. Première commande : eb init Cette commande commence par créer un répertoire .elasticbeanstalk à la racine de votre projet (enfin si vous y êtiez lorsque vous l’avez taper). On y retrouvera quelques fichiers intéressant pour la suite. eb va vous demander les points suivant : Region : pour ma part eu-west-3 Choix de l’app (une existante ou une nouvelle) : une nouvelle App name : DemoDevOps Platform : il y a le choix, pour moi .net core on linux SSH : pour le moment non (c’est à envisager par contre) et biiimmmm : On constate que notre application toute fraîche n’a pas d’environnement d’exécution. Nous allons le créer avec la prochaine commande. Si on regarde dans le répertoire .elasticbeanstalk on y trouve un nouveau fichier config.yml. Il contient tout ce que nous venons de créer sous forme d’un fichier (manifest de deploiement). On verra plus tard qu’on passera via ce fichier pour aller encore plus vite. Deuxième commande : eb create Cette commande va créer un environnement pour notre…

Conteneuriser et exploiter un cluster via AKS

Dans cet article nous allons suivre le tutoriel de la doc de microsoft tutorial-kubernetes-prepare-app J’ai pour ma part totalement effacé toute resource sur Azure (free trial) pour partir d’une feuille blanche car certain nom de resource été similaire. Ce tuto part du principe que l’on a une application qui fonctionne en dev. On souhaite la conteneuriser, la distribuer sur un registry online puis s’en servir via AKS. Ensuite on verra comment scaler l’app. Ce tuto est plutot long, mais je pense complet sur les sujet essentiels.   1 – Création d’une image docker On va cloner une app de demo sur github, mais si vous avez la votre, prennez la. Ouvrez un terminal, créer un répertoire de travail et se mettre dedans puis taper : git clone https://github.com/Azure-Samples/azure-voting-app-redis.git L’image est très légère. Faut dire que le code aussi. En se rendant dans le repertoire azure-voting-app-redis on peut voir quelques fichiers dont un qui va particulièrement nous intéresser : docker-compose.yaml version: ‘3’ services:   azure-vote-back:     image: redis     container_name: azure-vote-back     ports:         – « 6379:6379 »   azure-vote-front:     build: ./azure-vote     image: azure-vote-front     container_name: azure-vote-front     environment:       REDIS: azure-vote-back     ports:         – « 8080:80 » Ce fichier est relativement simple. Nous avons deux services basées sur une image redis et une app web dont l’image est azure-vote-front. L’image Redis proviendra du registry Docker Hub (version officielle) et la seconde sera buildé avec un dockerfile situé dans le projet web azure-vote. Voici ce dockerfile : FROM tiangolo/uwsgi-nginx-flask:python3.6 RUN pip install redis ADD /azure-vote /app Ce dockerfile va créer un conteneur basé sur l’image tiangolo/uwsgi-nginx-flask (950 Mo) (avec python 3.6). On execute ensuite une commande pour installer redis (via python) et on ajoute le code source du site web dans un repertoire sur le conteneur nommé app. On a plus qu’a taper la commande docker-compose up -d ce qui va monter les deux images dans le registry local. Dans un premier temps cela va télécharger les image de  tiangolo et redis si vous ne les avez pas déjà sur votre poste. Ensuite docker-compose va builder l’image de notre app. (attention, il faudra la rebuilder pour la mettre a jour dans une prochaine image). La commande suivante va lister vos images locales : $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE azure-vote-front latest 9cc914e25834 40 seconds ago 694MB redis latest a1b99da73d05 7 days ago 106MB tiangolo/uwsgi-nginx-flask flask 788ca94b2313 9 months ago $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 82411933e8f9 azure-vote-front « /usr/bin/supervisord » 57 seconds ago Up 30 seconds 443/tcp, 0.0.0.0:8080->80/tcp azure-vote-front b68fed4b66b6 redis « docker-entrypoint… » 57 seconds ago Up 30 seconds 0.0.0.0:6379->6379/tcp azure-vote-back En lisant nos conteneurs lancé par docker on voit bien nos deux images. On a plus qu’à tester l’url http://localhost:8080 et on devrait voir notre app tourner localement! Un petit docker-compose down pour libérer ces process docker et cette partie est finie. 2 – Envoyer nos conteneurs vers Azure Container Registry La première chose à faire est de créer une instance d’Azure Container Registry (ACR) En premier lieu on créer le groupe de ressources : az group create –name myResourceGroup –location eastus Pour info celui ci n’apparaitra pas sur le portail pour le moment car il est vide. Il faut lui rajouter un élement. Voici la commande pour créer un ACR : az acr create –resource-group myResourceGroup –name myACR35 –sku Basic Le nom du registry doit être unique car il sera accessible publiquement via une url comme celle ci myacr.azurecr.io En tapant cette commande, azure nous indique que ce nom est déjà occupé et nous livre une adress web pour vérifier les nom existant. On va renommer noter myACR en qq chose de libre, myACR35 à l’air de passer : > az acr create –resource-group myResourceGroup –name myACR35 –sku Basic { « adminUserEnabled »: false, « creationDate »: « 2020-01-30T10:12:36.101431+00:00 », « id »: « /subscriptions/eaeaae83-9dcd-405b-8f02-4e58e0e30bbb/resourceGroups/myResourceGroup/providers/Microsoft.ContainerRegistry/registries /myACR35 », « location »: « eastus », « loginServer »: « myacr35.azurecr.io », « name »: « myACR35 », « networkRuleSet »: null, « policies »: { « quarantinePolicy »: { « status »: « disabled » }, « retentionPolicy »: { « days »: 7, « lastUpdatedTime »: « 2020-01-30T10:12:37.145663+00:00 », « status »: « disabled » }, « trustPolicy »: { « status »: « disabled », « type »: « Notary » } }, « provisioningState »: « Succeeded », « resourceGroup »: « myResourceGroup », « sku »: { « name »: « Basic », « tier »: « Basic » }, « status »: null, « storageAccount »: null, « tags »: {}, « type »: « Microsoft.ContainerRegistry/registries » } L’ACR myACR35 étant créé on va s’y connecter : > az acr login –name myACR35 Uppercase characters are detected in the registry name. When using its server url in docker commands, to avoid authentication errors, use al l lowercase. Login Succeeded Le retour de cette commande nous indique qu’il serait préférable à l’avenir d’utiliser un  nom en minuscule. Balisage (tag) Pour utiliser l’image conteneur azure-vote-front avec ACR, on doit baliser cette image avec l’adresse du serveur de connexion de votre registre. Celle ci se trouve dans le retour json précedent : « loginServer »: « myacr35.azurecr.io » Si vous ne l’avez plus, vous pouvez l’obtenir avec la commande suivante : az acr list –resource-group myResourceGroup –query « [].{acrLoginServer:loginServer} » –output table À présent, étiquetez votre image azure-vote-front locale avec l’adresse myacr35.azurecr.io (en minuscule) du registre de conteneurs. Pour indiquer la version de l’image, ajoutez :v1 à la fin du nom de l’image :  docker tag azure-vote-front myacr35.azurecr.io/azure-vote-front:v1 PS D:\Kubernetes\AKSText2\azure-voting-app-redis> docker images REPOSITORY TAG IMAGE ID CREATED SIZE azure-vote-front latest df60d4cc1f96 About an hour ago 965MB myacr35.azurecr.io/azure-vote-front v1 df60d4cc1f96 About an hour ago 965MB On remarque alors qu’une nouvelle image est présente dans la liste (docker image) celle ci étant balisé sur notre serveur distant. Envoyer l’image docker push myacr35.azurecr.io/azure-vote-front:v1 On envoit notre image via la commande docker push. Cela peut prendre qq minutes suivant la taille de celle ci. Quand celle ci sera uploadé, on ira vérifier avec cette commande qui liste les images de notre repo de conteneur distant : > az acr repository list –name myacr35 –output table Result —————- azure-vote-front Notre image est bien sur notre Azure Container Registery myACR35. 3 – Déployer un cluster az aks create –resource-group myResourceGroup –name myAKSCluster –node-count 2 –generate-ssh-keys –attach-acr myacr35 Cette commande permet la création d’un cluster de 2 nodes branché sur le registre ACR que l’on vient de créer. Vous devriez voir au bout de qq minutes un retour en JSON : { « aadProfile »: null, « addonProfiles »: null, « agentPoolProfiles »: [ { « availabilityZones »: null, « count »: 2, « enableAutoScaling »: null, « enableNodePublicIp »: null, « maxCount »: null, « maxPods »: 110, « minCount »: null, « name »: « nodepool1 », « nodeTaints »: null, « orchestratorVersion »: « 1.14.8 », « osDiskSizeGb »: 100, « osType »: « Linux », « provisioningState »: « Succeeded », « scaleSetEvictionPolicy »: null, « scaleSetPriority »: null, « type »:…

Tuto AKS – mise en place

Dans cet article nous allons mettre en place AKS sur Azure en ligne de commande. AKS en ligne de commande : https://docs.microsoft.com/fr-fr/azure/aks/kubernetes-walkthrough Prérequis : avoir installer deux VMs sur azure (voir le tuto précédent) En avant Guingamp : az aks create –resource-group TutorialResources –name myAKSCluster –node-count 1 –enable-addons monitoring –generate-ssh-keys Cette commande va créer AKS sur un cluster nommé myAKSCluster avec une seule node et du monitoring. Ca prends qq minutes… La commande va normalement vous renvoyer du JSON avec toute la config installée : Json { « aadProfile »: null, « addonProfiles »: { « omsagent »: { « config »: { « logAnalyticsWorkspaceResourceID »: « /subscriptions/eaeaae83-9dcd-405b-8f02-4e58e0e30bbb/resourcegroups/defaultresourcegroup-eus/providers/microsoft.operationalinsights/workspaces/defaultworkspace-eaeaae83-9dcd-405b-8f02-4e58e0e30bbb-eus » }, « enabled »: true } }, « agentPoolProfiles »: [ { « availabilityZones »: null, « count »: 1, « enableAutoScaling »: null, « enableNodePublicIp »: null, « maxCount »: null, « maxPods »: 110, « minCount »: null, « name »: « nodepool1 », « nodeTaints »: null, « orchestratorVersion »: « 1.14.8 », « osDiskSizeGb »: 100, « osType »: « Linux », « provisioningState »: « Succeeded », « scaleSetEvictionPolicy »: null, « scaleSetPriority »: null, « type »: « VirtualMachineScaleSets », « vmSize »: « Standard_DS2_v2 », « vnetSubnetId »: null } ], « apiServerAccessProfile »: null, « dnsPrefix »: « myAKSClust-TutorialResource-eaeaae », « enablePodSecurityPolicy »: null, « enableRbac »: true, « fqdn »: « myaksclust-tutorialresource-eaeaae-955218b3.hcp.eastus.azmk8s.io », « id »: « /subscriptions/eaeaae83-9dcd-405b-8f02-4e58e0e30bbb/resourcegroups/TutorialResources/providers/Microsoft.ContainerService/managedClusters/myAKSCluster », « identity »: null, « kubernetesVersion »: « 1.14.8 », « linuxProfile »: { « adminUsername »: « azureuser », « ssh »: { « publicKeys »: [ { « keyData »: « ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCxi46MPyNjpH/kBnXxU5t4bPcWpeCrByvAH9p6uzM+IDda+NTrWHpEmUr1IVZS7CXku5lpl6v3WJjuK1E35DdB5s2ewB7VR6iYKHgruqduAeprMdUx34xeXxn7cc9/QC1b83Lw7k+oyYYYoIfYcy9q/beIlBco8Eidj6GxNRk74fHd3H5r99W0pqA4IfIFpksOb19iiO+pgiABgewmAQETldclajNjVuV6G3cVDdFILGUXjSA/Z1d1eWoqh00XbtyY7sl3LkLd6puHTm1Qt5UlcD4mZKpI2ggqWicHVLA2Eq2Fz7GE637CdYsqXXs5eDJUeBA8S+d2fas00zMB4Pyb » } ] } }, « location »: « eastus », « maxAgentPools »: 8, « name »: « myAKSCluster », « networkProfile »: { « dnsServiceIp »: « 10.0.0.10 », « dockerBridgeCidr »: « 172.17.0.1/16 », « loadBalancerProfile »: { « effectiveOutboundIps »: [ { « id »: « /subscriptions/eaeaae83-9dcd-405b-8f02-4e58e0e30bbb/resourceGroups/MC_TutorialResources_myAKSCluster_eastus/providers/Microsoft.Network/publicIPAddresses/449f34d6-68cb-49ad-aa08-825d6448e1d7 », « resourceGroup »: « MC_TutorialResources_myAKSCluster_eastus » } ], « managedOutboundIps »: { « count »: 1 }, « outboundIpPrefixes »: null, « outboundIps »: null }, « loadBalancerSku »: « Standard », « networkPlugin »: « kubenet », « networkPolicy »: null, « outboundType »: « loadBalancer », « podCidr »: « 10.244.0.0/16 », « serviceCidr »: « 10.0.0.0/16 » }, « nodeResourceGroup »: « MC_TutorialResources_myAKSCluster_eastus », « privateFqdn »: null, « provisioningState »: « Succeeded », « resourceGroup »: « TutorialResources », « servicePrincipalProfile »: { « clientId »: « f00bf5fa-37b4-42e5-9f2f-33ff3f32c672 », « secret »: null }, « tags »: null, « type »: « Microsoft.ContainerService/ManagedClusters », « windowsProfile »: null } AKS est maintenant installé dans le groupe de ressource « TutorialResources » Lors de la création d’un cluster AKS, un deuxième groupe de ressources est automatiquement créé pour stocker les ressources AKS. Pour ma part il s’appelle DefaultResourceGroup-EUS. Dedans on y trouve ceci : Le premier est un « espace de travail Log Analytics ». Le second est une « solution ».  Pour le moment je ne sais pas trop a quoi correspond ce dernier. Enfin, l’installation d’AKS a généré un troisieme groupe de ressources avec 5 éléments : Dans l’ordre affiché nous avons un équilibreur de charge un groupe de sécurité réseau une adresse IP publique une table de routage un réseau virtuel. Voilà, beaucoup d’élément on été automatiquement installé. C’est une configuration par défaut qu’il faudra bien sûr ajuster aux besoins.  Pour la suite on va avoir besoin de kubectl qui est le client de ligne de commande Kubernetes. Si vous avez DockerDesktop avec la case Kubernetes cochée, vous devriez déjà l’avoir. Sinon vous pouvez toujours l’obtenir avec cette commande : az aks install-cli Pour se connecter à notre cluster aks via kubectl : az aks get-credentials –resource-group TutorialResources –name myAKSCluster   réponse : Merged « myAKSCluster » as current context in C:\Users\Yann\.kube\config   Pour voir les nodes : kubectl get nodes On y est, Kubernetes est installé sur notre cluster et tourne avec une seule node. 

Azure CLI – tuto 2 VMs

Tuto pour apprendre avec Azure CLI à monter des VMs et ensuite utiliser AKS (prochain tuto). Prérequis : avoir un compte Azure (il en existe des gratuits avec 170€ de crédits) et Azure Cli installé sur sa machine. Azure cli : https://docs.microsoft.com/fr-fr/cli/azure/get-started-with-azure-cli?view=azure-cli-latest Création d’une VM 1 Pour tester azure cli, on va lui demander sa version az –version azure-cli 2.0.80 (…) On va maintenant se connecter sur Azure via cette commande az login Cela ouvre un browser pour se connecter au portail web. Après connextion, le terminal affiche les abonnements Azure Nous allons créer un groupe de ressources : az group create –name TutorialResources –location eastus Il n’est pas apparu sur le portail web d’Azure. Sans doute car je n’avais aucune ressources dedans pour le moment. Nous allons maintenant créer notre première Virtual Machine en ligne de commande : az vm create –resource-group TutorialResources ` –name TutorialVM1 ` –image UbuntuLTS ` –generate-ssh-keys ` –output json ` –admin-username yannvasseur ` –verbose Note : sous powershell une commande multi ligne se termine par ` (en bash c’est \ ) j’ai dû rajouter –admin-username yannvasseur ` à cette commande car on avait une erreur sinon. Il faut qq minutes pour créer une VM, voici ce que la commande nous retourne : { « fqdns »: «  », « id »: « /subscriptions/eaeaae83-9dcd-405b-8f02-4e58e0e30bbb/resourceGroups/TutorialResources/providers/Microsoft.Compute/virtualMachines/TutorialVM1 », « location »: « eastus », « macAddress »: « 00-0D-3A-8D-7D-07 », « powerState »: « VM running », « privateIpAddress »: « 10.0.0.4 », « publicIpAddress »: « 13.90.91.229 », « resourceGroup »: « TutorialResources », « zones »: «  » } Pour obtenir plus d’information sur cette VM : az vm show –name TutorialVM1 –resource-group TutorialResources Le listing que vous obtenez est plutot long, mais d’autant plus complet. Remarquez que l’on a pas de password pour l’administrateur. Json results : Si on se connecte sur le portail web Azure, on voit tout ce qui a été créé : Dans l’ordre affiché on a une machine virtuelle Standard DS1 v2 (1 processeurs virtuels, 3.5 Gio de mémoire) sous Linux (ubuntu 18.04), un disque de 30Go SSD premium, un groupe de sécurité réseau (un firewall), une adresse IP publique (13.90.91.229), une interface réseau et un réseau privé virtuel (10.0.0.0/16). L’emplacement est USA est. Tout ca en une ligne de commande ! VM2 On va maintenant en créer une deuxieme parce qu’on est foufou. Mais avant cela on va récupérer des infos sur notre premiere VM concernant notre subnet (sous réseau) afin que nos deux VMs soient sur le même réseau : az vm show –name TutorialVM1 ` –resource-group TutorialResources ` –query ‘networkProfile.networkInterfaces[].id’ ` –output tsv Résultat : /subscriptions/eaeaae83-9dcd-405b-8f02-4e58e0e30bbb/resourceGroups/TutorialResources/providers/Microsoft.Network/networkInterfaces/TutorialVM1VMNic Cette commande nous permet d’obtenir l’id de notre interface réseau VM1. A partir de cet id, on va demander a azure toutes les informations de cette interface réseau : az network nic show –ids /subscriptions/eaeaae83-9dcd-405b-8f02-4e58e0e30bbb/resourceGroups/TutorialResources/providers/Microsoft.Network/networkInterfaces/TutorialVM1VMNic info interface réseau On va devoir récupérer l’id de l’IP (et pour plus tard on aura peut etre besoin de l’id du sous réseau) az network nic show –ids /subscriptions/eaeaae83-9dcd-405b-8f02-4e58e0e30bbb/resourceGroups/TutorialResources/providers/Microsoft.Network/networkInterfaces/TutorialVM1VMNic ` –query ‘{IP:ipConfigurations[].publicIpAddress.id, Subnet:ipConfigurations[].subnet.id}’ ` -o json Voici le résultat, sous forme de donnée JSON : { « IP »: [ « /subscriptions/eaeaae83-9dcd-405b-8f02-4e58e0e30bbb/resourceGroups/TutorialResources/providers/Microsoft.Network/publicIPAddresses/TutorialVM1PublicIP » ], « Subnet »: [ « /subscriptions/eaeaae83-9dcd-405b-8f02-4e58e0e30bbb/resourceGroups/TutorialResources/providers/Microsoft.Network/virtualNetworks/TutorialVM1VNET/subnets/TutorialVM1Subnet » ] } Maintenant on va créer une deuxième VM avec cette commande az vm create –resource-group TutorialResources ` –name TutorialVM2 ` –image UbuntuLTS ` –generate-ssh-keys ` –subnet /subscriptions/eaeaae83-9dcd-405b-8f02-4e58e0e30bbb/resourceGroups/TutorialResources/providers/Microsoft.Network/virtualNetworks/TutorialVM1VNET/subnets/TutorialVM1Subnet ` –admin-username yannvasseur ` –output json ` –verbose Notez que l’on juste rajouté un sous réseau et renommer son nom. Voici le résultat : Use existing SSH public key file: C:\\Users\\Yann\\.ssh\\id_rsa.pub Accepted: vm_deploy_Ud4Y1LjR5olzzHxJhIQ1kNiWStjJCeBn (Microsoft.Resources/deployments) { « fqdns »: «  », « id »: « /subscriptions/eaeaae83-9dcd-405b-8f02-4e58e0e30bbb/resourceGroups/TutorialResources/providers/Microsoft.Compute/virtualMachines/TutorialVM2 », « location »: « eastus », « macAddress »: « 00-0D-3A-18-E6-A5 », « powerState »: « VM running », « privateIpAddress »: « 10.0.0.5 », « publicIpAddress »: « 40.117.142.145 », « resourceGroup »: « TutorialResources », « zones »: «  » } command ran in 103.297 seconds. Et voila notre 2ime VM est créée. Ce qui est vérifié sur le portail web : Nettoyage Si vou souhaitez tout effacer, c’est par ici : https://docs.microsoft.com/fr-fr/cli/azure/azure-cli-vm-tutorial?tutorial-step=7&view=azure-cli-latest

Kubernetes & AKS – Intro

Intro Kubernetes (communément appelé « K8S ») est un système open source qui vise à fournir une « plate-forme permettant d’automatiser le déploiement, la montée en charge et la mise en œuvre de conteneurs d’application sur des clusters de serveurs ». Il fonctionne avec toute une série de technologies de conteneurisation, et est souvent utilisé avec Docker. Il a été conçu à l’origine par Google, puis offert à la Cloud Native Computing Foundation. (Wikipedia) AKS (Azure Kubernete Service) est un service Kubernetes sur Azure. Il permet d’automatiser le déploiement, la mise à l’échelle et le fonctionnement de conteneurs d’application entre des clusters d’hôtes. C’est un orchestrateur de conteneur. Cela signifie qu’il est en charge de monter des conteneurs suivant un plan que l’on fixe. Il peut par exemple automatiser la charge (monter des conteneurs supplémentaire), relancer un conteneur défaillant, prévoir une réduction ou une augmentation de charge (planification) et donc adapter des besoins suivant des critères (horraire, ponctuel, exceptionnel, CPU, Bandwidth…) https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/ L’image ci dessous permet d’illustrer ce qu’est un cluster de conteneurs : Un cluster Kubernetes regroupe plusieurs hôtes Docker et les expose sous la forme d’un seul hôte Docker virtuel. Vous pouvez donc déployer plusieurs conteneurs sur le cluster et effectuer un scale-out d’un nombre illimité d’instances de conteneurs. Le cluster prend en charge tous les détails complexes de la gestion, comme la scalabilité, l’intégrité,etc. Structure et topologie Kubernetes dispose d’une structure basée sur un Master Node et des Nodes. Le Master Node contrôle les nodes. Ces dernières sont des machines virtuelles ou physique. Sur une node on peut retrouver un ou des Pods. Un namespace permet de segmenter des pods, volumes, secrets, configmap… On peut avoir deux namespaces (par exemple dev et staging) sur le même cluster. (là où d’habitude on travaillait avec des machines séparées sur une app monolithique) kubectl est l’application en ligne de commande permettant d’interragir avec Kubernetes. Il est possible d’utiliser Kubernetes sur votre machine locale avec Docker Desktop en cochant cet option : Il est donc possible de travailler localement et préparer ses fichier yaml pour AKS (dev, staging, prod) Pour cela il faut aussi préparer nos conteneurs et les déposer sur un registre (Docker Registry sur Azure) afin qu’ils puissent être utilisé par AKS. Ressources pour se former : Podcast Devapps.be Introduction à Kubernetes : https://www.youtube.com/watch?v=b5vJsYR-Vbo La doc microsoft : https://docs.microsoft.com/fr-fr/azure/aks/ Comprendre Kubernetes en 3 minutes : https://www.youtube.com/watch?v=uyiDNcSmwFw (perso j’ai rien compris…) Celle la est mieux https://www.youtube.com/watch?v=QJ4fODH6DXI xavki : https://www.youtube.com/watch?v=vFfngcRPj9M Web2Day 2017 : https://www.youtube.com/watch?v=zztKO0iRX_w&t=175s