Bonne résolution : Prendre soin de son cluster Service Fabric

JANV23

Pour ceux qui ne connaissent pas Service Fabric, il s’agit d’un produit fourni par Microsoft qui permet de mettre en place des architectures micro-services basées soit sur des “Guest Exe”, des containers ou des “reliable service” qui sont dans ce cas présent, des applications développées avec un SDK fourni par l’éditeur.


Ceux qui ont déjà testé Service Fabric dans un cadre projet ont pu voir qu’il est assez magique et rapide de mettre en place des solutions qui fonctionnent toutes seules. Par toutes seules, je veux bien entendu parler de toutes les fonctionnalités “automagiques” qu’offre Service Fabric, comme la répartition automatique des micro-services au sein du cluster, l’auto-healing du cluster, ou encore la gestion des données des différents services stateful.


Maintenant rien n’est vraiment magique si on creuse vraiment comment cela marche, mais ce n’est pas le but de cet article, nous allons voir comment faire en sorte de bien prendre soin de son cluster pour qu’il n’arrive rien d’irrémédiable à celui-ci. Et quand je veux dire rien d’irrémédiable, je parle du moment où vous vous dîtes : “Autant créer un nouveau cluster et rattraper mes données, car l’actuel est bon pour la casse”, bon après vous me direz que cette méthode marche et elle a souvent été éprouvée, mais bon ça n’arrive jamais au bon moment.


Laissez lui de l’air pour que votre cluster s’épanouisse :

A part le fait que cette phrase marche aussi avec un adolescent, il est nécessaire de laisser de l’espace disque sur les différents nœuds de votre cluster pour qu’il puisse effectuer ses opérations sans aucun soucis. Alors grand scoop, Service Fabric a beau être présenté comme du PaaS sur Azure, derrière, vous allez monter un cluster de Virtual Machine Scale Set (moi j’appelle ça du IaaS), le côté PaaS offert par Azure sur votre cluster SF concerne surtout les updates des versions de Service Fabric, les autres fonctionnalités qui sont présentées avec le produit sont les mêmes pour un cluster on premise ou créer à la main sur des Virtual Machine Azure ou AWS ou autre ... Donc ce cluster Scale Set, il faut le bichonner c’est grâce à lui que votre Service Fabric fonctionne, un des éléments à prendre en compte c’est l’espace disque disponible pour vos applications.

Bon vous me direz un disque dur ça ne se remplit pas tout seul, et bien je suis d’accord, tout dépend de votre utilisation de votre cluster. Si on exclu les erreurs courantes d’occupation d’espace disque, comme la génération de fichiers de logs sur le disque local sans mettre en place de politique de purge. Service Fabric peut utiliser l’espace disque pour stocker l’état des services stateful que ce soit vos acteurs ou vos “reliable service”, donc si vous ne supprimez jamais les données locales, il est possible de ne plus avoir d’espace disque si vous avez des acteurs qui gèrent beaucoup de données en disque.

Pour éviter ce problème, il est possible de faire les actions suivantes :

- Supprimer vos acteurs qui ne sont plus utilisés, par exemple ceux qui font des actions temporaires dans un traitement

- Mettre en place une politique de stockage à double niveau, à la fois basée sur le cluster, puis un déchargement sur un Blob Storage (ou autre).

- Mettre en place des alertes sur l’espace disque utilisé afin d’éviter les mauvaises surprises le jour où cela pose problème.


Les disques à monitorer dépendent de l’installation de votre cluster, si vous êtes passé par un template ARM comme celui disponible sur le GitHub de Microsoft (https://github.com/Azure/azure-quickstart-templates/blob/master/service-fabric-secure-cluster-5-node-1-nodetype/azuredeploy.json), vous pouvez voir qu’il y a une propriété nodeDataDrive qui vous permet de positionner les données de votre cluster sur le disque OS ou sur le disque Temp. A noter qu’il est possible de mettre vos données sur le disque Temp sans risque majeur si vos applications sont bien conçues elles sont redondées sur différents nœuds du cluster.


Dans l’hypothèse ou il est trop tard, et que votre cluster est chargé de beaucoup de données, il est parfois possible de supprimer des applications via les API Service Fabric. Cependant, cette opération ne marche pas toujours si votre cluster est vraiment plein. La dernière chance est souvent celle de se connecter au cluster via RDP (ou SSH si c’est un cluster Linux) et de supprimer les dossiers contenant les données liées à la persistance de vos services. J’espère par ailleurs que vous n’arriverez pas à cette solution ultime et brutale.


Les clusters adoptent une démarche démocratique :

Si vous vous êtes intéressé un peu à la notion de cluster, notamment celui de Service Fabric, vous devez savoir qu’il y des nœuds et des composants qu’on ne peut pas supprimer sans y prendre une attention toute particulière. Au sein de Service Fabric, il y a une notion de “Seed Node” que ce soit on-premise ou sur Azure, ces nœuds particuliers hébergent entre autre les applications systèmes servant au bon fonctionnement du cluster, il est donc fortement conseillé de faire en sorte que ces nœuds soient toujours opérationnels. Vous allez me dire que vu que c’est du Service Fabric managé, et que c’est automagique, vous n’avez rien à craindre pour ces nœuds. Et bien non, ce n’est pas le cas, derrière votre cluster il y a un cluster de Virtual Machine Scale Set, et la mauvaise nouvelle c’est que vous y avez accès, donc c’est à vous de le manager et de s’assurer qu’il se porte bien. Vous pouvez voir la liste de vos “Seed Node” dans le cluster manifest, comme on peut le voir ci dessous :

image


A noter que le XML de déclaration de l’infrastructure change entre un cluster “on premise” et un cluster Azure. De même selon le niveau de durabilité de votre cluster, le nombre de vos seed nodes est différents.


Alors je parle de démocratie, puisque toute opération d’infrastructure doit être votée par l’ensemble du chorum que forme l’ensemble de ses Seed Nodes. Un cas concret, si par exemple vous avez perdu un de vos seeds node, et que vous souhaitez mettre à jour votre cluster, celle-ci ne se fera pas.


Alors ce cas là arrive uniquement quand vous faites les opérations suivantes :

- Supprimer un nœud de votre cluster ScaleSet (oui la ressource n’est pas verrouillée par Service Fabric)

- Scale Up / Scale down, il est possible que les nœuds du chorum soient supprimés

- Créer votre cluster Scale Set avec le paramètre overProvision à true, dans ce cas précis lors de la création il crée plus de serveurs que nécessaire, et après il supprime ceux qu’il juge en trop, donc peut être vos nœuds de chorum

- Maltraiter les fichiers Service Fabric situés sur votre cluster, bon là ça devient intentionnel....


Si par hasard, c’est trop tard et que vos “Seed Nodes” sont cassés, vous pouvez envoyer un mail au support Microsoft Azure qui vous dira quasiment à chaque fois qu’il faut recréer votre cluster, ce qui peut être problématique dans le cas où vous vous êtes basé sur un cluster appartenant à un Virtual Network un peu petit et ayant des contraintes d’adressage IP, comme pour un cluster privé.


Pour éviter cela, c’est très simple, il suffit soit de faire grandement attention lorsque vous touchez l’infrastructure sous jacente à votre cluster. Il est possible de totalement protéger votre cluster Scale Set Service Fabric si vous prenez la peine de créer 2 types de nœuds lors de la création de votre cluster, le premier type contiendra les services “systèmes” et le deuxième vos services applicatifs, il faudra bien entendu prendre ceci en compte lors de vos déploiements.


Via le portail Azure, lorsque vous créer votre cluster, vous pouvez faire comme cela :


image


Il est bien entendu possible de faire tout cela en ARM (car après tout qui déploie des ressources Azure depuis le portail Azure ....) Bref à la création, vous aurez 2 clusters Scale Set, à vous de mettre des droits restreints sur le scale set sysnode dans mon cas, et pour preuve :


image

Si vous creusez un peu plus le cluster, vous pourrez voir que les applications systèmes sont toutes dans le scale set “sysnode” à l’exception du DnsService qui est présent sur tous les nœuds.


Bref prenez soin de vos clusters avant que les problèmes surviennent, car ils n’arrivent jamais au bon moment et les résolutions sont soit pas simples à mettre en œuvre, soit assez destructives pour le cluster.


Remonter

Tips : Création d’Azure Virtual Network via les templates ARM

DÉCE22


Il existe de multiples manières de créer des ressources sur la plateforme Azure, je ne dirais pas qu’il y en a de meilleures que d’autres, elles ont chacune leurs avantages et leurs inconvénients. Pour rappel, pour créer des ressources sur Azure, vous avez la possibilité de le faire d’une des manières suivantes :

  • Via le portail Azure qui a le mérite d’être simple à utiliser et correspond très bien au besoin si vous souhaitez mettre en place une ressource Azure pour la première fois, ou pour créer une ressource à des vues de tests. Par contre, c’est peu automatisable, et je ne conseille pas de se dire “hey si je faisais ma création de ressources via un test ui automatisé”
  • Via la CLI ou du powershell qui ont le mérite de pouvoir être jouer de manière automatisée et qui permettent de créer rapidement des ressources via du code, cependant il va falloir prendre en compte les comportements lorsqu’une ressource existe déjà. Et bien entendu la méthode “je supprime si la ressource existe” puis je recrée a quelques limites.
  • Via les REST API Azure sont certes très puissantes, mais il y a du code à écrire, à maintenir, et on retrouve les mêmes désavantages qu’avec une ligne de commande.
  • Via des templates ARM qui sont en réalité une surcouche aux REST API Azure vont vous permettre de décrire votre architecture via un “simple” modèle JSON. Par ailleurs, ils gèrent nativement les ressources existantes en apportant les modifications si besoin, donc pas de soucis à se faire là dessus. Cependant ces templates sont plutôt verbeux, ce qui ne facilite pas toujours leur adoption, de plus ils ont quelques limites que nous ne verrons pas dans cet article.


Si je prends comme exemple la création d’un Virtual Network, si je veux le créer via un template ARM, soit j’exporte un template ARM depuis un VNET existant sur Azure, soit je pars d’une feuille blanche, soit je vais voir ce magnifique repo GIT de Microsoft : https://github.com/Azure/azure-quickstart-templates. Il a pour avantage de contenir toute sorte de template pour à peu près toutes les ressources Azure disponible.

Après avoir trouvé le template que je souhaite, je peux le prendre et m’en inspirer pour faire un template avec mes paramètres souhaités et divers autres changements, je vais donc avoir quelque chose de ce type :

{
     "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
     "contentVersion": "1.0.0.0",
     "parameters": {
         "vnetName": {
             "type":"string",
             "defaultValue": "demo-vnet",
             "metadata": {
                 "description" : "Virtual network name"
             }
         },
         "vnetAddressPrefix": {
             "type": "string",
             "defaultValue": "16.0.0.0/16",
             "metadata": {
                 "description": "Address prefix"
             }
         },
         "subnet1Name": {
             "type": "string",
             "defaultValue": "Front",
             "metadata": {
                 "description": "Subnet name"               
             }
         },
         "subnet1Prefix": {
             "type": "string",
             "defaultValue": "16.0.1.0/24",
             "metadata": {
                 "description": "subnet 1 prefix"
             }
         },
         "subnet2Name": {
             "type": "string",
             "defaultValue": "Back",
             "metadata": {
                 "description": "Subnet name"               
             }
         },
         "subnet2Prefix": {
             "type": "string",
             "defaultValue": "16.0.3.0/24",
             "metadata": {
                 "description": "subnet 2 prefix"
             }
         }
     },
     "variables": {
         "vnetName":"[parameters('vnetName')]",
         "vnetAddressPrefix": "[parameters('vnetAddressPrefix')]",
         "subnet1Name": "[parameters('subnet1Name')]",
         "subnet1Prefix": "[parameters('subnet1Prefix')]",
         "subnet2Name": "[parameters('subnet2Name')]",
         "subnet2Prefix": "[parameters('subnet2Prefix')]"
     },
     "resources": [
         {
             "apiVersion": "2015-06-15",
             "type": "Microsoft.Network/virtualNetworks",
             "name": "[variables('vnetName')]",
             "location": "[resourceGroup().location]",
             "properties": {
               "addressSpace": {
                 "addressPrefixes": [
                   "[variables('vnetAddressPrefix')]"
                 ]
               },
               "subnets":[
                   {
                       "name": "[variables('subnet1Name')]",
                       "properties":{
                           "addressPrefix": "[variables('subnet1Prefix')]"
                       }
                   },
                   {
                     "name": "[variables('subnet2Name')]",
                     "properties":{
                         "addressPrefix": "[variables('subnet2Prefix')]"
                     }
                 }
               ]
             }
         }
     ],
     "outputs": {
        
     }
}

Bon, comme on peut le voir, c'est plutôt verbeux... Mais pour moi là n’est pas le problème, c’est que pour rajouter un subnet à notre VNET, il faut soit passer par un autre template ARM qui ajoute des subnets, ce qui est plutôt compliqué pour les rejouer si on a ajouté 3/4 subnets entre le temps de création du VNET et la nouvelle exécution de ce template sur une autre souscription. Pour parer cela, il est possible d’utiliser des objets complexes, et des fonctions intégrées aux templates ARM, tel que la copy. Cela nous donnerait donc ce script si je l’applique sur le même principe :

{
     "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
     "contentVersion": "1.0.0.0",
     "parameters": {
         "vnetName": {
             "type":"string",
             "defaultValue": "demo-vnet",
             "metadata": {
                 "description" : "Virtual network name"
             }
         },
         "vnetAddressPrefix": {
             "type": "string",
             "defaultValue": "16.0.0.0/16",
             "metadata": {
                 "description": "Address prefix"
             }
         },
         "subnets":{
             "type": "array",
             "defaultValue": [
                 {
                     "Name": "Front",
                     "Prefix": "16.0.1.0/24"
                 },
                 {
                     "Name": "Middle",
                     "Prefix": "16.0.2.0/24"
                 },
                 {
                     "Name": "Back",
                     "Prefix": "16.0.3.0/24"
                 }
             ],
             "metadata": {
                 "description" : "Subnets list to create"
             }
         }
     },
     "variables": {
         "vnetName":"[parameters('vnetName')]",
         "vnetAddressPrefix": "[parameters('vnetAddressPrefix')]",
         "subnets": "[parameters('subnets')]"
     },
     "resources": [
         {
             "apiVersion": "2015-06-15",
             "type": "Microsoft.Network/virtualNetworks",
             "name": "[variables('vnetName')]",
             "location": "[resourceGroup().location]",
             "properties": {
               "addressSpace": {
                 "addressPrefixes": [
                   "[variables('vnetAddressPrefix')]"
                 ]
               },
               "copy": [
                   {
                       "name": "subnets",
                       "count": "[length(variables('subnets'))]",
                       "input": {
                           "name": "[variables('subnets')[copyIndex('subnets')].Name]",
                           "properties": {
                               "addressPrefix": "[variables('subnets')[copyIndex('subnets')].Prefix]"
                           }
                       }
                   }
               ]
             }
         }
     ],
     "outputs": {
        
     }
}

Alors, effectivement en terme de verbosité on ne gagne pas tant de ligne que cela, mais on a l’avantage de garder toujours le même template pour modifier notre VNET et y ajouter différents subnets.

Et sans oublier le lien des templates ARM, si vous le voulez pas copier coller  : https://github.com/wilfriedwoivre/demo-blog/tree/master/ARM/Tips%20VNET%20creation


Remonter

Trucs et astuces avec Windows Azure Table Storage

MAI10

En ce vendredi quasiment férié…. je vous donne une petite astuce pour valider vos connexion avec le Table Storage.

 

Bon je suppose que vous connaissez tous la classe CloudStorageAccount, vu que le Table Storage c’est la vie. En ce moment je travaille beaucoup sur des outils génériques autour du Table Storage pour changer. J’ai donc une problématique, je dois valider que la chaine de connexion saisie par l’utilisateur est bien valide.

 

Alors pour rappel, il est possible de créer une instance de CloudStorageAccount de deux façons :

string accountKey = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
string accountName = "azertyqsdfgh";

var csa = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true);
var csa2 = CloudStorageAccount.Parse(string.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}", accountKey, accountName));

 

Le problème, c’est qu’avec cette méthode il est tout à fait possible de créer un CloudStorageAccount, mais cela ne nous dit pas s’il correspond à un vrai storage derrière, ce qui peut être problématique dans de nombreux cas.

Alors tant que Microsoft ne nous fournit pas une méthode simple de validation, il faut tout simplement réaliser une requête vers notre storage afin de savoir qu’il y a bien quelque chose derrière. Je vous conseille de faire un test non intrusif, donc par exemple lister les tables, les blobs ou les queues, mais en aucun cas créer un élément de “test” afin de voir que cela répond bien.

Et vu que je suis un grand seigneur aujourd’hui (comme tous les jours) je vous fournis ma méthode d’extension qui fait cela.

 

public static bool ValidateStorageAccount(this CloudStorageAccount storageAccount)
{
    if (storageAccount == null) throw new  ArgumentNullException("storageAccount");

    var tableClient = storageAccount.CreateCloudTableClient();
    try
    {
        tableClient.ListTablesSegmented(string.Empty, 1, null);
    }
    catch(StorageException ex)
    {
        return false;
    }

    return true;
}

 

A noter, que si c’est la clé du storage qui est mauvaise, j’ai une erreur 403, et si c’est le storage qui n’existe, c’est plus long déjà lors de l’execution, et je récupère une erreur comme quoi l’url est introuvable.

Et pour finir, je vous donne un lien vers un super article qui parle du Table Storage  :  Windows Azure Table Storage 2.0 Qu’est ce qui a changé ? écrit par moi.


Remonter

Windows Azure Global Bootcamp

AVRI24

Comme vous avez pu le remarquer, je ne blog plus trop sur mon blog personnel en ce moment, mais beaucoup plus sur celui de Soat, n’hésitez pas à y faire un tour, ça parle beaucoup de Windows Azure : http://blog.soat.fr

 

De plus je ne reste pas inactif, je suis toujours avec la communauté ZeCloud pour parler d’Azure ! Et d’ailleurs, ce samedi 27 avril, nous organisons la version parisienne du Global Windows Azure Bootcamp.

 

bootcamp

 

Cela se déroulera dans les locaux de Spark de 10h à 18h30, au programme il y aura du fun, de la bonne ambiance, des sessions de qualité, et surtout beaucoup d’Azure! Bref une journée comme je les aime!

Il n’est pas encore trop tard pour vous inscrire, il reste quelques places : http://bit.ly/GWABParis


Remonter

Installer un serveur Minecraft sur Windows Azure

JANV8

Et oui Windows Azure ne sert pas qu’à travailler, il est aussi possible de s’en servir comme d’un serveur personnel !

Je vais vous montrer comment installer un serveur Minecraft sur Windows Azure avec le mode IAAS qu’il faut donc au préalable activer, mais maintenant je pense que c’est fait pour tout le monde !

Donc au cas où ce ne soit pas le cas, il vous faut vous rendre à l’url : https://account.windowsazure.com/PreviewFeatures 

Et activer la fonctionnalité des machines virtuelles :

image

Ensuite, dans le portail, vous allez installer une machine Linux via la gallerie ! Car c’est bien connu que la JVM tourne mieux sous linux ! Et puis ce n’est pas parce que l’on est sur Azure qu’il faut choisir que des solutions Microsoft !

image

Il faut ensuite la configurer, notamment définir le mot de passe administraeur, et la taille de la machine virtuelle, surtout si vous voulez inviter plein de personne pour jouer avec vous !

 

image

 

Maintenant que vous avez votre linux, vous pouvez installer votre serveur Minecraft, pour cela, il faut vous connecter en SSH à votre instance grâce à PuTTy par exemple

image

 

Premièrement il vous faut installer Java pour installer le server, pour cela il faut executer ces trois requêtes linux :

sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java7-installer

Par la suite, vous pouvez installer votre serveur Minecraft d’abord en téléchargeant le fichier du jeu comme ceci :

wget https://s3.amazonaws.com/MinecraftDownload/launcher/minecraft_server.jar

Puis en créant un script RunMinecraft.sh par exemple pour lancer votre serveur, ce script contiendra les lignes suivantes :

#!/bin/sh
java -Xmx512M -Xms512M -jar ./minecraft_server.jar nogui

Vous rendez votre script executable

chmod +x RunMinecraft.sh

Et vous le démarrer !!

 

Ce n’est pas fini, dans le portail Azure il vous faut router le port utilisé pour le jeu vers l’extérieur, pour cela il faut aller dans Endpoint, et y ajouter dans votre point de terminaison comme ci-dessous :

 

image

 

Et voilà, vous pouvez lancer Minecraft, et y ajouter votre serveur Azure !!

 

image

 

Et voilà, pour conclure, c’était juste une étape amusante, et on voit bien qu’Azure peut faire tourner un peu n’importe quoi ! Même un serveur Minecraft !


Remonter

© Wilfried Woivré, tous droits réservés février 2018