<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Thomas Rannou</title>
    <description>The latest articles on DEV Community by Thomas Rannou (@thomasrannou).</description>
    <link>https://dev.to/thomasrannou</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F380073%2F83382b30-0fa7-42c3-a699-a2e84544eab9.png</url>
      <title>DEV Community: Thomas Rannou</title>
      <link>https://dev.to/thomasrannou</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thomasrannou"/>
    <language>en</language>
    <item>
      <title>L'automatisation dans Azure Kubernetes Services avec Azure DevOps</title>
      <dc:creator>Thomas Rannou</dc:creator>
      <pubDate>Wed, 10 Feb 2021 14:42:40 +0000</pubDate>
      <link>https://dev.to/thomasrannou/l-automatisation-dans-azure-kubernetes-services-avec-azure-devops-26g2</link>
      <guid>https://dev.to/thomasrannou/l-automatisation-dans-azure-kubernetes-services-avec-azure-devops-26g2</guid>
      <description>&lt;p&gt;Dans cet article nous allons parler d’industrialisation avec un cluster &lt;a href="https://thomasrannou.azurewebsites.net/2019/07/10/introduction-a-azure-kubernetes-service/" rel="noopener noreferrer"&gt;Azure Kubernetes Services&lt;/a&gt;. Nous verrons comment :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatiser le déploiement d'un cluster avec Terraform&lt;/li&gt;
&lt;li&gt;Automatiser le déploiement d’une application dans ce même cluster.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's go.&lt;/p&gt;

&lt;h1&gt;
  
  
  Automatiser le déploiement d’un AKS avec Terraform et Azure DevOps !
&lt;/h1&gt;

&lt;p&gt;Dans cette première partie, je vous propose de configurer un pipeline Azure DevOps pour exécuter un script Terraform afin de provisionner un cluster Azure Kubernetes Services (AKS) !&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvf07y491akl0zgpuu42e.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvf07y491akl0zgpuu42e.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Terraform
&lt;/h2&gt;

&lt;p&gt;Terraform est un outil d’Infrastructure As Code qui permet de décrire les ressources (VM, VNet, Web App, cluster Kubernetes, base de données) à provisionner dans un environnement auquel on se connecte au moyen d’un provider.&lt;/p&gt;

&lt;p&gt;Il peut s’agir d’un environnement Cloud comme Azure, AWS, GCP ou un environnement on premise virtualisé avec VMWare par exemple. L’infrastructure est décrite grâce au langage de configuration HCL (Hashicorp Configuration Language).&lt;/p&gt;

&lt;p&gt;Pour une approche globale de &lt;a href="https://thomasrannou.azurewebsites.net/2020/04/16/terraform-pour-azure/" rel="noopener noreferrer"&gt;Terraform&lt;/a&gt; avec Azure je vous renvoie à cette très bonne &lt;a href="https://www.youtube.com/watch?v=2Bh4NfLCslw" rel="noopener noreferrer"&gt;vidéo&lt;/a&gt; (et sa &lt;a href="https://www.youtube.com/watch?v=YJsfVS6BZB4" rel="noopener noreferrer"&gt;suite&lt;/a&gt;) réalisée par &lt;a href="https://stanislas.io" rel="noopener noreferrer"&gt;Stanislas Quastana&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Azure DevOps
&lt;/h2&gt;

&lt;p&gt;Les élements présentés ici sont tous disponible dans ce répo &lt;a href="https://github.com/thomasrannou/TerraformAKS" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Importer les fichiers
&lt;/h3&gt;

&lt;p&gt;Dans mon projet Azure DevOps fraichement &lt;a href="https://www.youtube.com/watch?v=IJrs_eIGNX8" rel="noopener noreferrer"&gt;créé&lt;/a&gt;, onglet Repos j’importe les 6 fichiers disponibles :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fawrh8pha5nhts1zahwwo.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fawrh8pha5nhts1zahwwo.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nous avons à disposition les fichiers suivants :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;outputs.tf : permet de spécifier les informations renvoyées par Terraform à l’issu du déploiement&lt;/li&gt;
&lt;li&gt;provider.tf : spécifie le provider cible : ici azurerm, permettra à Terraform de comprendre qu’il cible un déploiement dans le cloud Microsoft&lt;/li&gt;
&lt;li&gt;variables.tf : la définition des variables utilisées dans le script&lt;/li&gt;
&lt;li&gt;variables.tfvars : l’affectation de ces même variables&lt;/li&gt;
&lt;li&gt;main.tf : le script Terraform en lui-même&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Voyons maintenant les parties importantes de ces scripts pour notre automatisation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Les variables
&lt;/h3&gt;

&lt;p&gt;Dans le fichier .tfvars nous avons ceci :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2766rnyk1eb7ic9680bn.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2766rnyk1eb7ic9680bn.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On set les variables avec des valeurs assez abstraites pour le moment, ces variables seront renseignées à l’exécution du pipeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  Le main.tf
&lt;/h3&gt;

&lt;p&gt;Ce script contient un certain nombre de choses.&lt;br&gt;
La description du Backend pour le stockage du tfstate :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftlwfd1nrnr4nz0f0m2gd.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftlwfd1nrnr4nz0f0m2gd.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La description du ressource group qui contiendra nos ressources Azure :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqrptdooxd1rp6lxex783.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqrptdooxd1rp6lxex783.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La définition d’un Azure Container Registry :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdykmg2b8fl3926fvrfp5.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdykmg2b8fl3926fvrfp5.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La définition du cluster Azure Kubernetes Services :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1fg3hbc5d3c3nqiu8ku0.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1fg3hbc5d3c3nqiu8ku0.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On remarque dans ce script l’utilisation des variable définies dans le tfvars au moyen de : ${var.nomDeLaVariable} et la relation entre les composants. Par exemple le resource_group_name et la location du cluster référence le resource group précédemment créé.&lt;/p&gt;

&lt;p&gt;On notera également la configuration du &lt;a href="https://thomasrannou.azurewebsites.net/2020/01/28/les-pools-de-noeuds-dans-aks/" rel="noopener noreferrer"&gt;node pool&lt;/a&gt; ou on précise que l’on utilisera des VM de type D2_V2 déployés dans 3 Availability Zone pour un cluster &lt;a href="https://thomasrannou.azurewebsites.net/2020/10/23/gerer-la-haute-disponibilite-dun-cluster-aks/" rel="noopener noreferrer"&gt;hautement disponible&lt;/a&gt;. Ce node pool est déployé en se basant sur le mécanisme Azure des VMSS.&lt;/p&gt;

&lt;p&gt;J’ai également configuré un backend qui cible un Storage Account dans Azure. Cet espace de stockage héberge un conteneur : terraform-azure-kubernetes-tfstate.&lt;br&gt;
Cet espace, je l’ai créé depuis le portail Azure. Il est de type Storage V2 et est en accessibilité publique. Mon conteneur est lui en accessibilité “Objet Blob”. On peut donc accéder à une ressource précise mais il n’est pas possible de lister toutes les ressources présentes dans le conteneur.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp0ofaipf8ashvaa17uoa.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp0ofaipf8ashvaa17uoa.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La documentation complète pour créer un Azure Storage Account est &lt;a href="https://docs.microsoft.com/fr-fr/azure/storage/common/storage-account-create?tabs=azure-portal" rel="noopener noreferrer"&gt;ici&lt;/a&gt; !&lt;/p&gt;
&lt;h3&gt;
  
  
  Service Connection
&lt;/h3&gt;

&lt;p&gt;Avant de créer notre pipeline Azure DevOps nous aller configurer un service connection à notre tenant Azure. Pour cela dans les Project settings sélectionner l’onglet Service Connections.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F956l8apwewkrhsl8cbsx.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F956l8apwewkrhsl8cbsx.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Puis ajouter votre service connection. Vous devrez renseigner les informations suivantes :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdmzdcqrf7rii20jn70x7.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdmzdcqrf7rii20jn70x7.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pour créer un &lt;a href="https://docs.microsoft.com/fr-fr/cli/azure/create-an-azure-service-principal-azure-cli" rel="noopener noreferrer"&gt;service principal&lt;/a&gt; vous pouvez utiliser cette commande dans une fenêtre Powershell ou le shell du portail Azure :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;az&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ad&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;create-for-rbac&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;spTerraformAzDo&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pour obtenir le tenantId et le subscriptionId vous pouvez utiliser cette commande :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;az&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;show&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Le pipeline
&lt;/h3&gt;

&lt;p&gt;Il faut maintenant créer notre Pipeline pour exécuter ce script Terraform. Dans l’onglet Pipeline, choisir New Pipeline :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fa1el7bh0rnvr38dyrw4j.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fa1el7bh0rnvr38dyrw4j.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mon code est ici stocké dans mon repo Azure DevOps mais il pourrait tout à fait être utilisé directement depuis mon repo GitHub.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbejddthdyji1tvj3pqiu.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbejddthdyji1tvj3pqiu.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Je choisis mon repository local :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4adr8diei2xiclrg08y7.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4adr8diei2xiclrg08y7.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ici le pipeline est déjà écrit, il faut donc le réutiliser et sélectionner le fichier yml correspondant, ici nommé sobrement azure-pipelines.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fn1cwmtzi1j86y684bic5.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fn1cwmtzi1j86y684bic5.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Les variables du pipeline
&lt;/h3&gt;

&lt;p&gt;Maintenant que notre pipeline est créé et avant de le détailler et de l’exécuter nous allons lui fournir les variables dont il aura besoin à l’exécution. Pour cela, sélectionner Variables :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh7q5w9qj284vhjyanvlo.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh7q5w9qj284vhjyanvlo.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vous allez devoir créer et valoriser l’ensemble de ces variables :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2rkc3m63bl69v2d7hoos.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2rkc3m63bl69v2d7hoos.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ici vous avez dû remarquer que toutes mes variables déclarées ont le même nom que la valeur affectée à la variable Terraform dans mon fichier tfvars modulo les deux underscores positionnés avant et après le nom :&lt;/p&gt;

&lt;p&gt;aks-cluster-name = __ aks-cluster-name __&lt;/p&gt;

&lt;h2&gt;
  
  
  Le contenu du pipeline
&lt;/h2&gt;

&lt;p&gt;Si on s’intéresse maintenant au pipeline en lui-même on y trouve tout d’abord la copie des fichiers dans un espace de travail temporaire :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwennujgxrtmtke2kc84b.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwennujgxrtmtke2kc84b.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Gestion des variables
&lt;/h3&gt;

&lt;p&gt;Etapes très importante ! Ici nous allons parcourir les fichiers tfvars et provider.tf pour y trouver __ positionnées autour d’un nom de variable. Exemple : __ aks-cluster-name __&lt;br&gt;
Quand on en trouve, on remplace le contenu par la valeur renseignée précédemment dans la variable du pipeline :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxf9w0rew4kp2oa36xl9v.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxf9w0rew4kp2oa36xl9v.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ainsi __ aks-cluster-name __ devient “lenomdemoncluster”.&lt;/p&gt;

&lt;p&gt;On passe ensuite à la récupération de la dernière version de Terraform précisée dans une variable également :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3n6iars884jpy68jmp9i.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3n6iars884jpy68jmp9i.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Il est maintenant temps de voir les 3 étapes nécessaire à Terraform pour déployer mon cluster.&lt;/p&gt;
&lt;h3&gt;
  
  
  Init
&lt;/h3&gt;

&lt;p&gt;Le Init permet de tester la connexion à l’environnement cible, ici ma souscription Azure et mon backend. Ce backend, un storage account Azure, doit, je le rappelle, avoir été créé au préalable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fczjl3osmktpxxf0rimud.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fczjl3osmktpxxf0rimud.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Plan
&lt;/h3&gt;

&lt;p&gt;Le plan permet de comparer le contenu décrit dans le script à son infrastructure actuelle (via le tfstate). Ainsi Terraform obtient une liste d’élément à supprimer / modifier / créer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqiobpljzjuiohix1bdpt.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqiobpljzjuiohix1bdpt.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Apply
&lt;/h3&gt;

&lt;p&gt;L’étape Apply permet de réaliser le déploiement de notre infrastructure sur Azure. Ici aussi j’ai besoin de passer dans commandOptions le nom de mon fichier de variables.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F05xnjo3ii2coteli84jp.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F05xnjo3ii2coteli84jp.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(Une étape Terraform Validate peux être présente entre le Init et le Plan pour valider la sémantique du script Terraform).&lt;/p&gt;

&lt;p&gt;Une fois mon pipeline enregistré, un build démarre :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flpkxxeiok7ckvgjgn68o.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flpkxxeiok7ckvgjgn68o.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Le pipeline est en cours d’exécution :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fi6kyxzwl28u0dfsk8l46.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fi6kyxzwl28u0dfsk8l46.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si vous cliquez sur l’étape Deploy vous obtiendrez les détails de l’exécution du traitement :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxjm79r1opjzmf6st6lmg.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxjm79r1opjzmf6st6lmg.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Une fois l’exécution achevée, vous pourrez vérifier sur le portail Azure le bon déploiement de votre ressource group contenant un Azure Container Registry et un cluster Azure Kubernetes Services :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fln7w6d01ypk2tk1i7tnm.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fln7w6d01ypk2tk1i7tnm.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Une fois le script exécuté Terraform m’affichera en vert toutes les informations demandées en output.&lt;/p&gt;

&lt;p&gt;Vérifions maintenant notre déploiement !&lt;/p&gt;

&lt;p&gt;Je me connecte au cluster via :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Az&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;aks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;get-credentials&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="err"&gt;–&lt;/span&gt;&lt;span class="nx"&gt;resource-group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;rg-aks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;clustervacd&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Et j’exécute la commande ci-dessous pour vérifier que mes nœuds sont bien sur des Availability Zones différentes  :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nodes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;select-string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-pattern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'^Name:'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'zone='&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffed5rm4yhfwjywcdq5z6.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffed5rm4yhfwjywcdq5z6.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dans Azure, si je retourne dans mon espace de stockage je trouve mon fichier tfstate !&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1r45cw1xyme48tnmxwxu.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1r45cw1xyme48tnmxwxu.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4ulzv2mql32egaamkhoc.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4ulzv2mql32egaamkhoc.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Grace à ce state, si je réexécute mon pipeline, il n’y aura pas de redéploiement de mon cluster, puisqu’il existe déjà.&lt;br&gt;
En revanche, si je modifie le node_count dans mon main.tf et que je le positionne à 10 :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffsnlzb370pk847oemgcs.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffsnlzb370pk847oemgcs.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Un build se relance automatiquement et je pourrais trouver dans les logs :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7go2vctl0kvtozy1z4h1.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7go2vctl0kvtozy1z4h1.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ici Terraform a identifié, grace au tfstate, que ma ressource était bien présente (0 to Add) mais qu’il faut la modifier (1 to change).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6k75gzq274lnfw7pe2pm.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6k75gzq274lnfw7pe2pm.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pendant le build, mon node pool se verra appliquer la modification demandée et passera automatiquement de 3 à 10 nœuds :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe2cq4artncqhps3v9wit.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe2cq4artncqhps3v9wit.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Voilà pour cette automatisation du déploiement d’un cluster AKS avec Terraform et Azure DevOps ! Terraform nous a ici permis de décrire un cluster AKS hautement disponible grâce aux Availability Zone.&lt;/p&gt;

&lt;p&gt;On passe maintenant à la configuration d’un pipeline d’intégration / déploiement continu d’une application sur ce cluster fraichement créé !&lt;/p&gt;
&lt;h1&gt;
  
  
  Configurer un pipeline CI/CD Azure DevOps pour déployer dans AKS
&lt;/h1&gt;

&lt;p&gt;Nous allons déployer sur notre cluster AKS une &lt;a href="https://thomasrannou.azurewebsites.net/2020/05/24/templates-pour-deployer-sur-aks/" rel="noopener noreferrer"&gt;application&lt;/a&gt; hébergée sur GitHub toujours grâce à Azure DevOps !&lt;/p&gt;
&lt;h2&gt;
  
  
  Prérequis
&lt;/h2&gt;

&lt;p&gt;Nous avons pour le moment créé :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Un Azure Container Registry pour stocker l’image Docker générée&lt;/li&gt;
&lt;li&gt;Un cluster Azure Kubernetes Services pour hoster mon application&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On peut passer à la partie applicative !&lt;/p&gt;

&lt;p&gt;Je crée, tout d’abord, un nouveau projet Azure DevOps :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frqcah0jmprlbon1iw091.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frqcah0jmprlbon1iw091.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mon code étant hébergé sur GitHub, je peux directement passer à la création du pipeline dans l’onglet Pipeline :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhcuxckotjn2594fckgh6.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhcuxckotjn2594fckgh6.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;J’indique que mon code est sur GitHub, il faudra que vous vous identifiez sur votre compte quand Azure DevOps vous le demandera :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fl9dkgyqi95jn5jbf41jd.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fl9dkgyqi95jn5jbf41jd.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Je choisis le repository  concerné :&lt;br&gt;
&lt;a href="https://github.com/thomasrannou/DemoAppAzDo" rel="noopener noreferrer"&gt;https://github.com/thomasrannou/DemoAppAzDo&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fawgk2gv2rziaa5z9phal.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fawgk2gv2rziaa5z9phal.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cette fois-ci je ne vais pas immédiatement lancer de build (Run). Je choisis donc de sauvegarder mon pipeline en l’état (Save) : &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fckt2vb3yqkssxcm5r6cr.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fckt2vb3yqkssxcm5r6cr.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Avant de l’exécuter, j’ai besoin d’ajouter 2 services connexion à mon projet Azure DevOps, une connexion à mon Container Registry Azure et une seconde à mon cluster AKS. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqag29skudyq9ejavj9v7.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqag29skudyq9ejavj9v7.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cela va se passer dans les “project settings”, onglet “Service Connections”. J’ajoute dans un premier temps une “Docker Registry service connection” que je nomme acr-connexion:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fr2dpahzd71jp7al7y17v.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fr2dpahzd71jp7al7y17v.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vous devez ici choisir votre souscription Azure et le container registry que vous venez de créer précédemment. De même pour établir une connexion avec le cluster AKS (aks-connexion) : &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flqguhykvz1p1rwvp26y6.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flqguhykvz1p1rwvp26y6.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;De retour sur mon pipeline, on peut maintenant ajouter les variables globales (bouton Variables) :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkf9p22hcseof9lqpp4rp.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkf9p22hcseof9lqpp4rp.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;J’ai besoin d’une variable “containerRegistry” avec l’url de ma registry précédemment créée. L’url de votre registry se présente comme ceci : nomdelaregistry suivi de azurecr.io.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fsc9z34if9cpoqe0pwpug.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fsc9z34if9cpoqe0pwpug.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ainsi que le nom de l’image Docker “imageRepository”, ici valorisée comme ceci :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb8zezon04hzestebb0py.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb8zezon04hzestebb0py.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Je peux maintenant exécuter mon pipeline (Run) :  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frxk8r7cy3p9lvw4kx8qe.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frxk8r7cy3p9lvw4kx8qe.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;J’ai un indicateur visuel sur mon déploiement :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjrxjbclka4lftdszj6n7.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjrxjbclka4lftdszj6n7.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Une fois le build terminé, un :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pods&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;m’indique que 5 pods exécutent mon application. Via un :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;services&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;je vois également que celle-ci est accessible via une external-ip : &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fke7yvrg7hqe46tb8um0z.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fke7yvrg7hqe46tb8um0z.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Description du pipeline
&lt;/h3&gt;

&lt;p&gt;On va maintenant passer en revue le pipeline que nous venons d’exécuter pour comprendre comment on en arrive à ce résultat !&lt;/p&gt;

&lt;p&gt;Tout d’abord, on définit les variables de traitement :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Le nom de ma service connexion à mon Container Registry (acr-connexion)&lt;/li&gt;
&lt;li&gt;Le path du dockerfile (présent sur GitHub)&lt;/li&gt;
&lt;li&gt;Un tag automatiquement généré par le build&lt;/li&gt;
&lt;li&gt;Le nom de mon pull secret, nous y reviendrons.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fesr9aalxjz5h01emdc8t.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fesr9aalxjz5h01emdc8t.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Première étape : le push sur ma registry, je dois ici renseigner que je veux effectuer un Docker « build and push » avec en paramètres :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;le nom de mon repository (applicationnetcore)&lt;/li&gt;
&lt;li&gt;le path du Dockerfile de mon projet&lt;/li&gt;
&lt;li&gt;la connexion à utiliser pour atteindre mon registry&lt;/li&gt;
&lt;li&gt;le tag généré précédemment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F11c8p83zp2mow3unmyew.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F11c8p83zp2mow3unmyew.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Déploiement
&lt;/h3&gt;

&lt;p&gt;Le déploiement sur mon cluster Kubernetes sera réalisée grâce aux deux fichiers yml présent dans le dossier manifest de mon repository. On trouve un deployment.yml et un service.yml.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fswi8l7thijjeiif5k1dv.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fswi8l7thijjeiif5k1dv.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En vue de mon installation, je dois modifier (dans mon pipeline) le fichier Deployment.yml pour  valoriser :&lt;br&gt;
image: #{containerRegistry}#/#{imageRepository}#:#{tag}#&lt;/p&gt;

&lt;p&gt;Pour ce faire, je vais utiliser l’instruction replacetokens. Je précise ici que je veux analyser les fichier .yml pour y trouver des chaines de caractère telles que #{texte}# et les remplacer par une valeur concrète renseignée dans les variables du pipeline (globales comme locales, les deux fonctionnent) :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvne8fyoba7sythudg4lx.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvne8fyoba7sythudg4lx.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Après cette étape, le contenu de mon fichier de travail deployment.yml sera par exemple :&lt;/p&gt;

&lt;p&gt;image: registryacrdemo.azurecr.io/applicationnetcore:25&lt;/p&gt;

&lt;p&gt;Kubernetes exige ensuite un secret pour que mon cluster puisse récupérer l’image sur mon container registry : &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh23ybhehwdhh5u55u6zr.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh23ybhehwdhh5u55u6zr.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;J’utilise enfin mes deux fichiers yml pour déployer mon application et un service pour l’exposer sur le port 80.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb1svhm3n57khtqeifz96.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb1svhm3n57khtqeifz96.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Modification du projet
&lt;/h2&gt;

&lt;p&gt;Mon projet déployé ressemble à ceci : &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp6gb2qby0gy17knsll5j.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp6gb2qby0gy17knsll5j.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si  je modifie la page pour ajouter une image, je peux créer une nouvelle branche :  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjdylbk6nd95xgyi81u36.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjdylbk6nd95xgyi81u36.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fr0m3c1h2inpabcqhaqg8.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fr0m3c1h2inpabcqhaqg8.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Et déclencher une pull request : &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F89kzfbre4xim9nefdz4p.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F89kzfbre4xim9nefdz4p.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Qui, une fois validée, va lancer un nouveau build coté Azure DevOps :  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwedk92zztmgfphu839tg.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwedk92zztmgfphu839tg.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Foq1bjgr2fkv4hxk83htk.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Foq1bjgr2fkv4hxk83htk.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mon application se met alors automatiquement à jour via un &lt;a href="https://kubernetes.io/docs/tutorials/kubernetes-basics/update/update-intro/" rel="noopener noreferrer"&gt;rolling update&lt;/a&gt; Kubernetes !  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fivb8lhpymbcbsp17fojo.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fivb8lhpymbcbsp17fojo.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;C'est la fin de cette mise en œuvre de pipeline Azure DevOps pour automatiser la gestion de mon cluster AKS ainsi que le déploiement d’applications !&lt;/p&gt;

&lt;p&gt;J’espère que cet article vous aura été utile !&lt;br&gt;
A bientôt.&lt;/p&gt;

&lt;p&gt;Thomas&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>devops</category>
      <category>azure</category>
    </item>
    <item>
      <title>Azure Kubernetes Services en vidéos</title>
      <dc:creator>Thomas Rannou</dc:creator>
      <pubDate>Sat, 06 Feb 2021 21:19:53 +0000</pubDate>
      <link>https://dev.to/thomasrannou/referentiel-videos-meetup-1418</link>
      <guid>https://dev.to/thomasrannou/referentiel-videos-meetup-1418</guid>
      <description>&lt;p&gt;Bonjour,&lt;/p&gt;

&lt;p&gt;J'ai eu l'occasion de proposer plusieurs talks sur Azure Kubernetes Services, en meetup ou conférence. Les voici agregé dans cet article par ordre d'accessibilité :)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Se simplifier Kubernetes grâce à Azure ? Merci AKS !&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;On ne présente plus Kubernetes, l'orchestrateur de conteneur de Google permet de déployer et mettre à l'échelle facilement nos conteneurs Docker. Azure nous propose avec AKS (Azure Kubernetes Services) une offre managée Kubernetes dans Azure pour faciliter la gestion de notre cluster k8s. Nous verrons dans cette présentation comment mettre en place cette solution pour déployer, manager et monitorer nos applications.&lt;br&gt;
Vidéo : &lt;a href="https://www.youtube.com/watch?v=kUCc_OzCAY0"&gt;ici&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Azure DevOps + Terraform + AKS = une automatisation de bout en bout pour du Kubernetes dans Azure&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Aujourd'hui on aborde l'approche "Everything as Code" ! De l'infra aux apps sans oublier le CI/CD, tout est du code. Au programme : - Définition d'un cluster AKS avec Terraform - Automatisation du déploiement de l'infrastructure et des apps avec des pipelines Azure DevOps.&lt;br&gt;
Vidéo : &lt;a href="https://www.youtube.com/watch?v=cdE3HkhcnQA"&gt;ici&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Tips &amp;amp; Tricks pour de la haute disponibilité avec Azure Kubernetes Services&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Si il y a une seule raison à retenir pour l'utilisation d'un cluster Kubernetes c'est bien pour garantir de la haute disponibilité. En théorie ça peut paraître simple mais en pratique ... Voyons ensemble les différentes stratégies pour garantir de la haute disponibilité au niveau de son infra et de ces applications dans AKS.&lt;br&gt;
Vidéo : &lt;a href="https://www.youtube.com/watch?v=ifrNsn0T8qU"&gt;ici&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Du DevOps multi Cloud avec Kubernetes et Terraform&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Un cluster Kubernetes sur le Cloud c’est bien, mais sur plusieurs Clouds c’est mieux ! Mise en oeuvre, à partir d’un projet .Net Core et de script Terraform, d’un pipeline d’intégration et déploiement continu avec Azure DevOps pour déployer une application dans un cluster Kubernetes sur Azure, AWS et GCP. Ou comment rendre son application et son CI/CD agnostique du clouder utilisé !&lt;br&gt;
Vidéo : &lt;a href="https://www.youtube.com/watch?v=fz6BFSAF_xs"&gt;ici&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;J'espère que ces présentations vous seront utile :)&lt;br&gt;
A bientôt.&lt;/p&gt;

&lt;p&gt;Thomas&lt;/p&gt;

</description>
    </item>
    <item>
      <title>De la haute disponibilité avec Azure Kubernetes Services : le focus Apps !</title>
      <dc:creator>Thomas Rannou</dc:creator>
      <pubDate>Tue, 20 Oct 2020 09:10:01 +0000</pubDate>
      <link>https://dev.to/thomasrannou/de-la-haute-disponibilite-avec-azure-kubernetes-services-le-focus-apps-3l8l</link>
      <guid>https://dev.to/thomasrannou/de-la-haute-disponibilite-avec-azure-kubernetes-services-le-focus-apps-3l8l</guid>
      <description>&lt;p&gt;Après s’être intéressé à la haute disponibilité de notre &lt;a href="https://dev.to/thomasrannou/de-la-haute-disponibilite-avec-azure-kubernetes-services-le-focus-infra-2jdc"&gt;infrastructure&lt;/a&gt;, au menu aujourd'hui : la configuration de la montée en charge automatique sur nos pods et nos nodes.&lt;/p&gt;

&lt;h1&gt;
  
  
  Rappel sur le scaling
&lt;/h1&gt;

&lt;p&gt;Il y a deux possibilités de scale.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---2sHs_dv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9yu9zwnmsbyah024d24y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---2sHs_dv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9yu9zwnmsbyah024d24y.png" alt="Alt Text" width="294" height="172"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Scaling Vertical
&lt;/h2&gt;

&lt;p&gt;Si un traitement dans un pod necessite plus de ressources mémoire ou vCPU que ce que vous avez prévu mais que ce traitement ne peux être réparti sur plusieurs instances, vous devrez allouer plus de ressources à votre pod. On parle alors de scaling vertical.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scaling horizontal
&lt;/h2&gt;

&lt;p&gt;Cette méthode permet de multiplier le nombre d'instance d'une application si l'instance est trop sollicitée afin de repartir la charges.&lt;/p&gt;

&lt;p&gt;Aujourd'hui nous allons nous concentrer sur le scaling horizontal et la façon de l'automatiser.&lt;/p&gt;

&lt;h1&gt;
  
  
  L’autoscaling sur les pods
&lt;/h1&gt;

&lt;p&gt;Le scaling consiste à augmenter ou diminuer le nombre d’instances d’une application. Cela permet par exemple de résister à un pic de charge si votre service est fortement sollicité par moments et très peu le reste du temps. On peut configurer grâce à Kubernetes l’upscale et le downscale pour s’adapter en temps réel aux besoins de nos utilisateurs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Montée en charge manuelle
&lt;/h2&gt;

&lt;p&gt;Avant de rentrer dans le vif du sujet, petite précision sur le scaling : la commande kubectl scale vous permet de modifier instantanément le nombre d’instances dont vous souhaitez disposer pour exécuter votre application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;scale&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--replicas&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;deployment/myApp&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Montée en charge automatique
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Préparation du cluster
&lt;/h3&gt;

&lt;p&gt;Je provisionne un AKS avec le monitoring activé, comme expliqué &lt;a href="http://thomasrannou.azurewebsites.net/2019/10/16/azure-monitor-pour-aks/"&gt;ici&lt;/a&gt; et je vais utiliser un container registry pour déployer mon app comme expliqué dans ce &lt;a href="http://thomasrannou.azurewebsites.net/2019/08/03/deployer-dans-aks"&gt;tuto&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Déploiement de mon application
&lt;/h3&gt;

&lt;p&gt;Voici le yaml que j’ai écrit pour mon application :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9DyMp-dg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mjdthot7hpwchdwkhs8s.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9DyMp-dg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mjdthot7hpwchdwkhs8s.PNG" alt="Alt Text" width="588" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;L’élément qui va nous intéresser aujourd’hui est “ressources” avec la définition des propriétés requests et limits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Requests&lt;/strong&gt;, c’est ce que le pod est garanti d’avoir à sa disposition pour fonctionner. Ici mon container aura donc 100m de CPU et 15Mi de RAM.&lt;br&gt;
&lt;strong&gt;Limits&lt;/strong&gt; en revanche c’est une sécurité sur la consommation de ressources du container. Il ne pourra pas utiliser plus de 500m de CPU et 512Mi de RAM. &lt;/p&gt;

&lt;p&gt;Si le pod consomme trop de ressources :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPU : un mécanisme de &lt;a href="https://medium.com/omio-engineering/cpu-limits-and-aggressive-throttling-in-kubernetes-c5b20bd8a718"&gt;throttling&lt;/a&gt; permet de limiter la charge CPU&lt;/li&gt;
&lt;li&gt;RAM : le pod est détruit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Les valeurs de CPU sont définies en milli-cores. Si vous avez besoin de deux VCPU il faudra indiquer 2000m. La notation “2” sera équivalente.&lt;/p&gt;

&lt;p&gt;Déployons mon application avec un :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Kubectl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;apply&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;–&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;\deploytoaks.yaml&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Ajoutons de l’HPA
&lt;/h3&gt;

&lt;p&gt;La commande kubectl autoscale crée un objet HorizontalPodAutoscaler (HPA) qui cible une ressource spécifiée et la fait évoluer si nécessaire. Le HPA ajuste périodiquement le nombre d’instances dupliquées en fonction de la consommation CPU ou RAM.&lt;/p&gt;

&lt;p&gt;En cas de modification de la charge, cet objet &lt;a href="https://cloud.google.com/kubernetes-engine/docs/how-to/scaling-apps?hl=fr#autoscaling-deployments"&gt;augmente ou réduit&lt;/a&gt; le nombre d’instances de l’application.&lt;/p&gt;

&lt;p&gt;Ici, je vais demander un HPA sur mon application aspwebsitenetcore. Je lui indique de scaler entre 2 et 10 réplicas. L’upscale se fera si le pourcentage CPU consommé dépasse les 10% de ce qui est alloué, ici c’est donc 10% de consommé sur  les 500millicores de CPU.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;autoscale&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;deployment&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;aspwebsitenetcore&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--max&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--min&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--cpu-percent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;10&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VGJKrLwQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kf8ltj3ilq7wrjen2xz2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VGJKrLwQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kf8ltj3ilq7wrjen2xz2.png" alt="Alt Text" width="880" height="95"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Précision : La commande kubectl get hpa me permet d’afficher mes différents scaling mis en place sur mon cluster k8s.&lt;br&gt;
Je constate qu’après la mise en place de mon HPA, j’ai désormais deux pods d’opérationnel ! Les appels vers mon site web seront automatiquement répartis vers ces deux pods via le loadbalancer de Kubernetes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9ythFQfm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/n55u08hz0kahes9mekvi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9ythFQfm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/n55u08hz0kahes9mekvi.png" alt="Alt Text" width="880" height="151"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si je rééxecute un get hpa, je visualise dans la colonne targets ou se situent mes conteneurs par rapport à la limite qu’on leur a fixée :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DeQSyk94--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/v99gb7j311cf8kcs9jyf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DeQSyk94--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/v99gb7j311cf8kcs9jyf.png" alt="Alt Text" width="880" height="85"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Stress Test
&lt;/h3&gt;

&lt;p&gt;Maintenant, je vais stresser un peu mon application et simuler un fort trafic sur mon site. En toute logique, l’autoscaling configuré pour mon cluster AKS doit intervenir et mon nombre de pods devraient se dupliquer. Pour ce faire je vais utiliser &lt;a href="https://github.com/tsenart/vegeta"&gt;Vegeta&lt;/a&gt; !&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vzp80SJJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2stt7t3co4v0emlr7tbb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vzp80SJJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2stt7t3co4v0emlr7tbb.jpg" alt="Alt Text" width="600" height="852"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;L'installation et l'utilisation de l'outil est super simple.&lt;br&gt;
Pour le télécharger, rendez vous &lt;a href="https://github.com/tsenart/vegeta/releases"&gt;ici&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La commande me permet de lancer une "attaque" pendant 5 minutes à raison de 5 appels seconde.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;GET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;http://40.121.84.148&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vegeta.exe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;attack&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-duration&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-rate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;stress-results.bin&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;J'ai spécifié un output qui me permettra ensuite de générer un rapport comme ceci afin de constater la latence induite par mon test de charge.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;vegeta.exe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;plot&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Results&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;stress-results.bin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;stress-results-plot.html&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LDi-NcTH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/w6qihiyav8aeynkjnalc.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LDi-NcTH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/w6qihiyav8aeynkjnalc.PNG" alt="Alt Text" width="880" height="126"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9Q2BmyNf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7b01tp64od0cuo967crm.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9Q2BmyNf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7b01tp64od0cuo967crm.PNG" alt="Alt Text" width="880" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Assez rapidement, des événements m’informent du scale up :&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HiacpRre--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7gzgqmfhpufkqi0a408c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HiacpRre--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7gzgqmfhpufkqi0a408c.png" alt="Alt Text" width="880" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;J’ai maintenant 5 pods d’actif :&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZdnnC-q5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8gd6b3hpb1jnx4atf6e6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZdnnC-q5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8gd6b3hpb1jnx4atf6e6.png" alt="Alt Text" width="880" height="67"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Puis 6 :&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DMuX_sVE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/e3m05xxkz0fcizxg0dcw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DMuX_sVE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/e3m05xxkz0fcizxg0dcw.png" alt="Alt Text" width="880" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quand je stoppe le load, je vais constater l’inverse et voir progressivement mon nombre de pods diminuer :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZmV3CfM_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/59zlv8zh2cx86lnx64a6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZmV3CfM_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/59zlv8zh2cx86lnx64a6.png" alt="Alt Text" width="880" height="113"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Jusqu’à revenir à ma situation initiale :&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PbvOQker--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ijoas1dq6s5q1viptpeg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PbvOQker--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ijoas1dq6s5q1viptpeg.png" alt="Alt Text" width="880" height="66"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mw0SW2YW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/icy4rj7e2ymm99yr5ooi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mw0SW2YW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/icy4rj7e2ymm99yr5ooi.png" alt="Alt Text" width="880" height="170"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pour déterminer à quel moment scale up ou down, Kubernetes utilise un algorithme présenté &lt;a href="https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#algorithm-details"&gt;ici&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Un autoscale déployé via un YAML
&lt;/h3&gt;

&lt;p&gt;Et oui, il est possible de configurer un scaling via une description yaml comme celle-ci :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---U_HO_Fb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kfy56zb6btcmmesidcvf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---U_HO_Fb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kfy56zb6btcmmesidcvf.png" alt="Alt Text" width="442" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Je précise toujours sur quel déploiement je veux positionner mon scaling, un nombre de pod min et max et une condition ici représentée par “targetAverageValue” sur la consommation mémoire de mes conteneurs. Ici la montée en charge sera toujours entre 2 et 10 pods et le scale se fera si on dépasse les 32Mi de mémoire.&lt;/p&gt;
&lt;h3&gt;
  
  
  KEDA
&lt;/h3&gt;

&lt;p&gt;Il est possible de configurer un autoscaling sur des métriques autres que la charge CPU et RAM. Pour se faire je vous invite à vous intéresser à &lt;a href="https://docs.microsoft.com/fr-fr/azure/azure-functions/functions-kubernetes-keda"&gt;KEDA&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XX1a_WIy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3e0abdy3jjr6bq9fyag9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XX1a_WIy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3e0abdy3jjr6bq9fyag9.png" alt="Alt Text" width="880" height="756"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cet outil permet par exemple de configurer un autoscale sur :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Le nombre de message dans une queue Azure Service Bus ou RabbitMQ&lt;/li&gt;
&lt;li&gt;Le nombre de fichiers dans Azure Storage&lt;/li&gt;
&lt;li&gt;Des métriques customs exposées via Prometheus&lt;/li&gt;
&lt;li&gt;et bien d'autres sources !&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;La liste complète &lt;a href="https://keda.sh/#scalers"&gt;ici&lt;/a&gt; !&lt;/p&gt;

&lt;p&gt;Après la gestion du scaling des pods, voyons comment configurer une montée en charge sur les nodes.&lt;/p&gt;
&lt;h1&gt;
  
  
  Autoscaling de nodes
&lt;/h1&gt;

&lt;p&gt;AKS nous offre la possibilité d’allouer et de désallouer automatiquement des nodes Kubernetes pour l’hébergement de nos applications : c’est grâce à l’autoscaler de cluster.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MHyGjXZH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/i39semendr0591brsoou.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MHyGjXZH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/i39semendr0591brsoou.png" alt="Alt Text" width="880" height="623"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Création du cluster
&lt;/h2&gt;

&lt;p&gt;Demandons un cluster de test :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;az&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;rg-aks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--location&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;eastus&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;az&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;aks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--resource-group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;rg-aks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;myAKS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--node-count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--generate-ssh-keys&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Autoscale manuel
&lt;/h2&gt;

&lt;p&gt;Comme vu &lt;a href="https://dev.to/thomasrannou/de-la-haute-disponibilite-avec-azure-kubernetes-services-le-focus-infra-2jdc"&gt;ici&lt;/a&gt; AKS fonctionne avec un système de node pool. Un pool est un regroupement de nœuds dans mon cluster, chaque nœud étant une machine virtuelle Azure.&lt;/p&gt;

&lt;p&gt;Pour scaler manuellement mes nodes il faut cibler un pool :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;az&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;aks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;scale&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--resource-group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;rg-aks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;myAKS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--node-count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--nodepool-name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;#NodePoolName#&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pour obtenir un descriptif du/des pool(s), utilisez cette commande. On y voit le nom du pool à utiliser dans la commande ci-dessus.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;az&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;aks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nodepool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--resource-group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;rg-aks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--cluster-name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;myAKS&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Il y a maintenant 3 nœuds, donc 3 VM pouvant héberger des pods, dans notre cluster.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0R8jPkG5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a9cdvb0o5450ie3a651f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0R8jPkG5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a9cdvb0o5450ie3a651f.png" alt="Alt Text" width="880" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Autoscale automatique
&lt;/h2&gt;

&lt;p&gt;Nous avons parlé précédemment des “ressources” avec la définition des propriétés requests et limits.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TUoIey8e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/94hxs56yu5j6xzmx0gvb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TUoIey8e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/94hxs56yu5j6xzmx0gvb.png" alt="Alt Text" width="588" height="561"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;L’autoscaler AKS augmente ou diminue automatiquement la taille du pool de nœuds, en analysant la demande de ressources des pods.&lt;br&gt;
• Si les pods ne peuvent pas être démarrés, car il n’y a pas assez de puissance cpu/ram sur les nœuds du pool, l’autoscaler de cluster en ajoute, jusqu’à atteindre la taille maximale du pool de nœuds.&lt;br&gt;
• Si les nœuds sont sous-utilisés et que tous les pods peuvent être déployés en utilisant moins de noeuds, l’autoscaler de cluster déplace les pods puis supprime des nœuds, jusqu’à atteindre la taille minimale du pool.&lt;/p&gt;

&lt;p&gt;Pour la mise en œuvre je dois provisionner un AKS avec le support de l’autoscale sur les nodes, il faut alors spécifier une taille minimale et maximale pour le pool de nœuds.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;az&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;aks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--resource-group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;rg-aks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;myAKSWithAutoscale&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--node-count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--vm-set-type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;VirtualMachineScaleSets&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--enable-cluster-autoscaler&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--min-count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--max-count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Par ailleurs, il est possible de configurer plus finement le fonctionnement du scaling via des paramètres supplémentaires.&lt;br&gt;
Par exemple :&lt;br&gt;
--scan-interval : permet de fixer la fréquence d'évaluation du cluster pour un éventuel scale. Ce paramètre permettra de temporiser suite à au scaling avant de provisionner ou supprimer à nouveau une VM. La liste complète des paramètres est disponible &lt;a href="https://docs.microsoft.com/fr-fr/azure/aks/cluster-autoscaler#using-the-autoscaler-profile"&gt;ici&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--f3LOruK0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jbrnawp8smv6xdu1164c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--f3LOruK0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jbrnawp8smv6xdu1164c.png" alt="Alt Text" width="880" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On a maintenant un cluster avec une VM dans le node pool déclaré, scalable entre 1 et 3.&lt;/p&gt;
&lt;h3&gt;
  
  
  Modifier son autoscale
&lt;/h3&gt;

&lt;p&gt;Si mon cluster contient un seul nodepool, je peux utiliser la commande :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;az&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;aks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--resource-group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;rg-aks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;myAKSWithAutoscale&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--update-cluster-autoscaler&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--min-count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--max-count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7Y25tDGS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/97hllx1k8qf3dfzgezxo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7Y25tDGS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/97hllx1k8qf3dfzgezxo.png" alt="Alt Text" width="880" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si mon cluster utilise plusieurs nodepools, je dois utiliser l'instruction az aks nodepool update, comme ceci :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;az&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;aks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nodepool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--resource-group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;rg-aks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--cluster-name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;myAKSWithAutoscale&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nodepool1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--update-cluster-autoscaler&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--min-count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--max-count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dernier cas d'usage, si notre cluster existe mais que l’autoscale n’a pas été configuré à la création il faut l’activer via une commande sur le pool cible avec l'argument --enable-cluster-autoscaler :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;az&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;aks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nodepool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--resource-group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;rg-aks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--cluster-name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;myAKSWithAutoscale&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nodepool1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--enable-cluster-autoscaler&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--min-count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--max-count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nous avions précédemment demandé 3 nodes mais suite à notre configuration de l’autoscale, le nombre de nœud redescend progressivement à 1 puisqu’il n’y a pas de charge sur mes nœuds !&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--07mtvK4H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/oqmoyqpurxzrisjtjeti.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--07mtvK4H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/oqmoyqpurxzrisjtjeti.png" alt="Alt Text" width="880" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nous avons donc vu ici un second niveau d’autoscaling, nous permettant de provisionner des nodes dynamiquement, afin de s’adapter à la demande en ressources des pods.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Après avoir abordé la haute disponibilité coté &lt;a href="https://dev.to/thomasrannou/de-la-haute-disponibilite-avec-azure-kubernetes-services-le-focus-infra-2jdc"&gt;Infrastructure&lt;/a&gt; nous avons vu aujourd'hui comment rendre nos applicatifs résilient grâce à l'autoscaling. En effet l'un ne vas pas sans l'autre ! Configuré en premier lieu sur les pods il doit également être géré sur les nodes pour une meilleure élasticité face à la charge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Merci à &lt;a href="https://www.linkedin.com/in/lgmorand"&gt;Louis-Guillaume Morand&lt;/a&gt; et &lt;a href="https://www.linkedin.com/in/yves-de-cacqueray-88b5b793"&gt;Yves de Caqueray&lt;/a&gt; pour la relecture et leurs précieux conseils.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Thomas&lt;/p&gt;

</description>
    </item>
    <item>
      <title>De la haute disponibilité avec Azure Kubernetes Services : le focus Infra !</title>
      <dc:creator>Thomas Rannou</dc:creator>
      <pubDate>Tue, 06 Oct 2020 13:32:55 +0000</pubDate>
      <link>https://dev.to/thomasrannou/de-la-haute-disponibilite-avec-azure-kubernetes-services-le-focus-infra-2jdc</link>
      <guid>https://dev.to/thomasrannou/de-la-haute-disponibilite-avec-azure-kubernetes-services-le-focus-infra-2jdc</guid>
      <description>&lt;p&gt;Quand on choisit d’utiliser AKS, c’est pour répondre à un besoin de haute disponibilité et de résilience applicative. Dans ce post, je vous propose d'analyser quelques points d’attention au niveau infrastructure pour atteindre ces objectifs. Nous parlerons donc ici de pools de nœuds, de déploiement multi zone et multi région ainsi que de SLA.&lt;/p&gt;

&lt;h1&gt;
  
  
  Organiser son cluster avec des pools de nœuds
&lt;/h1&gt;

&lt;p&gt;Quand on utilise un cluster Kubernetes, nous sommes amenés à utiliser des nodes. Ces nodes sont des VMs composant le cluster permettant d’exécuter des pods contenant nos applications. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fo4akhcwcah5kltyn9vay.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fo4akhcwcah5kltyn9vay.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ces nœuds sont regroupés en pool de nœuds, un regroupement logique de VM du même type grâce aux VMSS Azure (&lt;a href="https://docs.microsoft.com/en-us/azure/virtual-machine-scale-sets/overview" rel="noopener noreferrer"&gt;Virtual Machine Scale Set&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Petit apparté : il est possible d'utiliser des VMAS (VM avec Availability Set plutôt que des VMSS). J'en parle pour être complet mais je déconseille cette approche car il vous sera alors impossible de gérer plusieurs nodepools et configurer un autoscale sur le cluster.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Tout l’intérêt des nodepools est la possibilité de gérer des nœuds spécifiques pour exécuter nos pods afin de répondre à des besoins bien précis. Voyons comment les manipuler.&lt;/p&gt;

&lt;h2&gt;
  
  
  Création du cluster
&lt;/h2&gt;

&lt;p&gt;Je créé un cluster AKS avec un pool de noeud de 2 VM. Important : Le cluster AKS doit utiliser un loadbalancer en SKU "Standard" pour pouvoir utiliser plusieurs pools de nœuds :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;az&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;aks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--resource-group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;rgAks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;myAKSCluster&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--vm-set-type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;VirtualMachineScaleSets&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--node-count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--generate-ssh-keys&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--load-balancer-sku&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;standard&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La commande suivante (az aks nodepool list) me renseigne sur les node pools de mon cluster. Pour le moment il n'y en a qu'un :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6rg4qrd9lk8du3hcncsr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6rg4qrd9lk8du3hcncsr.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Ajout d’un pool de noeud
&lt;/h2&gt;

&lt;p&gt;J'ajoute un second node pool contenant une VM de type D4s_v3 :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;az&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;aks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nodepool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--resource-group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;rgAks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--cluster-name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;myAKSCluster&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nodepool2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--node-count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--node-vm-size&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Standard_D4s_v3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--no-wait&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;J'ai maintenant deux pools de nœuds à disposition. Deux pools qui contiennent des VM de taille (et donc de puissance de calcul) différente ! Et nous allons tout de suite voir en quoi cette capacité est hyper intéressante :)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjfa5zu5ycfndw2afc615.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjfa5zu5ycfndw2afc615.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Le choix des noeuds
&lt;/h1&gt;

&lt;p&gt;Il est possible de créer des nodes particuliers :&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  •   Optimisé en quantité de mémoire ou de processeur.
  •   Avec une prise en charge GPU. 
  •   Optimisé pour le stockage.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Je ne vais pas présenter ici les différents type de VM et le nommage associé donc pour obtenir des informations sur les machine virtuelles vous pouvez consulter ce &lt;a href="https://azure.microsoft.com/fr-fr/pricing/details/virtual-machines/series/" rel="noopener noreferrer"&gt;lien&lt;/a&gt; !&lt;/p&gt;

&lt;p&gt;Ici par exemple je créé un pool de nœud conçu pour le calcul GPU.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;az&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;aks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nodepool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--resource-group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;rgAks--cluster-name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;myAKSCluster&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;gpunodepool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--node-count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--node-vm-size&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Standard_NC6&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--no-wait&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Associer des nodes au pods
&lt;/h2&gt;

&lt;p&gt;Maintenant que nous avons des nœuds spécifiques, il serait intéressant que des pods s’exécutent sur ces nœuds en conséquence. Pour ce besoin nous pouvons utiliser les notions de &lt;a href="https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/" rel="noopener noreferrer"&gt;"taints" et "tolerations"&lt;/a&gt; !&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  •   Si j’applique une taint à un nœud je pourrais déployer sur ce nœud uniquement des pods prévu pour la supporter.
  •   Je peux alors appliquer une toleration à un pod pour lui permettre de supporter la taint d’un nœud.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Voici les types de taint disponibles :&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  •   NoSchedule : les pods qui ne tolèrent pas la taint ne seront pas déployés sur le nœud.
  •   PreferNoSchedule : Kubernetes évite de déployer les pods sur le nœud. Mais si besoin, il peut le faire.
  •   NoExecute : Même punition que le NoSchedule mais en prime, si un pod est déjà en cours d’exécution sur ce nœud, il est supprimé de celui-ci.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Grâce à ces pools de nœuds ainsi que les taints et tolerations nous avons la possibilité de prévoir des nœuds dans notre cluster AKS destinés à des types de pods bien précis. Il est donc possible d’adapter l’environnement d’exécution Kubernetes en fonction du type d’application déployé pour lui affecter plus ou moins de ressources, du stockage ou un GPU.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quelques précisions :
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  •   La création du cluster crée un pool de nœuds par défaut, qu’il n’est pas possible de supprimer.
  •   Le cluster AKS peut avoir un maximum de huit pools de nœuds et 800 nœuds dans ces 8 pools de nœuds.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Maintenant que nous avons des pools de nœuds adaptés à notre besoin, voyons comment les déployer dans Azure.&lt;/p&gt;

&lt;h1&gt;
  
  
  Comment déployer mes nœuds ?
&lt;/h1&gt;

&lt;p&gt;On désigne par résilience la capacité d’un service à continuer de fonctionner malgré la défaillance d’un ou plusieurs éléments d’infrastructure (base de données, serveurs Web, accès réseau, … ). La résilience désigne également la capacité du service à revenir dans un mode nominal de façon automatisée.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4ef05dnsow633vp3x46w.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4ef05dnsow633vp3x46w.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Les régions et zones Azure
&lt;/h2&gt;

&lt;p&gt;Avant de parler de régions, il faut introduire les zone géographiques. Une zone géographique correspond à une offre de déploiement de composants Azure. Par exemple France. Une zone géographique contient au minimum deux régions, qui peuvent être géorépliqué (le pairage des régions étant définis par Microsoft).&lt;br&gt;
Par exemple la zone géographique France est composée de France Centre et France Sud. Celles-ci permettent de répondre à des exigences clients concernant le déploiement et le stockage des informations.&lt;/p&gt;

&lt;p&gt;Une région est un emplacement physique de datacenter Azure. Par exemple la région France Centre est constitué de 3 datacenters situés en région parisienne.&lt;/p&gt;

&lt;p&gt;Les zones de disponibilité sont des emplacements physiquement séparés au sein d’une région Azure comme France Centre. Chaque zone de disponibilité est composée d’un ou de plusieurs centres de données équipés d’une alimentation, d’un refroidissement et d’un réseau indépendants.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh5d2c045jgsy14z4966z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh5d2c045jgsy14z4966z.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  AKS et zones de disponibilité
&lt;/h2&gt;

&lt;p&gt;Voyons l’application des zones de disponibilités sur AKS ! Si vous avez bien suivis, vous comprenez maintenant que les clusters AKS déployés à l’aide de zones de disponibilité peuvent répartir les nœuds sur plusieurs zones au sein d’une même région ! Par exemple, un cluster dans la région  France Centre  peut créer des nœuds dans les trois zones de disponibilité de France Centre. Il y aura des noeuds sur chaque datacenter composant la région.&lt;/p&gt;

&lt;p&gt;Grace à cela votre cluster AKS est capable de tolérer une défaillance dans l’une de ces zones ; si un des datacenter de la région est indisponible la continuité de service est assuré. A contrario, si tout les nœuds de notre cluster était déployé au même endroit, le service serait indisponible.&lt;/p&gt;
&lt;h3&gt;
  
  
  SLA des Nodes AKS
&lt;/h3&gt;

&lt;p&gt;Le SLA d’un node de notre cluster correspond au SLA de la VM utilisée par ce node.&lt;/p&gt;

&lt;p&gt;Le SLA “standard” est à 99.9%. Si nous utilisons un availability set : 99.95% soit environ 4h d’indisponibilité par an.&lt;br&gt;
Grace à l’availability zone, on monte à 99.99% soit moins d’une heure d’indisponibilité par an.&lt;/p&gt;
&lt;h3&gt;
  
  
  Limitations et disponibilité de la région
&lt;/h3&gt;

&lt;p&gt;Attention, toutes les régions ne gèrent pas les AZ ! Nous pouvons actuellement créer des clusters AKS en utilisant des zones de disponibilité dans les régions listées &lt;a href="https://docs.microsoft.com/fr-fr/azure/aks/availability-zones#limitations-and-region-availability" rel="noopener noreferrer"&gt;ici&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Attention, quelques informations à prendre en compte !&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  •   Les zones de disponibilité se gèrent à la création du cluster. Ces paramètres ne sont pas modifiables ultérieurement.
  •   Les clusters avec des zones de disponibilité activées nécessitent l’utilisation du loadbalancer SKU Standard Azure pour la distribution entre les zones.
  •   Incompatible avec les pods statefulset avec un volume persistent !
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Mise en oeuvre
&lt;/h3&gt;

&lt;p&gt;Le paramètre permettant d’utiliser les zones de disponibilité est zones :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;az&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;aks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--resource-group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;aksAvailabilityZone&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;aks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--generate-ssh-keys&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--vm-set-type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;VirtualMachineScaleSets&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--load-balancer-sku&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;standard&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--node-count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--zones&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Je me connecte à mon cluster nouvellement créé :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;az&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;aks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;get-credentials&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--resource-group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;aksAvailabilityZone&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;aks&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pour obtenir la description des nodes :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nodes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;select-string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-pattern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'^Name:'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'zone='&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frniqpatrr0mwzfp4r0vh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frniqpatrr0mwzfp4r0vh.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;J’ai bien un node de déployé dans chaque zone de la région France Centre. Réalisons une montée en charge pour analyser la répartition des nodes :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;az&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;aks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;scale&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--resource-group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;aksAvailabilityZone&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;myAKSCluster&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--node-count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nodes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;select-string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-pattern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'^Name:'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'zone='&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fc53us54gwz7c3ndmr4dt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fc53us54gwz7c3ndmr4dt.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;J’ai donc deux nodes sur France Centre 1 et 2, et un node sur France Centre 3. Je déploie un nginx :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--replicas&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Et je demande un descriptif de mes pods :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pod&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;select-string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-pattern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'^Name:'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'^Node:'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ft495lrzczzhqhj7stt5j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ft495lrzczzhqhj7stt5j.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;J’ai donc un pod en zone 1 et 3. Si le premier datacenter de la région est indisponible, j'aurais toujours un pod à s'éxécuter sur un autre datacenter.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comment fonctionne le déploiement multi zones ?
&lt;/h3&gt;

&lt;p&gt;Par défaut Kubernetes est capable de répartir automatiquement les pods sur les différents &lt;a href="https://kubernetes.io/docs/setup/best-practices/multiple-zones/" rel="noopener noreferrer"&gt;noeuds&lt;/a&gt; du cluster. Ceci afin de prévenir la défaillance de l'un d'eux. Cependant, sans contrôle de notre part, rien ne garantit qu'ils seront répartis de façon optimale.&lt;/p&gt;

&lt;p&gt;Dans le cas d'un déploiement multi zones il peux être intéressant d'influer sur la façon dont la répartition est effectuée.&lt;br&gt;
Il pourra par exemple être pertinent de demander l'exécution de minimum 2 réplicas sur chacune des 3 AZ d'une région.&lt;/p&gt;

&lt;p&gt;Pour ce faire nous pourrons utiliser les &lt;a href="https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/" rel="noopener noreferrer"&gt;topology spread constraints&lt;/a&gt;. Associé aux labels des nodes, ces topologies nous permettront de contrôler la propagation des pods dans notre cluster afin de garantir au mieux la haute disponibilité et l'utilisation des ressources allouées.&lt;/p&gt;

&lt;p&gt;Je vous renvoie à la &lt;a href="https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/#spread-constraints-for-pods" rel="noopener noreferrer"&gt;doc officielle du composant&lt;/a&gt; pour la mise en œuvre.&lt;/p&gt;
&lt;h2&gt;
  
  
  Pour aller plus loin : le déploiement multi-région
&lt;/h2&gt;

&lt;p&gt;Pour se prémunir de l’indisponibilité d’une région entière comme France Centre, on peux imaginer déployer deux clusters AKS sur deux régions différentes.&lt;/p&gt;

&lt;p&gt;A ce moment-là, on peut utiliser Traffic Manager pour contrôler la façon dont le trafic est dirigé vers les clusters dans différentes régions. &lt;/p&gt;

&lt;p&gt;On peux router le traffic suivant divers paramètres :&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  •   Le temps de réponse des clusters
  •   En fonction de critères géographiques (pour connecter un utilisateur à sa région la plus proche par exemple).
  •   Si cette région rencontre un problème, Traffic Manager peux diriger l’utilisateur vers une autre région.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnyvtcg5opxwk9qefp39b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnyvtcg5opxwk9qefp39b.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nous pourrons utiliser cette approche conjointement avec la Réplication des registry afin d’accélérer les déploiements applicatifs.&lt;/p&gt;

&lt;p&gt;Coté backend (base de données, stockage de documents) il est possible également de mettre en oeuvre des mécanismes de déploiement multi régions et de synchronisation automatique des données :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Avec une base de données &lt;a href="https://docs.microsoft.com/fr-fr/azure/azure-sql/database/active-geo-replication-overview" rel="noopener noreferrer"&gt;SQL Database géo répliqué&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Avec un storage account avec une &lt;a href="https://docs.microsoft.com/fr-fr/azure/storage/common/storage-redundancy" rel="noopener noreferrer"&gt;réplication&lt;/a&gt; GRS voir RA-GRS afin que les données puissent être en R/W dans les deux régions simultanément.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;
  
  
  Concernant le master ...
&lt;/h1&gt;

&lt;p&gt;En déploiement « standard » Microsoft fournit un SLO de 99.5% pour l’API Server du Master Kubernetes, point d’entrée de toutes les sollicitations au cluster.&lt;/p&gt;

&lt;p&gt;Depuis peu Microsoft propose un “uptime SLA” pour AKS pour garantir la disponibilité de l’API Server Kubernetes.&lt;/p&gt;

&lt;p&gt;Cette possibilité se positionne en parallèle du déploiement classique d’AKS, que nous connaissons déjà.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0uxcwxlc7j1xrfwobox6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0uxcwxlc7j1xrfwobox6.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Le contrat de SLA garantit une durée de bon fonctionnement de 99,95 % pour le serveur d’API Kubernetes pour les clusters utilisant des zones de disponibilité Azure et de 99,9 % pour les clusters n’utilisant pas de zones de disponibilité.&lt;/p&gt;

&lt;p&gt;Pour atteindre ce niveau de SLA (99.9), la plateforme utilise une réplication de nodes du master sur des availability set : des “zones” d’un datacenter qui garantissent :&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  •   Des mises à jour qui ne seront pas appliquées en même temps qu’une autre zone
  •   Une alimentation électrique spécifique
  •   Une gestion réseau spécifique
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Le coût de cet option est d’environ (il varie suivant les régions) de 0.10$ par heure par cluster. Un cluster AKS déployé sans cette option (comme actuellement donc) conserve son SLO de 99.5% !&lt;/p&gt;

&lt;p&gt;Le tableau récapitulatif :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fj4so5tecsbpi9bgfjtx7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fj4so5tecsbpi9bgfjtx7.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pricing par région : &lt;a href="https://azure.microsoft.com/fr-fr/pricing/details/kubernetes-service/" rel="noopener noreferrer"&gt;https://azure.microsoft.com/fr-fr/pricing/details/kubernetes-service/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La disponibilité des nœuds, comme vu précédemment, est couverte par le contrat SLA des machine virtuelle sur lesquelles s’exécutent les pods. &lt;/p&gt;
&lt;h2&gt;
  
  
  Mise en oeuvre
&lt;/h2&gt;

&lt;p&gt;Pour utiliser cette garantie de disponibilité, il faudra utiliser le paramètre --uptime-sla comme dans la commande ci-dessous, fournie par Microsoft :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;az&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;aks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--resource-group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;myResourceGroup&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;myAKSCluster&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--uptime-sla&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--node-count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--generate-ssh-keys&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Attention, il n’est pas possible de retirer cette configuration à un cluster une fois appliquée. En revanche il est possible de créer un cluster "standard" puis de configurer le uptime SLA.&lt;/p&gt;

&lt;p&gt;La différence se verra ici au niveau du SKU du cluster déployé :&lt;/p&gt;

&lt;p&gt;"sku": {&lt;br&gt;
    "name": "Basic",&lt;br&gt;
    "tier": "Paid"&lt;br&gt;
  },&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Nous avons vu dans cet article les différents éléments composants un cluster AKS et les moyens d'optimiser leur disponibilité. Nous étions aujourd'hui concentré sur la partie infrastructure, mais attention cette gestion seule n'est pas suffisante ! Il faut également s'intéresser à la haute disponibilité applicative. Une infrastructure résiliente c'est bien, mais si l'applicatif ne l'est pas cela ne sert à rien !&lt;/p&gt;

&lt;p&gt;Dans un prochain article nous nous intéresserons au façon de propager cette haute disponibilité aux applications avec l'autoscaling au niveau des pods comme du cluster.&lt;/p&gt;

&lt;p&gt;J'espère que cet article vous aura apporté des informations pour la gestion de votre cluster k8s dans Azure !&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Merci à &lt;a href="https://www.linkedin.com/in/lgmorand" rel="noopener noreferrer"&gt;Louis-Guillaume Morand&lt;/a&gt; et &lt;a href="https://www.linkedin.com/in/yves-de-cacqueray-88b5b793" rel="noopener noreferrer"&gt;Yves de Caqueray&lt;/a&gt; pour la relecture et leurs précieux conseils.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Thomas&lt;/p&gt;

</description>
      <category>azure</category>
      <category>kubernetes</category>
      <category>infrastructure</category>
    </item>
  </channel>
</rss>
