Archives de catégorie : DevOps

L’essentiel sur Docker et les conteneurs Windows

Le support de Docker est une des principales nouveautés de Windows Server 2016, et maintenant qu’il est possible de conteneuriser nos bonnes vieilles applications ASP.net ainsi que toutes les nouvelles sous .net Core, je vous propose un petit tour de toutes les notions essentielles pour comprendre Docker et les conteneurs Windows.

windows-10-docker

Afin de ne pas se laisser distancer par Linux sur le marché des serveurs, Microsoft a conclu un partenariat avec Docker, leader de la conteneurisation sous Linux, afin d’implémenter la même possibilité sous Windows. 2 ans de développement en commun plus tard, nous pouvons enfin profiter de ceci afin d’héberger nos applications On-Premise, en IaaS, ou via services cloud d’hébergement de conteneurs.

Les conteneurs

image

On compare souvent les conteneurs à de la virtualisation d’OS. Ainsi au lieu de virtualiser tout le matériel d’une machine (CPU, RAM, Disques, carte réseau, etc.),  un conteneur permet de faire fonctionner une application au sein d’un environnement isolé où la couche hardware utilisée correspond à celle de la machine hôte du conteneur, mais également où le kernel de la machine hôte est partagé par tous les conteneurs en cours d’exécution.

L’idée est de proposer un environnement d’exécution isolé sans payer le coût lié à l’hébergement d’une VM, et ainsi  de parvenir à héberger un nombre beaucoup plus important d’applicatifs isolés au sein d’une machine hôte.

Les containers permettent également d’avoir une grande souplesse au sujet du type de déploiement que pouvez effectué. Déployer votre application sur un serveur physique, dans une VM, ou encore sur le Cloud se fait de manière extrêmement simple puisqu’il vous suffit de déployer votre conteneur où vous le souhaitez pour avoir une application fonctionnelle, sans réinstallation logicielle, ni paramétrage.

Différents niveaux d’isolations sont proposés sous Windows Server 2016.

Les conteneurs Windows

Avec ce niveau d’isolation, chaque conteneur partage le kernel de la machine hôte. Ainsi, il est uniquement possible de faire fonctionner des conteneurs Windows au sein d’un serveur fonctionnant lui-même sous Windows, et ayant la même version de kernel.

Les conteneurs Hyper-V

Un niveau d’isolation supplémentaire est possible grâce aux conteneurs Hyper-V. Les conteneurs Hyper-V nécessitent un hyperviseur Hyper-V, Une petite VM est automatiquement créé et démarrée lorsque vous souhaitez démarrer votre conteneur.

Le kernel n’est donc plus partagée entre conteneurs, mais reste propre à chaque conteneur.

Autre avantage, vous pouvez faire fonctionner un conteneur Linux sous Windows grâce à ce niveau d’isolation.

Les images Docker

image

Les conteneurs sont basés sur des images qui contiennent :

  • Une image de l’OS souhaité. Même si le conteneur partage le même kernel que la machine hôte, on s’assure ainsi d’utiliser une image “propre” indépendante de la machine hôte, et non polluée par les différents drivers et logiciel du constructeur de votre serveur
  • Le ou les frameworks applicatifs souhaités
  • Et bien évidemment votre application !

Les images sont construites grâce à un fichier Dockerfile qui permet de définir l’image de base utilisée, et qui permet d’exécuter différentes commandes pour installer votre application et ses dépendances, et effectuer différents paramétrages.

Les couches

Cela signifie-t-il qu’en plus de mon application web (par exemple packagée via un package webdeploy) je dois en plus uploader et télécharger toute une image de Windows ?

Au lieu d’avoir une application de 50Mo, je me donc retrouve avec une image de plusieurs Go ?

Oui, et non (et même surtout non). Il est certes nécessaire de packager l’application au sein d’une image Docker qui contient l’image de l’OS et qui pèse donc au total assez lourd, mais il n’est pas pourtant nécessaire de télécharger l’intégralité de tout cela pour déployer une application.

Les images Docker reposent en effet sur un principe de couches, chaque instruction d’un fichier dockerfile créé en effet une couche au dessus des modifications déjà effectuées.

docker-layers

Lorsque l’on souhaite récupérer une image, Docker va donc récupérer celle-ci, couche par couche en commençant par l’image de base de l’OS. Et bien évidemment si la ou les couches sous-jacentes à la dernière couche de votre image sont déjà disponibles sur votre ordinateur, Docker ne les récupèrera pas de nouveau.

Ainsi si vous avez différentes images basées sur l’image microsoft/windowservercore, vous n’aurez pas à récupérer les 4Go de celle-ci à chaque fois, vous récupèrerez uniquement les couches qui ne sont pas encore disponible sur la machine hôte.

Les images de base

D’un point de vue OS, Microsoft propose deux images de base de Windows Server, une pour Windows Server Core qui pèse 4 Go en compressé, et une autre pour la nouvelle version “ultra-light” de Windows nommée Windows Nano Server. Celle-ci pèse 300Mo compressée.

Windows Nano Server correspond à un important travail de refactoring de Windows et de suppression de différents services considérés comme étant inutiles pour ce type de serveur.

Vous pouvez apprécier avec le schéma ci-dessous le résultat de cet effort de réduction :

image

25 fois plus petit qu’un Windows Server classique,  et avec une image Docker 10 fois plus petite que Windows Server Core, Windows Nano Server est l’édition indispensable pour bénéficier d’une empreinte la plus petite possible.

Ces deux images sont disponibles comme beaucoup d’autres images sur le hub de docker. Docker Hub est une bibliothèque d’images Docker, les plus grandes sociétés et éditeurs mettent à disposition leurs images Docker directement sur ce service qui permet d’héberger des images publiques mais également privées.

Il est important de noter que des images de base contenant uniquement des OS sont disponibles mais également des images contenant des frameworks applicatifs déjà installés. Il n’est donc pas nécessaire de se baser sur une image “nue”, le plus simple est de partir sur l’image correspondant le plus à votre besoin.

Le choix entre Windows Server Core et Windows Nano Server va essentiellement se faire en fonction de l’applicatif que vous souhaitez conteneuriser. Les deux éditions sont effet loin d’être iso-fonctionnelles et vous devrez faire votre choix en fonction des dépendances de votre application.

Ainsi si vous souhaitez déployer une application ASP.net WebForms ou MVC et donc basée sur le framework .net classique, vous devrez impérativement utiliser Windows Server Core car le framework .net n’est pas supporté sur Nano Server.

A contrario, si vous déployez une application ASP.net Core, Windows Nano Server, plus léger sera probablement votre choix de prédilection.

D’un point de vue Licensing

D’un point de vue Licensing tout est décrit dans le tableau ci-dessous :

image

Comme vous pouvez le voir, il est important de noter la limitation à deux conteneurs Hyper-V en édition standard alors que les conteneurs Windows sont eux, illimités.

Du côté du cloud

Côté cloud, que cela soit sur Microsoft Azure ou sur le cloud d’Amazon, il est pour le moment nécessaire de passer par des offres IaaS et donc d’avoir un host sous forme de VM pour héberger des conteneurs Windows. Les deux fournisseurs fournissent le même type d’image Windows Server 2016 with Containers qui proposent une instance de Windows Server 2016 avec les fonctionnalités de conteneurisation déjà installées et fonctionnelles.

Les services d’hébergement de conteneurs ne peuvent héberger que des conteneurs Linux chez ces deux fournisseurs de cloud.

Une preview privée est en cours sur le service Azure Container Service, et Amazon à annoncé le support des conteneurs Windows d’ici la fin de l’année 2016.

Il va donc falloir patienter un petit peu pour profiter d’un service dédié probablement moins coûteux qu’un service d’IaaS.

 

Rendez-vous pour un prochain post sur Docker afin d’aborder le déploiement d’applications d’ASP.net par la pratique !

Meetup .net Toulouse : Docker sous Windows pour les dév .net le 21 Novembre

Vous êtes développeurs ASP.net WebForms, ASP.net MVC ou ASP.net Core et vous n’avez pas encore trop regardé Docker car vous n’êtes pas intéressé par l’hébergement de vos applications sous Linux ?

Et bien rejoignez-nous pour découvrir l’intégration de Docker au sein de Windows Server 2016 (et de Windows 10 Anniversary Update) !

Que cela soit pour vos applications on-premises ou pour le cloud, nous vous présenterons les containers Windows et les containers Hyper-V, et nous aborderons les avantages de ce type de déploiement : réversibilité, blue/green deployment, etc.

image

Nous verrons comment mettre en place une démarche DevOps avec Visual Studio Team Services.

Le tout sous entièrement sous Windows, avec les technos .net que vous utilisez !

S’inscrire au meetup du 21 Novembre sur Docker sous Windows : https://www.meetup.com/fr-FR/Meetup-NET-Toulouse/events/234939602/

S’inscrire au groupe meetup .net Toulouse (nous sommes déjà presque une 100 aine !) : https://www.meetup.com/fr-FR/Meetup-NET-Toulouse/

Déploiement automatisé avec TFS 2012 (Partie 1)

Nous avons vu précédemment comment intégrer les modifications de schémas d’une base de données dans un process d’intégration continue, la prochaine étape naturelle après la mise en place d’un processus est d’arriver à automatiser le déploiement d’une application directement depuis une build.

Le principe est simple : arriver à déployer une build en un seul click que cela soit vers un environnement de tests ou un environnement de production.

image

TFSDeployer est un projet CodePlex qui permet de mettre en place cela assez simplement.

Le principe est simple, TFS permet de définir des indicateurs qualité de builds :

image

TFSDeployer permet de s’abonner au changement d’indicateur qualité sur une build et de déclencher un script batch ou un script powershell lors de changement.

Vous pouvez ainsi récupérer toutes les informations nécessaires sur la build en question et lancer votre script de déploiement.

Exemple : Un testeur va sur la fiche de la build qu’il souhaite tester, sélectionne la qualité “Ready for Initial Test”, et automatiquement la build se déploie sur son environnement de tests.

Pour l’installation de TFSDeployer et la préparation des scripts je vous laisse soin de suivre les instructions sur les pages dédiées :

Une fois la solution déployée, il vous faut donc définir votre processus déploiement.

Cela se fait en deux étapes :

  • La définition des déploiement
  • L’écriture de script de déploiement

Mise à jour d’un logiciel client

Commençons par le cas le plus simple, la mise à jour d’un poste client. Pour cela une build spécifique existe nous allons donc créer une définition de déploiement qui permettra de déployer sur une machine de test.

Pour cela créer le fichier xml adéquat (comme indiqué dans la doc) et le placer dans le contrôleur de code source.

Dans mon cas, plusieurs testeurs interviennent sur les différents projets et disposent de leurs propres environnements de tests (machines physiques ou VM).

J’ai donc commencé par créer un indicateur de qualité de build par personne :

image

Le fichier de définition des déploiements a été créé en conséquence :

image

Comme vous pouvez le constater, j’ai opté pour l’utilisation de scripts batch traditionnels et non de scripts Powershell.

J’ai également ajouté un paramètre de script additionnel “ScriptParameter” qui me permet d’indiquer le nom de la machine sur laquelle je souhaite déployer ma build.

Passons maintenant à la création du script en lui-même.

Pour comprendre comment créer des scripts de déploiement et récupérer les différents arguments, rendez-vous dans le dossier Samples de TFSDeployer vous y trouverez toutes les infos nécessaires.

Exemple pour un .bat :

image

Pour la copie vers la machine de tests, il suffit donc de faire une “simple copie” de fichiers à ceci près qu’il faut la faire sur une machine distante.

copy %1*.* C:LoginspaceAdb.net

C:LoginspaceAdb.net étant un chemin fixe d’installation du client WPF.

Pour cela deux possibilités :

  • On créé un partage réseau (ou on utilise un existant du type NomMachineC$ ) et on effectue directement la copie comme ceci.
  • Autre solution plus exotique mais vraiment très intéressante et très puissante : l’utilisation d’un super outil de Sysinternals nommé “PsExec”

PsExec

PsExec est un outil en ligne de commande de SysInternals qui permet de lancer des process sur des machines distantes sans prendre la main dessus :

image

Par exemple, nous sommes capable d’effectuer un ipconfig sur une machine distante nommée “Froggiestation” depuis la machine « Patrice-Tablet” et même de récupérer les résultats de cette exécution via la simple ligne de commande présente ci-dessus.

Nous allons donc utiliser cette technique pour effectuer la copie des fichiers assez simplement :

image

L’exécution de cette ligne de code effectuera la copie de fichiers non pas depuis la machine d’exécution du script mais depuis la machine passée en paramètre dans le script.

Ainsi le « C:LoginspaceAdb.net pourra dynamiquement être celui de la machine “VMDovadisChristine” ou “VMDovadisSandrine” ou autre en fonction des infos définies dans la définition du déploiement.

Une fois ce script fait il faudra le placer dans un fichier “DeployToTestEnvironment.cmd” en source control à côté de cette définition pour automatiquer le lancer lors du changement de la qualité d’une build.

Nous verrons ensuite dans la deuxième partie en quoi psexec peut nous permettre d’aller beaucoup plus loin dans l’automatisation de ces déploiements.

Dans les prochaines parties nous verrons en effet comment déployer les mises à jour de schéma de bases de données,  et comment déployer un service Windows (avec arrêt et démarrage à distance).

Stay tuned !

FeatureFlags : Initial Checkin sur CodePlex

Comme indiqué dans le titre, je viens de faire un premier checkin de mon état d’avancement de la librairie de gestion de FeatureFlags sur CodePlex.

image

Vous pouvez accéder au portail du projet à cette adresse : http://featureflags.codeplex.com

Pour rappel du scope actuel :

  • Création de Feature
  • Gestion de Flip au niveau code ou au niveau UI (WPF uniquement)
  • Persistence de l’état des features dans une base SQL Server

Je vais très prochainement faire une vraie application de démo pour montrer l’utilisation de librairie ainsi que la documentation pour montrer comment étendre le stockage de l’état des features.

Toutes les remarques, idées, critiques sont les bienvenues ! N’hésitez pas à m’en faire part via l’issue tracker du projet directement sur CodePlex.

Librairie FeatureFlags : Choix de conception

Je vous ai parlé il y a peu de l’utilisation des Feature Flags qui est une technique qui facilite la mise en place d’intégration continue, je vous avais alors indiqué que les différentes implémentations disponibles en .net ne me satisfaisait pas.

imageJ’ai donc débuté le développement d’une librairie appelée tout simplement FeatureFlags.

Avant de mettre le code à disposition sur codeplex, je vais donc partager vous les différents choix de design que j’ai effectué.

J’ai opté pour un principe simple afin de faciliter la maintenance des features : je souhaite que l’utilisation du principe soit le plus fortement typé possible afin que l’on puisse agir directement sur les différents emplacements dans le code où une feature est utilisée.

Ainsi toute suppression de feature (car plus utile, par exemple dans le cas d’une activation définitive), doit lever différentes erreurs de compilation afin de forcer le développeur à supprimer tout le code inhérent.

Niveau UI

Mon besoin étant uniquement orienté autour d’applications WPF, je me suis attardé uniquement sur ce type d’intégration.

L’objectif est de pouvoir afficher ou non n’importe quel contrôle WPF en fonction de l’état d’activation d’une fonctionnalité.

Pour une intégration simple et souple, j’ai opté pour l’implémentation d’une custom MarkupExtension.

Cette solution de lier très simplement une propriété Visibility à une Feature et permet également de rester fortement typé. Si la classe de définiton de la feature est supprimée, nous nous retrouverons avec une erreur de compilation XAML facilement détectable.

image

A noter la possibilité d’afficher des contrôles en fonction de la non activation d’une feature via la définition de la propriété IsEnabled (définie à True par défaut) :

image

D’un point de vue du rafraichissement, j’ai opté pour une récupération de l’état d’activation de la feature en “One Time” uniquement au moment de la récupération de la MarkupExtension. Cela signifie que si l’état d’activation change alors que la fenêtre parent est déjà chargé, l’UI ne sera pas impactée.

Niveau Code

D’un point de vue code, le flip se fait de manière très simple :

image

Je viendrais dans un prochain post sur la gestion de la persistence de l’état des features en base de données.

N’hésitez pas à me faire part de vos remarques sur ce design par rapport aux autres libraires du marché.

Gestion des évolutions grâce aux Feature Flags

Gérer correctement les évolutions dans un projet logiciel n’est pas simple car il faut arriver à gérer le cycle des releases qui en général est beaucoup plus rapide que le rythme de mise à disposition de certaines fonctionnalités qui prennent du temps à être développé.

Il est donc souvent nécessaire de mettre en place certains mécanismes permettant d’arriver à livrer très régulièrement une application “malgré” des développements en cours non finalisés.

Première principe et le plus populaire :

La mise en place de branching

Quelle que soit la stratégie de branching choisie (branche corrective + branche évolutive, branches par version, ou branches par fonctionnalité – je vous recommande d’ailleurs ce guide sur les différentes stratégies de branching que l’on peut mettre en place –), la mise en place de branches ajoute une surcharge de travail qui est gérable mais qui peut être conséquente.

Il y a bien évidemment la surcharge de travail pour les développeurs au niveau des merges entre les différentes branches, mais également une surcharge de travail d’un point de vue des tests.

Il est en effet nécessaire d’effectuer des tests sur la branche sur laquelle le développement a été effectué, mais également sur toutes les autres branches sur lesquelles les modifications vont être fusionnées.

Il s’agit donc d’une technique qui peut avoir un impact sur la vélocité des releases, sur le rythme de mise à disposition de nouvelles fonctionnalités.

Les feature flags

Autre principe plus léger à mettre en place : les feature flags.

imageLe principe est simple : afin d’être capable de gérer les évolutions, il suffit de développer les fonctionnalités et de les livrer même non finalisés dans les différentes releases mais de les désactiver afin de les rendre inacessibles aux utilisateurs.

Il suffira ensuite de les activer ou non directement au runtime par configuration, sans aucune modification de code et donc sans aucun déploiement lorsqu’on le souhaitera.

 

 

Plusieurs avantages à ce principe :

  • On ne ralentit pas la cadence des releases puisqu’on livre les fonctionnalités non terminées (qui resteront masquées)
  • On peut activer ou non certains certains fonctionnalités en fonction des différents clients (selon leur profil par exemple) afin de les faire participer à des phases de tests (alpha, beta, etc.)
  • On n’est capable de revenir en arrière en cas de problème car en général les feature flags doivent pouvoir être accompagnées de logique de rollback

Ce concept a été mis en place et mis en avant par les équipes de Flickr. Je vous invite d’ailleurs à consulter le post de fin 2009 présentant le principe et son application au site web flickr.

Le principe a été ensuite décrit par Martin Fowler via le pattern Feature Toggle.

Il existe différentes implémentations des feature flags dans l’ecosystème .net : FeatureSwitcher, FeatureToggle, NFeature

La plupart des librairies reposent sur le même principe : on active ou désactive les features de l’application en passant par le fichier de configuration de l’application.

D’un point de vue de la représentation des features au niveau du code, la plupart se basent sur des classes implémentant une interface ou une classe de base, ou alors via une Enum qui permet de lister celles-ci.

N’aimant pas particulièrement les fichiers de configuration (ils sont trop compliqués à maintenir, à faire évoluer), je vais bientôt revenir vers vous avec une nouvelle libraire permettant de gérer cela directement en base de données.

Stay tuned !

VM de démo d’un scénario DevOps avec TFS et SCOM

Brian Keller a publié le mois dernier une VM vous permettant de tester le scénario DevOps proposé par Miccrosoft grâce à TFS et SCOM : http://blogs.msdn.com/b/briankel/archive/2013/02/07/team-foundation-server-2012-and-system-center-2012-operations-manager-integration-virtual-machine-and-hands-on-lab-demo-script.aspx

L’idée est simple et l’implémentation prometteuse : votre service IT monitore le bon fonctionnement de vos applications grâce à System Center Operations Manager (SCOM) et lors d’un incident, il a la possibilité (en cas de détection d’un potentiel bug et non d’un incident d’exploitation) de créer un Work Item de type Operational Issue dans TFS.

Ce WI peut ensuite être traité par le service développement efficacement car il peut contenir les informations liées à une exception mais également un fichier de trace IntelliTrace plus ou moins riche en fonction du fait que l’IT ait activé ou non la collecte directement depuis SCOM.

Un scénarion de communication entre IT et Dév très intéressant que vous pouvez consulter via cette démonstration :

image

ou via la VM de démonstration proposée dans le post indiqué ci-dessus. Attention, il vous faudra un “monstre” pour être capable de la faire fonctionner correctement. La VM est en effet un contrôleur de domaine avec TFS, Sharepoint, SQL Server, SCOM, Visual Studio d’installé, il vous faudra donc au bas mot 12Go de RAM de disponible et un disque dur bien rapide pour la faire fonctionner dans des conditions acceptables.