<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Thomas Labarussias</title><link>https://thomas.labarussias.fr/</link><description>Recent content on Thomas Labarussias</description><generator>Hugo -- gohugo.io</generator><language>fr</language><lastBuildDate>Thu, 17 Jun 2021 00:00:00 +0000</lastBuildDate><atom:link href="https://thomas.labarussias.fr/index.xml" rel="self" type="application/rss+xml"/><item><title>Le FinOps</title><link>https://thomas.labarussias.fr/posts/finops/</link><pubDate>Thu, 17 Jun 2021 00:00:00 +0000</pubDate><guid>https://thomas.labarussias.fr/posts/finops/</guid><description>&lt;h2 id="avant-propos"&gt;Avant-propos
&lt;/h2&gt;&lt;p&gt;Durant mon expérience professionnelle précédente, j&amp;rsquo;ai exercé pendant 3 ans en tant qu&amp;rsquo;expert &lt;strong&gt;FinOps&lt;/strong&gt; sur &lt;strong&gt;AWS&lt;/strong&gt;. La fonction ayant été créée avec moi, j&amp;rsquo;ai eu toute liberté pour mettre en place le modèle que je souhaitais, avec sa méthodologie et ses outils.
Avant d&amp;rsquo;oublier ce que je sais, je me suis dit qu&amp;rsquo;il serait peut-être intéressant pour certains que je mette ce qui me reste en tête par écrit, la littérature en français se faisant rare d&amp;rsquo;autant plus (si l&amp;rsquo;article plaît, je ferai peut-être une traduction en anglais).&lt;/p&gt;
&lt;p&gt;Il m&amp;rsquo;était également apparu, en discutant avec mes clients et d&amp;rsquo;autres experts, souvent issus d&amp;rsquo;entreprises de conseils, que ma vision pouvait différer de la leur et de ce qu&amp;rsquo;on trouve généralement dans les articles traitant du sujet. Je pense que cela vient du fait que je suis avant tout un &lt;em&gt;OPS&lt;/em&gt;, gérant une production et les contraintes inhérentes. Mes recommandations et conseils ont toujours eu pour trame de fond une vraie exploitation des plateformes, de leurs performances et disponibilités (travaillant pour un infogérant, si la plateforme tombait, c&amp;rsquo;étaient mes collègues et moi qui réglons les problèmes, possiblement en astreinte 😉 ).&lt;/p&gt;
&lt;p&gt;N&amp;rsquo;ayant de connaissances avancées et n&amp;rsquo;ayant effectué des audits uniquement pour &lt;em&gt;AWS&lt;/em&gt;, j&amp;rsquo;utiliserai dans cet article beaucoup de termes et conseils liés à ce &lt;em&gt;Cloud Provider&lt;/em&gt;, mais je pense que les éléments généraux sont facilement transposables à &lt;em&gt;GCP&lt;/em&gt; et &lt;em&gt;Azure&lt;/em&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="définition"&gt;Définition
&lt;/h2&gt;&lt;p&gt;La première des tâches est bien entendu de définir le terme de &lt;strong&gt;FinOps&lt;/strong&gt; lui-même. Il apparaît évidemment qu&amp;rsquo;il est la contraction de deux termes (comme tous ces &lt;strong&gt;TrucOps&lt;/strong&gt; à la mode 😛).
Dans notre cas: &lt;strong&gt;Financial&lt;/strong&gt; + &lt;strong&gt;Operations&lt;/strong&gt;.
Pas très parlant au demeurant, on s&amp;rsquo;attend plus à de la comptabilité qu&amp;rsquo;à de l&amp;rsquo;architecture &lt;em&gt;Cloud&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Voilà donc ma définition, avec des morceaux en gras et ce, à dessein:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Le &lt;strong&gt;FinOps&lt;/strong&gt; &lt;strong&gt;analyse les architectures&lt;/strong&gt; Cloud et leurs &lt;strong&gt;facturations associées&lt;/strong&gt;, afin de dégager des &lt;strong&gt;axes de limitations des coûts et/ou d’économie&lt;/strong&gt;, en assurant &lt;strong&gt;un niveau de risque faible&lt;/strong&gt; et en prenant en compte les &lt;strong&gt;enjeux de l&amp;rsquo;entreprise&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Reprenons chacune des parties mises en exergue:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;analyse les architectures&lt;/strong&gt;: Le travail de &lt;em&gt;FinOps&lt;/em&gt; est un travail d&amp;rsquo;ingénierie avant tout, si on se contente de pointer des lignes dans une feuille &lt;em&gt;Excel&lt;/em&gt; pour trouver les services coûtant trop chers dans lesquels il faudrait tailler, cela ne marchera pas.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;facturations associées&lt;/strong&gt;: On enfonce une porte ouverte, mais il va de soit que pour cibler les axes d&amp;rsquo;améliorations, il faut savoir quels sont les services qui sont facturés et dans quelles mesures (réduire de 10% le coût d&amp;rsquo;un service à $100 reste moins intéressant avant que 2% d&amp;rsquo;un service à $1000, par exemple).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;axes de limitations des coûts et/ou d’économie&lt;/strong&gt;: La distinction est très importante à mon sens. On cherche souvent à seulement diminuer les coûts, mais il faut aussi penser à faire en sorte de contrôler leurs évolutions. J&amp;rsquo;ai souvent expliqué qu&amp;rsquo;une facture de &lt;em&gt;Cloud Provider&lt;/em&gt; qui augmente, ce n&amp;rsquo;est pas forcément anormal ou gênant, cela peut juste être la conséquence logique de l&amp;rsquo;augmentation de l&amp;rsquo;activité. Vous avez plus de trafic, et donc plus de consommation mais surtout plus de chiffre d&amp;rsquo;affaires, ce qui est attendu. Là où ça coince c&amp;rsquo;est quand la facture augmente alors que le CA baisse, ou bien que les deux croissent tous deux mais dans des ordres de grandeur très différents (coûts qui explosent par rapport aux revenus).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;un niveau de risque faible&lt;/strong&gt;: Quand on met en place des actions &lt;em&gt;FinOps&lt;/em&gt;, on pense souvent à changer les types des Instances (&lt;em&gt;VM&lt;/em&gt;), ou à ré-architecturer des portions de la plateforme. Il est alors très important de garder à l&amp;rsquo;esprit que la plateforme doit assurer un service de même qualité (voire plus), et il faut donc être très prudent dans les choix et leurs mises en place.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;enjeux de l&amp;rsquo;entreprise&lt;/strong&gt;: Une plateforme &lt;em&gt;Cloud&lt;/em&gt; n&amp;rsquo;est après-tout qu&amp;rsquo;un outil, un moyen de délivrer un service, elle s&amp;rsquo;inscrit dans un cadre beaucoup plus vaste à prendre en compte. Je pense par exemple à la maturité de l&amp;rsquo;entreprise avec les technologies, ou bien aux contraintes légales (&lt;em&gt;PCI-DSS&lt;/em&gt;, &lt;em&gt;HADS&lt;/em&gt;, etc).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="trouver-le-bon-dosage-entre-ha-perfs-et-coûts"&gt;Trouver le bon dosage entre HA, Perfs et Coûts
&lt;/h2&gt;&lt;p&gt;Fort de cette définition, il convient désormais d&amp;rsquo;expliciter ce qu&amp;rsquo;on vise en faisant du &lt;strong&gt;FinOps&lt;/strong&gt;, ce qui va guider nos choix.&lt;/p&gt;
&lt;p&gt;Il s&amp;rsquo;agit de trouver le bon dosage entre 3 critères:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Haute-disponibilité&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Performances&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Coûts&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Les 3 s&amp;rsquo;influencent bien évidemment mutuellement.&lt;/p&gt;
&lt;p&gt;Par exemples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Si la &lt;strong&gt;HA&lt;/strong&gt; est un critère dominante, les coûts vont forcément grimper et les performances peuvent baisser &lt;em&gt;(multi-régions, multi-cloud)&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Si on privilégie les &lt;strong&gt;performances&lt;/strong&gt;, des machines plus grosses seront à payer mais la &lt;strong&gt;HA&lt;/strong&gt; pourra être sacrifiée également &lt;em&gt;(j&amp;rsquo;ai eu un client qui faisait tout tourner sur une seule AZ AWS car les latences entre les datacenters AWS avaient un impact sur sa grille de calcul)&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Si on cherche absolument à baisser les coûts, on sacrifiera les &lt;strong&gt;performances&lt;/strong&gt; et/ou la &lt;strong&gt;haute-disponibilité&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="un-autre-critère-à-prendre-en-compte-la-sécurité"&gt;Un autre critère à prendre en compte: la Sécurité
&lt;/h3&gt;&lt;p&gt;J&amp;rsquo;ai volontairement omis de rajouter ce 4ème critère dans la liste précédente, car il est particulier et à toute son importance. Il impacte potentiellement les 3 autres critères et s&amp;rsquo;inscrit dans un cadre plus important très souvent impossible à négliger (&lt;em&gt;PCI-DSS&lt;/em&gt;, &lt;em&gt;HADS&lt;/em&gt;, etc). Il faut donc veiller à ce que les recommandations s&amp;rsquo;inscrivent dans les bonnes pratiques de sécurité, voire dans le cadre de la loi.&lt;/p&gt;
&lt;h3 id="ajuster-ses-critères"&gt;Ajuster ses critères
&lt;/h3&gt;&lt;p&gt;Il ressort de tout cela une bonne nouvelle, c&amp;rsquo;est que nous sommes dans le cadre d&amp;rsquo;une plateforme &lt;em&gt;Cloud&lt;/em&gt;, qui vient avec ses contraintes mais aussi ses avantages, avec en tête de la liste la flexibilité.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai mentionné précédemment que tout l&amp;rsquo;art du &lt;em&gt;FinOps&lt;/em&gt; était de trouver le bon dosage entre les &lt;em&gt;perfs&lt;/em&gt;, la &lt;em&gt;HA&lt;/em&gt; et les &lt;em&gt;coûts&lt;/em&gt;, et ce qu&amp;rsquo;il y a de &lt;em&gt;magique&lt;/em&gt; avec le &lt;em&gt;Cloud&lt;/em&gt;, c&amp;rsquo;est que ce dosage n&amp;rsquo;est pas voué à être immuable et universel. La souplesse des &lt;em&gt;Cloud Providers&lt;/em&gt; permet d&amp;rsquo;ajuster la balance comme on le souhaite et quand on le souhaite.&lt;/p&gt;
&lt;p&gt;Voici une liste d&amp;rsquo;éléments pouvant amener à adapter notre choix du ou des critères dominants, avec quelques exemples pour les expliciter:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Environnement&lt;/strong&gt;: On accorde souvent plus d&amp;rsquo;importance à la disponibilité de l&amp;rsquo;environnement de production qu&amp;rsquo;à celui de staging.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Période&lt;/strong&gt;: En e-commerce, on mettra le paquet en période de soldes. Une application de facturation n&amp;rsquo;a besoin d&amp;rsquo;être gonflée aux stéroïdes qu&amp;rsquo;en début ou fin de mois, etc.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Criticité des données&lt;/strong&gt;: On peut parfois se permettre de perdre du cache, mais pas des données métier.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Criticité de l&amp;rsquo;application&lt;/strong&gt;: Un SSO sera central, alors qu&amp;rsquo;un &lt;em&gt;worker&lt;/em&gt; qui tombe ne crée que du délai et sa tâche sera censée être reprise ensuite.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enjeux Business&lt;/strong&gt;: Respect des SLA de disponibilité ou de performance.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Budget&lt;/strong&gt;: Une levée de fond permet souvent d&amp;rsquo;apporter les modifications voulues ou à l&amp;rsquo;inverse, un trou dans la trésorerie imposera de sacrifier tel ou tel critère.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="coûts-et-modèles-de-facturation"&gt;Coûts et modèles de facturation
&lt;/h2&gt;&lt;p&gt;Il est extrêmement important d&amp;rsquo;avoir à l&amp;rsquo;esprit de quoi sont composées les factures mais aussi le contexte global dans lesquelles elles s&amp;rsquo;inscrivent.&lt;/p&gt;
&lt;p&gt;Je dégage donc 2 axes, les coûts &lt;em&gt;Directs&lt;/em&gt; et les coûts &lt;em&gt;Indirects&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;On ne pourra pas jouer sur les deux de la même façon, voire pas du tout pour certains éléments. Et il est très important de tous les prendre en compte dans les choix des actions à mener.&lt;/p&gt;
&lt;h3 id="les-coûts-directs"&gt;Les coûts Directs
&lt;/h3&gt;&lt;p&gt;Je classe parmi les coûts &lt;em&gt;Directs&lt;/em&gt; tout ce qui est directement dans la facture du &lt;em&gt;Cloud Provider&lt;/em&gt;, en séparant en 2 catégories:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ressources&lt;/strong&gt;: Ce sont les coûts dans les factures les plus simples à comprendre et estimer, généralement facturés à la seconde ou heure, ils caractérisent les éléments &amp;ldquo;immobilisés&amp;rdquo; pour composer l&amp;rsquo;infrastructure (&lt;em&gt;Instances&lt;/em&gt;, &lt;em&gt;Volumes&lt;/em&gt;, etc). La règle est simple, plus on prend gros, plus on paye cher, et inversement. On peut donc facilement estimer les économies possibles quand on agit sur elles.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Consommations&lt;/strong&gt;: Ce sont tous les coûts dans les factures plus difficiles à estimer car indépendant de nos propres choix et variant du tout ou tout entre les périodes. On y classe la bande passante, les snapshots, le nombre total de requêtes, etc. Les estimations d&amp;rsquo;économies sont souvent moins précises mais en connaissant bien son activité et en prenant quelques marges, on y arrive.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="les-coûts-indirects"&gt;Les coûts Indirects
&lt;/h3&gt;&lt;p&gt;Quand on pense à réduire sa facture &lt;em&gt;Cloud&lt;/em&gt; on oublie bien souvent les coûts annexes qui n&amp;rsquo;apparaissent pas à proprement parlé sur la facture mais qui sont pourtant bien là quand on veut mettre en place des actions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Coûts de migration&lt;/strong&gt;: Si vous prévoyez de remplacer des morceaux ou de partir sur une nouvelle architecture, il sera nécessaire de passer un grand nombre de &lt;em&gt;JH&lt;/em&gt; (jour-homme) sur le sujet, et cela aura un coût pour votre organisation, tant financier qu&amp;rsquo;humain. Le retour sur investissements se doit donc d&amp;rsquo;être intéressant.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Coûts de développement&lt;/strong&gt;: Dans la même idée, moins &lt;em&gt;OPS&lt;/em&gt; et plus &lt;em&gt;DEV&lt;/em&gt;, si vous changez de technologie, il y aura sûrement du code à écrire et donc du &lt;em&gt;JH&lt;/em&gt; à passer, sur des fonctionnalités qui n&amp;rsquo;apportent pas forcément une plus-value pour le client final.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Formation&lt;/strong&gt;: Un point à ne jamais négliger, tout changement sera mieux vécu s&amp;rsquo;il est accompagné par une formation, qu&amp;rsquo;elle soit interne ou non (c&amp;rsquo;est souvent plus cher avec des consultants extérieurs, bien entendu).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Infogérance&lt;/strong&gt;: Si vous ne gérez pas vous-même votre plateforme, ou si vous avez souscrit un contrat pour avoir du 24/7, le périmètre financier peut être impacté.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Licences&lt;/strong&gt;: C&amp;rsquo;est un point surtout valable pour les migrations d&amp;rsquo;&lt;em&gt;On-Premise&lt;/em&gt; vers du &lt;em&gt;Cloud&lt;/em&gt;, les modèles de facturation des licences éditeurs pouvant beaucoup changer, et pas forcément à la baisse.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ces coûts &lt;em&gt;Indirects&lt;/em&gt; sont bien souvent plus difficiles à évaluer, voire quasi impossibles quand vous êtes un auditeur externe, mais il est important de prendre en compte le fait qu&amp;rsquo;ils existent et peuvent drastiquement changer le choix des actions à mener.&lt;/p&gt;
&lt;h2 id="finops-un-processus"&gt;FinOps, un processus
&lt;/h2&gt;&lt;p&gt;Maintenant que nous avons la destination, voyons le chemin. A mon sens, le &lt;em&gt;FinOps&lt;/em&gt; est un processus qui se déroulera toute la vie de la plateforme et débute à sa conception. Il apparaît bien souvent que réfléchir à une architecture en intégrant les aspects &lt;em&gt;FinOps&lt;/em&gt; dès le début, amène à créer des conceptions plus proches des bonnes pratiques.&lt;/p&gt;
&lt;p&gt;Ce processus à plusieurs caractéristiques, il est:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Continue&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Itératif&lt;/em&gt; (une action après l&amp;rsquo;autre)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;A complexité croissante&lt;/em&gt; (voire exponentielle)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ce processus, peut varier d&amp;rsquo;une entreprise à l&amp;rsquo;autre, mais on retrouve généralement 3 étapes clés, se répétant:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Analyse &amp;gt; Recommandations &amp;gt; Mise en place &amp;gt; Analyse &amp;gt; &amp;hellip;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="un-processus-continue"&gt;Un processus continue
&lt;/h3&gt;&lt;p&gt;Les architectures &lt;em&gt;Cloud&lt;/em&gt; étant élastiques, les facturations associées le sont tout autant. A cela s&amp;rsquo;ajoute que le tout virtualisé, payé à la consommation, rend les architectures mutables (changement de types de machines, remplacement de briques par d&amp;rsquo;autres services, etc). Il apparaît alors évident que mener des actions &lt;em&gt;FinOps&lt;/em&gt; une fois tous les trimestres, par exemple, sera moins pertinent, et pire, à la traîne vis-à-vis des dépenses.&lt;/p&gt;
&lt;p&gt;Il est important d&amp;rsquo;intégrer le &lt;em&gt;FinOps&lt;/em&gt; parmi tous les autres processus permettant de gérer correctement une plateforme, voire même d&amp;rsquo;intégrer des points de contrôle au même titre que nous mettons en place du &lt;em&gt;monitoring&lt;/em&gt; pour les systèmes eux-mêmes. Les &lt;em&gt;Cloud Providers&lt;/em&gt; ne s&amp;rsquo;y sont pas trompés et fournissent des moyens de vérifier le respect d&amp;rsquo;un budget (sans jamais bloquer les possibles dépenses, on parle juste d&amp;rsquo;alertes). Cela rentre dans la partie de ma définition: &lt;code&gt;limiter les coûts&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Cela n&amp;rsquo;écarte pas les audits plus profonds pouvant être menés, non pas au jour le jour, mais tout de même régulièrement, et qui eux servent souvent à dégager les axes d&amp;rsquo;économies plus importantes.&lt;/p&gt;
&lt;h3 id="un-processus-itératif"&gt;Un processus itératif
&lt;/h3&gt;&lt;p&gt;Une fois qu&amp;rsquo;une analyse &lt;em&gt;FinOps&lt;/em&gt; a été menée à bien et que des préconisations ont été établies, la tentation de réduire la facture immédiatement peut être forte en menant toutes les actions d&amp;rsquo;un coup. C&amp;rsquo;est rarement une bonne chose. En menant plusieurs actions en parallèle, il devient plus difficile de déterminer quelles sont celles qui ont eu l&amp;rsquo;effet escompté, et pire, certaines peuvent entrer en contradiction sans qu&amp;rsquo;il ne soit possible de déterminer comment. En itérant, action par action, il devient aisé de déterminer celles qui ont bien fonctionné et donc de les répéter dans le temps ou sur d&amp;rsquo;autres environnements.&lt;/p&gt;
&lt;h3 id="un-processus-à-complexité-croissante"&gt;Un processus à complexité croissante
&lt;/h3&gt;&lt;p&gt;La première action (cf suite de l&amp;rsquo;article) est généralement de traquer les dépenses inutiles, les gâchis. C&amp;rsquo;est une action relativement simple, qu&amp;rsquo;on peut faire manuellement dans un premier temps puis automatisée. Une fois que c&amp;rsquo;est en place, d&amp;rsquo;autres actions peuvent être menées, forcément plus compliquées que les précédentes, et ainsi de suite. Il apparaît rapidement que le rapport économies possibles sur investissement (temps + argent) s&amp;rsquo;amenuise avec le temps, plus on avance dans les solutions trouvées pour limiter les coûts ou économiser, plus celles-ci deviennent complexes à mettre en oeuvre. Je pense même que la tendance suivie est exponentielle. L&amp;rsquo;ordre de grandeur de l&amp;rsquo;investissement n&amp;rsquo;est pas du tout le même entre une automatisation de la suppression des volumes détachés et la refonte d&amp;rsquo;une partie de l&amp;rsquo;infrastructure pour utiliser du &lt;em&gt;Serverless&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id="outillage"&gt;Outillage
&lt;/h2&gt;&lt;p&gt;Avec quoi pouvons-nous mener une analyse &lt;em&gt;FinOps&lt;/em&gt;?&lt;/p&gt;
&lt;p&gt;Il s&amp;rsquo;agit bien entendu d&amp;rsquo;une liste non exhaustive, mais c&amp;rsquo;est une demande qui m&amp;rsquo;a souvent été faîte donc la voici.&lt;/p&gt;
&lt;h2 id="les-factures"&gt;Les Factures
&lt;/h2&gt;&lt;p&gt;Les factures sont, bien entendu, les premières pièces à étudier, elles sont souvent simplifiées et permettent d&amp;rsquo;avoir un aperçu global ainsi que les tendances. C&amp;rsquo;est aussi ce que reçoit votre service comptabilité (ça aidera pour communiquer avec eux, pour lui expliquer les possibles pics ou autres quand c&amp;rsquo;est nécessaire).&lt;/p&gt;
&lt;h2 id="aws-cost-explorertrusted-advisor"&gt;AWS Cost Explorer/Trusted Advisor
&lt;/h2&gt;&lt;p&gt;AWS fournit 2 outils:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cost Explorer&lt;/strong&gt;: Cela va être votre nouvel meilleur ami. L&amp;rsquo;outil s&amp;rsquo;améliore d&amp;rsquo;année en année et vous permet d&amp;rsquo;analyser et de mettre en graphique tout votre historique de dépenses, de filtrer par tags, service, région, etc. C&amp;rsquo;est vraiment un indispensable et il faut vraiment apprendre à s&amp;rsquo;en servir. La difficulté est de comprendre ce qu&amp;rsquo;on lit, car contrairement aux factures, les détails se basent sur l&amp;rsquo;API AWS et non une simplification des termes comme dans les factures reçues en fin de mois.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Trusted Advisor&lt;/strong&gt;: Lorsque vous souscrivez au support de niveau &lt;strong&gt;Business&lt;/strong&gt;, en plus de donner de bonnes informations liées à la sécurité de votre plateforme, l&amp;rsquo;outil vous donne des informations sur les gâchis financiers présents dans le compte. La nécessité d&amp;rsquo;avoir un haut niveau de support pour que ce soit actif peut être contraignant mais heureusement, les éléments donnés sont relativement simples à obtenir à la main ou via script.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="les-scripts"&gt;Les Scripts
&lt;/h2&gt;&lt;p&gt;Il existe une pléthore de scripts voire d&amp;rsquo;applications complètes sur le web pour aider à analyser ses coûts et trouver les axes d&amp;rsquo;amélioration. Vous pouvez également écrire vos propres scripts pour mettre en avant des points précis liés à votre infrastructure. L&amp;rsquo;avantage de l&amp;rsquo;automatisation est bien entendu de vous faire gagner du temps mais surtout de pouvoir avoir des résultats réguliers et donc de suivre les résultats de vos modifications.&lt;/p&gt;
&lt;p&gt;Voici quelques exemples (les deux premiers sont de moi):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/claranet/go-s3-describe" target="_blank" rel="noopener"
&gt;go-s3-describe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/claranet/aws-inventory-graph" target="_blank" rel="noopener"
&gt;aws-inventory-graph&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/mlabouardy/komiser" target="_blank" rel="noopener"
&gt;komiser&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Et une recherche sur Github avec quelques autres outils: &lt;a class="link" href="https://github.com/search?q=finops&amp;#43;aws&amp;amp;type=Repositories" target="_blank" rel="noopener"
&gt;Résultats&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="saas"&gt;SaaS
&lt;/h2&gt;&lt;p&gt;L&amp;rsquo;engouement pour le &lt;em&gt;FinOps&lt;/em&gt; vient forcément avec son lot de services en ligne pour aider dans la tâche, en voici deux que j&amp;rsquo;ai testés (je ne ferai pas de comparatif, n&amp;rsquo;y ayant pas touché depuis longtemps maintenant):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.cloudhealthtech.com/" target="_blank" rel="noopener"
&gt;Cloudhealth&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://cloudcheckr.com/" target="_blank" rel="noopener"
&gt;Cloudcheckr&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ces outils font plus que du &lt;em&gt;FinOps&lt;/em&gt;, mais comme leurs coûts rentrent dans ce que j&amp;rsquo;appelle les coûts &lt;em&gt;Indirects&lt;/em&gt;, il faut donc les prendre en compte dans vos calculs pour estimer les économies.&lt;/p&gt;
&lt;h2 id="websites"&gt;Websites
&lt;/h2&gt;&lt;p&gt;Le web fourmille de documentations et d&amp;rsquo;articles comme celui-ci, il ne faudra pas hésiter à chercher des heures durant pour apprendre les techniques en vogue pour limiter les coûts ou même décoder la documentation AWS parfois absconde.&lt;/p&gt;
&lt;p&gt;Voici un exemple d&amp;rsquo;outils que l&amp;rsquo;on peut trouver et utiliser fréquemment:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://Instances.vantage.sh" target="_blank" rel="noopener"
&gt;https://Instances.vantage.sh&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://calculator.aws/#/" target="_blank" rel="noopener"
&gt;https://calculator.aws/#/&lt;/a&gt; (calculateur officiel fourni par &lt;em&gt;AWS&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://observablehq.com/@rustyconover/aws-ec2-spot-Instance-simulator" target="_blank" rel="noopener"
&gt;https://observablehq.com/@rustyconover/aws-ec2-spot-Instance-simulator&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="schémas"&gt;Schémas
&lt;/h2&gt;&lt;p&gt;Le &lt;em&gt;FinOps&lt;/em&gt; est un travail technique, même si on épluche bien les factures, il est intéressant d&amp;rsquo;avoir la vision de la plateforme en terme d&amp;rsquo;architecture. Comprendre comment les choses sont pensées, de l&amp;rsquo;Instance aux services managés. Le nec plus ultra étant d&amp;rsquo;avoir également les flux réels et pas juste un schéma de principe, les flux étant souvent très difficiles à catégoriser et encore plus à comprendre niveau facturation.&lt;/p&gt;
&lt;p&gt;Voici un schéma de quelques flux avec les sens pour lesquels AWS vous facture:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://thomas.labarussias.fr/posts/finops/img/aws-flux.png"
width="1962"
height="1076"
srcset="https://thomas.labarussias.fr/posts/finops/img/aws-flux_hu_f089d9598e4cad73.png 480w, https://thomas.labarussias.fr/posts/finops/img/aws-flux_hu_4681a986df45e467.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="182"
data-flex-basis="437px"
&gt;&lt;/p&gt;
&lt;h2 id="la-métrologie"&gt;La Métrologie
&lt;/h2&gt;&lt;p&gt;Tous les &lt;em&gt;Cloud Providers&lt;/em&gt; fournissent leurs propres solutions de métrologie, plus ou moins avancées. Dans le cas d&amp;rsquo;AWS, la solution s&amp;rsquo;appelle &lt;em&gt;Cloudwatch&lt;/em&gt;. Bien que pratiques, il est nécessaire, pour évaluer le bon usage des ressources, d&amp;rsquo;avoir son propre système de métrologie, avec une granularité plus fine, mais surtout plus de métriques.
Prenons le cas de l&amp;rsquo;utilisation CPU, qui est certes rarement un facteur limitant sur des services Web, l&amp;rsquo;utilisation de la mémoire ou les IO étant plus à suivre. Vous n&amp;rsquo;avez aucune information sur les contextes d&amp;rsquo;exécution (&lt;em&gt;user&lt;/em&gt;, &lt;em&gt;system&lt;/em&gt;, &lt;em&gt;steal&lt;/em&gt;, &lt;em&gt;iowait&lt;/em&gt;, &amp;hellip;).
Dans le cas de la RAM, votre &lt;em&gt;Cloud Provider&lt;/em&gt; ne vous fournira pas de détails sur son utilisation, difficile de juger en l&amp;rsquo;état de la pertinence de sa taille pour vos besoins.&lt;/p&gt;
&lt;h2 id="beaucoup-dactions-possibles"&gt;Beaucoup d&amp;rsquo;actions possibles
&lt;/h2&gt;&lt;p&gt;La liste suivante d&amp;rsquo;actions catégorisées &lt;em&gt;FinOps&lt;/em&gt; ne se veut absolument pas complète, chaque service ayant ses spécificités et les modèles de facturation évoluant aussi dans le temps. Encore une fois, même si très orienté &lt;em&gt;AWS&lt;/em&gt;, elles sont tout ou en partie transposables à d&amp;rsquo;autres &lt;em&gt;Cloud Providers&lt;/em&gt;.&lt;/p&gt;
&lt;h3 id="catégoriser-les-actions-à-entreprendre"&gt;Catégoriser les actions à entreprendre
&lt;/h3&gt;&lt;p&gt;Afin de pouvoir mieux évaluer les pertinences des actions préconisées mais aussi de pouvoir les prioriser, j&amp;rsquo;ai pris l&amp;rsquo;habitude de les catégoriser selon 3 critères:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Complexité&lt;/em&gt;: C&amp;rsquo;est souvent un bon moyen pour aider à estimer le temps qui sera nécessaire pour la mise en oeuvre.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Risque&lt;/em&gt;: Notre but, comme explicité dans ma définition, est de ne pas dégrader la production, mais toute action à sa part de risque, surtout lors d&amp;rsquo;une bascule d&amp;rsquo;un morceau d&amp;rsquo;architecture à une autre, ou bien lors de la réduction du type d&amp;rsquo;une Instance.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Economies attendues&lt;/em&gt;: En valeur absolue bien souvent, et à mettre en perspective avec les deux autres critères. Il peut être pertinent de faire une action simple, sans risque qui fait économiser $100 plutôt qu&amp;rsquo;une refonte compliquée qui fera gagner $200 mais demandera 10JH par ailleurs (rappelez-vous, les coûts &lt;em&gt;Indirects&lt;/em&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Lorsque l&amp;rsquo;audit &lt;em&gt;FinOps&lt;/em&gt; est pour un client tiers, cela sera d&amp;rsquo;autant plus important de lui permettre d&amp;rsquo;évaluer les actions qu&amp;rsquo;il voudra mener ou faire mener, lui seul ayant les cordons de sa bourse.&lt;/p&gt;
&lt;h3 id="identifier-et-supprimer-les-gâchis"&gt;Identifier et supprimer les gâchis
&lt;/h3&gt;&lt;p&gt;La première action à laquelle on pense, est bien évidemment de réduire les gâchis. La flexibilité du &lt;em&gt;Cloud&lt;/em&gt; amenant souvent à créer puis laisser traîner des ressources dans un coin.&lt;/p&gt;
&lt;p&gt;Voici une liste de quelques gâchis communs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Snapshots anciens&lt;/em&gt;: Plusieurs cas de figures, soit ce sont des &lt;em&gt;Snapshots&lt;/em&gt; pour des &lt;em&gt;AMI&lt;/em&gt; obsolètes, soit de volumes &lt;em&gt;EBS&lt;/em&gt; n&amp;rsquo;existant plus. Il se peut que ce soit de vieux &lt;em&gt;Snapshots&lt;/em&gt; d&amp;rsquo;&lt;em&gt;EBS&lt;/em&gt; encore en fonctionnement, dans ce cas, comme ils sont sauvegardés de manière incrémentale, leurs suppressions entraîneront un gain moins important sur la facture, les plus récents ayant toujours besoin d&amp;rsquo;une référence.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;AMI Anciennes&lt;/em&gt;: Sauf si cela s&amp;rsquo;avère vraiment nécessaire, il n&amp;rsquo;est pas utile de garder de vieilles &lt;em&gt;AMI&lt;/em&gt;, avec des systèmes et des paquets obsolètes. Leurs suppressions ne font rien gagner à proprement parlé, mais libèrent des &lt;em&gt;Snapshots&lt;/em&gt; qui eux peuvent ensuite être supprimés.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;EIP détachées&lt;/em&gt;: Le gain est minime, mais si vraiment elles ne servent à rien, autant les libérer.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;EBS détachés&lt;/em&gt;: Cela vient souvent de la suppression d&amp;rsquo;&lt;em&gt;Instances&lt;/em&gt; sans suppression des volumes qui les utilisaient. Si en plus il y avait de l&amp;rsquo;&lt;em&gt;AutoScaling&lt;/em&gt; d&amp;rsquo;actif, les volumes peuvent vite monter.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;EBS attachés mais sans IO&lt;/em&gt;: Le coup classique du volume monté sur &lt;code&gt;/logs&lt;/code&gt; mais où aucune application n&amp;rsquo;écrit dedans.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;ELB/ALB/NLB sans Instance ou sans requête&lt;/em&gt;: Il arrivent que des &lt;code&gt;xLB&lt;/code&gt; ne pointent vers rien, ou bien que les &lt;em&gt;Instances&lt;/em&gt; derrières soient &lt;em&gt;Unhealthy&lt;/em&gt; depuis très longtemps, sans aucun impact par ailleurs.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;EC2/RDS dans des anciens types&lt;/em&gt;: A chaque nouvelle famille sortie par &lt;em&gt;AWS&lt;/em&gt;, les prix sont plus faibles, pour parfois de meilleures performances ou options.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;EC2 stoppées depuis longtemps&lt;/em&gt;: Le &lt;em&gt;compute&lt;/em&gt; n&amp;rsquo;est pas payé dans ce cas, seul le stockage, cela peut être légitime ou non. A vous de voir.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Buckets S3 avec des objets de type Reduced Redundancy Storage Class&lt;/em&gt;: AWS a déprécié ce type d&amp;rsquo;objet, en le rendant légèrement plus chère d&amp;rsquo;un millième que le type &lt;em&gt;Standard&lt;/em&gt;, sur des Po voire To, cela vite (histoire vécue avec une plateforme de streaming de musique)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Buckets S3 Buckets qui sont Publics mais pas derrière une distribution CloudFront&lt;/em&gt;: Rien que le fait de sortir sur Internet à travers une distribution &lt;em&gt;Cloudfront&lt;/em&gt; réduit les coûts de bande passante, cache activé ou non. Ceci est valable dans tous les cas, devant &lt;code&gt;xLB&lt;/code&gt; ou &lt;code&gt;EC2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;RDS sans connexion depuis longtemps&lt;/em&gt;: Si la base ne sert que de temps en temps, il est toujours possible de l&amp;rsquo;éteindre (pour 7j maximum, ensuite il faudra éteindre de nouveau).&lt;/li&gt;
&lt;li&gt;&lt;em&gt;RDS utilisant du PIOPS inutile&lt;/em&gt;: Pour chaque GB de &lt;em&gt;GP2/3&lt;/em&gt;, &lt;em&gt;AWS&lt;/em&gt; assure un plancher de 3 IOPS, ce qui implique qu&amp;rsquo;avec 350GB, vous avez plus (1050 IOPS) que les 1000 IOPS demandés à être payés en minimum pour le stockage &lt;em&gt;PIOPS&lt;/em&gt;, et ce pour beaucoup moins cher.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pour vous aider à identifier ces éléments, l&amp;rsquo;&lt;em&gt;API&lt;/em&gt; et les métriques en votre possession seront très utiles.&lt;/p&gt;
&lt;h3 id="utiliser-correctement-les-ressources"&gt;Utiliser correctement les ressources
&lt;/h3&gt;&lt;h4 id="les-ressources-managées"&gt;Les ressources managées
&lt;/h4&gt;&lt;p&gt;Avec l&amp;rsquo;avènement du &lt;em&gt;Cloud&lt;/em&gt;, sa souplesse et sa rapidité pour obtenir des ressources, on en vient presque à oublier les réflexes de nos prédécesseurs, contraints à tirer jusqu&amp;rsquo;à la dernière goutte de sève des machines achetées pour plusieurs années.
Je crois fermement, qu&amp;rsquo;avant d&amp;rsquo;entamer des changements de type, surtout lors de &lt;em&gt;Scale Up&lt;/em&gt; (augmentation du type), il faut travailler au niveau de l&amp;rsquo;&lt;em&gt;OS&lt;/em&gt; et des applications pour obtenir le maximum. Tout résoudre par de l&amp;rsquo;infra n&amp;rsquo;a jamais été pertinent (le fameux plus de RAM, toujours plus de RAM, au lieu de traiter la fuite mémoire).&lt;/p&gt;
&lt;h4 id="los-et-les-applications"&gt;L&amp;rsquo;OS et les Applications
&lt;/h4&gt;&lt;p&gt;Dans le cas des ressources managées, surtout &lt;em&gt;RDS&lt;/em&gt;, de très nombreux réglages sont à disposition pour paramétrer les moteurs (taille des &lt;em&gt;buffers&lt;/em&gt;, allocation de tables temporaires, nombre max de connexions, etc). Les ajuster au réel besoin métier peut parfois changer du tout au tout les performances.&lt;/p&gt;
&lt;p&gt;Pour les EC2, c&amp;rsquo;est encore plus vrai, car on peut jouer sur bien plus de réglages comme:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;les &lt;em&gt;paramètres sysctl&lt;/em&gt;: Tous les &lt;em&gt;OS Unix-Like&lt;/em&gt; permettent de régler des paramètres du &lt;em&gt;kernel&lt;/em&gt;, dont beaucoup de limites. En ajustant ces valeurs, on peut souvent repousser les capacités utilisables.&lt;/li&gt;
&lt;li&gt;les &lt;em&gt;configurations des applications&lt;/em&gt;: La majorité des applications, surtout dans le monde du &lt;em&gt;Web OpenSource&lt;/em&gt;, permettent d&amp;rsquo;être configurées jusqu&amp;rsquo;au plus petit détails pour assurer leurs charges (&lt;em&gt;worker_processes&lt;/em&gt; ou &lt;em&gt;keepalives&lt;/em&gt; pour &lt;em&gt;Nginx&lt;/em&gt; par exemple).&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="compiler-ses-binaires"&gt;Compiler ses binaires
&lt;/h4&gt;&lt;p&gt;Une autre option, bien moins répandue, car plus difficile à mettre en oeuvre, est le fait d&amp;rsquo;utiliser des binaires compilés pour l&amp;rsquo;architecture &lt;em&gt;CPU&lt;/em&gt; de l&amp;rsquo;&lt;em&gt;EC2&lt;/em&gt; utilisée. Cela peut paraître farfelu, surtout que cela apporte une grande complexité et sort totalement du cadre des gestionnaires de paquets si pratiques. Mais après tout, utiliser des binaires compilés en dehors de toute arborescence, c&amp;rsquo;est une chose très répandue, et cela s&amp;rsquo;appelle un &lt;em&gt;Container&lt;/em&gt; 😉. AWS fournit pour chaque type d&amp;rsquo;&lt;em&gt;Instance&lt;/em&gt; le modèle de &lt;em&gt;CPU&lt;/em&gt; associé, à votre charge de trouver les bons &lt;em&gt;flags&lt;/em&gt; à utiliser pour la compilation, et de penser à les modifier à chaque changement de type (par un exemple, un rendu &lt;em&gt;Blender&lt;/em&gt; via le &lt;em&gt;CPU&lt;/em&gt; peut gagner jusqu&amp;rsquo;à 30% de temps [du vécu], imaginez pour la capacité de traitements de requêtes par un &lt;em&gt;Apache&lt;/em&gt; ou &lt;em&gt;Nginx/PHP-FPM&lt;/em&gt;).&lt;/p&gt;
&lt;h3 id="utiliser-les-services-managés"&gt;Utiliser les services managés
&lt;/h3&gt;&lt;p&gt;Utiliser des services managés a un coût, c&amp;rsquo;est indéniable, mais ils sont à relativiser et à mettre en perspective avec les coûts &lt;em&gt;Indirects&lt;/em&gt;. Entre un &lt;em&gt;PostgreSQL&lt;/em&gt; managé et un &lt;em&gt;PostgreSQL&lt;/em&gt; installé à la main sur un serveur loué, il se peut que la solution du &lt;em&gt;Cloud Provider&lt;/em&gt; soit plus chère, mais si vous rajoutez dans votre solution maison les coûts financiers et humains pour la gestion des backups, des possibles restaurations, de la haute disponibilité, etc, sans avoir en plus forcément la capacité de changer la taille de la machine ou agrandir son stockage, la balance ne penche plus du même côté. Encore une fois, s&amp;rsquo;arrêter uniquement aux coûts matériels (qui se rattachent aux coûts &lt;em&gt;Directs&lt;/em&gt;) et ne pas prendre l&amp;rsquo;ensemble du périmètre financier, peut s&amp;rsquo;avérer contre-productif.&lt;/p&gt;
&lt;h3 id="mettre-en-place-des-outils-des-procédures-des-formations"&gt;Mettre en place des outils, des procédures, des formations
&lt;/h3&gt;&lt;p&gt;Je conseille généralement de commencer par tout faire manuellement, que ce soit l&amp;rsquo;analyse des coûts dans le &lt;em&gt;Cost Explorer&lt;/em&gt;, la recherche des gâchis ou l&amp;rsquo;estimation des économies possibles. Cela dans le but de vraiment comprendre comment les choses fonctionnent et de pouvoir repérer d&amp;rsquo;un coup d&amp;rsquo;oeil des axes d&amp;rsquo;améliorations une fois que l&amp;rsquo;habitude est faîte.
Une fois rodé, il est temps de mettre en place des procédures, et si possible des outils automatisés pour limiter les dérives dans le temps. L&amp;rsquo;automatisation des procédures de nettoyage et d&amp;rsquo;extinction des environnements en dehors des heures ouvrées sont des grands classiques, on trouve de nombreux exemples sur le net.
Comme évoqué plus haut, c&amp;rsquo;est à ce niveau que les alertes de &lt;em&gt;Budget&lt;/em&gt; peuvent aussi apporter leurs aides, même si elles peuvent souvent s&amp;rsquo;avérer trop rigides (une période de soldes peut exploser les compteurs par rapport au mois d&amp;rsquo;avant, sans que cela soit inquiétant, bien au contraire).
Un volet à ne pas négliger à cette étape (à toutes en fait), est de former les équipes (chez soi ou chez son client), à ce qu&amp;rsquo;est le &lt;em&gt;FinOps&lt;/em&gt;, ce qu&amp;rsquo;il apporte et sur les procédures en cours dans l&amp;rsquo;entreprise qui font partie de son processus.&lt;/p&gt;
&lt;h3 id="architecturer-pour-réduire-les-coûts"&gt;Architecturer pour réduire les coûts
&lt;/h3&gt;&lt;p&gt;C&amp;rsquo;est la méthode la plus complexe, mais souvent la plus efficace et gratifiante, la refonte. Les &lt;em&gt;Cloud Providers&lt;/em&gt; sortent en permanence de nouvelles fonctionnalités et nouveaux services, ce qui est impossible aujourd&amp;rsquo;hui ne le sera possiblement plus dans 1 ou 2 ans. Intégrer le &lt;em&gt;FinOps&lt;/em&gt; lors de la conception d&amp;rsquo;une plateforme est important pour être efficient, mais cela l&amp;rsquo;est encore plus lors des refontes, qui peuvent souvent être dictées pour des raisons de rationalisation et/ou d&amp;rsquo;économies. Cela est d&amp;rsquo;autant plus pertinent que vous avez alors une vraie expérience du comportement de votre plateforme, de ses besoins et contraintes.&lt;/p&gt;
&lt;p&gt;On peut envisager dans le cas d&amp;rsquo;une refonte de:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;migrer certaines fonctions dans &lt;em&gt;Lambda&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;utiliser &lt;em&gt;DynamoDB&lt;/em&gt; en base &lt;em&gt;NoSQL&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;utiliser des &lt;em&gt;ALB&lt;/em&gt; devant les &lt;em&gt;Lambda&lt;/em&gt; et non des &lt;em&gt;API Gateway&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Il faut garder à l&amp;rsquo;esprit encore une fois, que toutes les actions ont des coûts &lt;em&gt;Indirects&lt;/em&gt; (JH pour migrer le code d&amp;rsquo;une solution technique à une autre, formations, etc), et peuvent vous &amp;ldquo;verrouiller&amp;rdquo; chez un &lt;em&gt;Cloud Provider&lt;/em&gt;, on touche là, à la politique de l&amp;rsquo;entreprise.&lt;/p&gt;
&lt;h3 id="politiqes-de-scale-inout"&gt;Politiqes de Scale In/Out
&lt;/h3&gt;&lt;p&gt;La capacité d&amp;rsquo;adapter la flotte de machines à la charge est une fonctionnalité de base, c&amp;rsquo;est presque la raison première de l&amp;rsquo;existence du &lt;em&gt;Cloud&lt;/em&gt;. Avec le temps, que ce soit en natif ou via des fonctions externes, on peut piloter les groupes d&amp;rsquo;&lt;em&gt;AutoScaling&lt;/em&gt; pour faire beaucoup de choses comme:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Retirer tout ou partie des machines en dehors des heures ouvrées&lt;/li&gt;
&lt;li&gt;Changer la taille des &lt;em&gt;Instances&lt;/em&gt; en fonction des périodes&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Scale In/Out&lt;/em&gt; (ajouter/retirer) en fonction de métriques métiers et non juste le &lt;em&gt;CPU&lt;/em&gt; (qui est rarement une métrique pertinente, je le rappelle)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="réservations--saving-plans"&gt;Réservations / Saving Plans
&lt;/h3&gt;&lt;p&gt;Si vous êtes prêt à vous engager sur du long terme (1 ou 3 ans), réserver des ressources est le moyen le plus direct d&amp;rsquo;obtenir au moins 30% d&amp;rsquo;économie (avec versement d&amp;rsquo;un account ou non) sur des services tels que:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;EC2&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;RDS&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Elasticache&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;DynamoDB&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Les cas de &lt;em&gt;DynamoDB&lt;/em&gt; et &lt;em&gt;Elasticache&lt;/em&gt; sont un peu particulier, le premier demandant de réserver des capacités en &lt;em&gt;Read/Write&lt;/em&gt; et non des ressources &amp;ldquo;matérielles&amp;rdquo; et le second imposant un acompte dans tous les cas.&lt;/p&gt;
&lt;p&gt;Pour rappel, les réservations fonctionnent avec des unités de temps, il ne s&amp;rsquo;agit pas de machines avec une étiquette à son nom dans le datacenter &lt;em&gt;AWS&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Prenons un exemple pour expliciter les choses.&lt;/p&gt;
&lt;p&gt;Imaginons que vous réserviez pour 1 an, pour de l&amp;rsquo;&lt;em&gt;EC2&lt;/em&gt;, 1 &lt;em&gt;&amp;ldquo;Instance&amp;rdquo;&lt;/em&gt; &lt;code&gt;m5.xlarge&lt;/code&gt;. Vous obtenez donc, 4 unités (cf ce &lt;a class="link" href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/apply_ri.html" target="_blank" rel="noopener"
&gt;tableau&lt;/a&gt;) par mois dans la famille &lt;code&gt;m5&lt;/code&gt;. En prenant qu&amp;rsquo;un mois fait en moyenne 732h, vous aurez donc le droit au prix réduit pour:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;732h de &lt;code&gt;m5.xlarge&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;1464h de &lt;code&gt;m5.large&lt;/code&gt; (soit 2 Instances)&lt;/li&gt;
&lt;li&gt;366h de &lt;code&gt;m5.2xlarge&lt;/code&gt; (soit 1 Instance allumée la moitié du mois)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Les unités sont circonscrites à une famille, c&amp;rsquo;est exactement le même cas pour les &lt;em&gt;Saving Plans&lt;/em&gt; de type &lt;em&gt;EC2 Instance&lt;/em&gt; (les économies sont à la virgule près les mêmes que pour les Réservations). Si vous voulez ne pas être contraint, et ne raisonner qu&amp;rsquo;en termes d&amp;rsquo;unités de calcul et non de &amp;ldquo;famille&amp;rdquo;, les &lt;em&gt;Saving Plans&lt;/em&gt; de type &lt;em&gt;Compute&lt;/em&gt;, sont la nouvelle méthode pour procéder à des réservations chez &lt;em&gt;AWS&lt;/em&gt;, peu importe la famille ou le type. Les réductions sur le &lt;em&gt;Compute&lt;/em&gt; s&amp;rsquo;appliquant peu importe le type, cela vous permet de changer de famille quand vous le souhaitez. Cela vient cependant avec une économie moindre.&lt;/p&gt;
&lt;h3 id="spot-instances"&gt;Spot Instances
&lt;/h3&gt;&lt;p&gt;&lt;em&gt;AWS&lt;/em&gt; met à disposition son stock d&amp;rsquo;invendus (en quelque sorte) à prix cassé (jusqu&amp;rsquo;à -70%), ce qu&amp;rsquo;ils appellent des &lt;em&gt;Spot Instances&lt;/em&gt;. Le principe est simple, vous définissez un prix maximal pour lequel vous êtes prêt à payer, et tant que le prix courant est inférieur et qu&amp;rsquo;&lt;em&gt;AWS&lt;/em&gt; a du stock, vous êtes susceptible d&amp;rsquo;avoir votre &lt;em&gt;Instance&lt;/em&gt;. Si un des critères n&amp;rsquo;est plus respecté, &lt;em&gt;AWS&lt;/em&gt; vous prévient 2min avant de vous retirer l&amp;rsquo;&lt;em&gt;Instance&lt;/em&gt;. Pour mitiger les risques, vous avez la possibilité de vous faire des flottes, c&amp;rsquo;est-à-dire des groupes d&amp;rsquo;&lt;em&gt;Instances&lt;/em&gt; de différents types.&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;est un moyen extrêmement puissant pour faire des économies, à condition que l&amp;rsquo;usage que vous en faîtes tolère de perdre des noeuds, c&amp;rsquo;est donc très souvent utilisé pour faire des tests au sein d&amp;rsquo;une &lt;em&gt;CI&lt;/em&gt;, par exemple.&lt;/p&gt;
&lt;p&gt;Un autre aspect à prendre en compte et qui permet de limiter encore plus les risques, c&amp;rsquo;est de mixer des &lt;em&gt;Instances&lt;/em&gt; &lt;em&gt;On-Demand&lt;/em&gt; (payées au prix public annoncé) et des &lt;em&gt;Instances&lt;/em&gt; &lt;em&gt;Spot&lt;/em&gt;. C&amp;rsquo;est désormais possible avec les &lt;em&gt;Launch Templates&lt;/em&gt; qui définissent comment doivent être les &lt;em&gt;Instances&lt;/em&gt; d&amp;rsquo;un groupe d&amp;rsquo;&lt;em&gt;Auto-Scaling&lt;/em&gt;. Vous définissez le nombre d&amp;rsquo;&lt;em&gt;Instances&lt;/em&gt; &lt;em&gt;On-Demand&lt;/em&gt; qui constitueront votre base, puis le pourcentage d&amp;rsquo;&lt;em&gt;On-Demand&lt;/em&gt; au dessus cette base par rapport aux &lt;em&gt;Instances&lt;/em&gt; &lt;em&gt;Spot&lt;/em&gt;. Si votre base &lt;em&gt;On-Demand&lt;/em&gt; correspond à vos réservations, l&amp;rsquo;économie est encore plus importante avec un risque contrôlé.&lt;/p&gt;
&lt;h3 id="organisation-des-comptes"&gt;Organisation des comptes
&lt;/h3&gt;&lt;p&gt;La bonne pratique est d&amp;rsquo;isoler les environnements (prod, staging, etc) dans des comptes &lt;em&gt;AWS&lt;/em&gt; différents. Isoler les comptes les uns des autres permet, entre autres:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;d&amp;rsquo;assurer l&amp;rsquo;étanchéité pour la sécurité&lt;/li&gt;
&lt;li&gt;de bien séparer les coûts, ce qui facilite les analyses (un flux sortant est un flux sortant, &lt;em&gt;AWS&lt;/em&gt; ne vous dira pas de quelle &lt;em&gt;VPC&lt;/em&gt; précisément il vient, difficile de refacturer entre &lt;em&gt;cost centers&lt;/em&gt; dans ce cas)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A côté de cela il est très intéressant de regrouper tous ces comptes au sein d&amp;rsquo;une seule organisation, avec un compte payeur identifié (appelé compte consolidant) et ne possédant aucune ressource (pour simplifier les analyses, de cette manière il n&amp;rsquo;apparaîtra pas 2 fois, en tant que compte et compte consolidant).&lt;/p&gt;
&lt;p&gt;Il y a plusieurs avantages à faire cela, le compte payeur agrégeant la totalité de la facture:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;les réservations sont remontées au niveau du compte consolidant (sauf paramétrage volontaire), ce qui implique que les unités non utilisées d&amp;rsquo;un côté peuvent l&amp;rsquo;être de l&amp;rsquo;autre, vous ne payez pas pour rien&lt;/li&gt;
&lt;li&gt;vous bénéficiez des tarifs sur les volumes (au sens de quantité), ce qu&amp;rsquo;on appelle les &lt;em&gt;Blended Costs&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;AWS&lt;/em&gt; fournit une facture récapitulative de l&amp;rsquo;ensemble des frais, ce qui fera plaisir au service comptable qui n&amp;rsquo;aura pas à gérer N pdf.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Les &lt;em&gt;Blended Costs&lt;/em&gt; sont une manière d&amp;rsquo;agréger tous les volumes de certains services et de bénéficier ainsi des tranches de prix inférieures.&lt;/p&gt;
&lt;p&gt;Prenons comme exemple &lt;em&gt;S3&lt;/em&gt; pour expliciter la chose.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Imaginons deux comptes liés A et B à un compte consolidant Z.
Les usages S3 sont respectivement:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;50To en eu-west-3 pour le compte A&lt;/li&gt;
&lt;li&gt;30To en eu-west-3 pour le compte B&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si les comptes étaient facturés séparément, il devraient:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;compte A: &lt;code&gt;40To x 0,024$/GB = $960&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;compte B: &lt;code&gt;30To x 0,024$/GB = $720&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;total: &lt;code&gt;$1680&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Avec les Blended Costs, le compte Z consolidant le tout paiera en fait:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;50To x 0,024$/GB + 20To x 0,023$/GB = $1620&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Le principe sous-jacent étant que pour S3, en eu-west-3, les 50 premiers To valent &lt;code&gt;0,024$/GB&lt;/code&gt; et &lt;code&gt;0,023$/GB&lt;/code&gt; au delà.&lt;/p&gt;
&lt;p&gt;On a donc une économie de $60, sans aucune action autre qu&amp;rsquo;avoir lié les comptes A et B à Z.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(voir &lt;a class="link" href="https://aws.amazon.com/fr/s3/pricing/" target="_blank" rel="noopener"
&gt;ICI&lt;/a&gt; pour les tarifs de &lt;em&gt;S3&lt;/em&gt;)&lt;/p&gt;
&lt;h2 id="tags"&gt;Tags
&lt;/h2&gt;&lt;p&gt;On touche au nerf de la guerre, les &lt;em&gt;Tags&lt;/em&gt;. Il est essentiel pour comprendre les coûts, voire de les anticiper, de catégoriser au maximum les choses, et cela passe par le tagging des ressources qui le peuvent (on ne peut pas tagger les flux réseau, par exemple).&lt;/p&gt;
&lt;p&gt;Voici quelques tags utiles:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;environnement&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;project&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;businessUnit&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;costCenter&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;scope&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;team&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Il y a un point très important à savoir, les tags sont sensibles à la casse au niveau des clés et des valeurs, il faut donc être vigilant pour ne pas avoir des &lt;code&gt;prod&lt;/code&gt;, &lt;code&gt;Prod&lt;/code&gt;, &lt;code&gt;production&lt;/code&gt;, etc, qui représentent la même valeur mais créent du bruit, voire peuvent cacher certaines ressources de vos rapports.&lt;/p&gt;
&lt;p&gt;Pour vous aider dans votre rattrapage, dans le cas où vous avez des ressources créées à la main, &lt;em&gt;AWS&lt;/em&gt; fournit un outil au final assez méconnu, le &lt;a class="link" href="https://docs.aws.amazon.com/ARG/latest/userguide/tag-editor.html" target="_blank" rel="noopener"
&gt;&lt;em&gt;Tag Editor&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;Cet article n&amp;rsquo;est finalement qu&amp;rsquo;une ébauche de tout ce qu&amp;rsquo;on peut faire sans vraiment rentrer dans les détails de comment on le fait. Il ne représente qu&amp;rsquo;une synthèse de mes réflexions, dont les conclusions sont sûrement discutables (et peut-être obsolètes maintenant, le monde du &lt;em&gt;Cloud&lt;/em&gt; bougeant tellement vite). Vous avez sûrement remarqué qu&amp;rsquo;il y a un grand absent dans cet article, quid du &lt;em&gt;FinOps&lt;/em&gt; quand on utilise &lt;em&gt;Kubernetes&lt;/em&gt;? A l&amp;rsquo;époque où je faisais encore des audits &lt;em&gt;FinOps&lt;/em&gt;, bien qu&amp;rsquo;utilisant &lt;em&gt;K8S&lt;/em&gt; en production, je n&amp;rsquo;avais jamais eu à creuser sérieusement la question. Je pense cependant que les principes généraux que j&amp;rsquo;ai mentionnés peuvent s&amp;rsquo;appliquer en partie, dans le cas d&amp;rsquo;un environnement avec des ressources mutualisées comme l&amp;rsquo;est &lt;em&gt;Kubernetes&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Merci d&amp;rsquo;avoir lu jusqu&amp;rsquo;au bout ce long article, et j&amp;rsquo;espère qu&amp;rsquo;il aura été utile à quelqu&amp;rsquo;un, il m&amp;rsquo;a au moins permis de sortir de ma tête quelque chose qui y traînait depuis longtemps.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Enjoy&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Falco: Détection et réaction aux menaces dans Kubernetes</title><link>https://thomas.labarussias.fr/posts/cncf-meetup-paris-mars-2021/</link><pubDate>Tue, 06 Apr 2021 00:00:00 +0000</pubDate><guid>https://thomas.labarussias.fr/posts/cncf-meetup-paris-mars-2021/</guid><description>&lt;p&gt;J&amp;rsquo;ai enregistré il y a quelques jours une présentation traitant de &lt;code&gt;falco&lt;/code&gt; et &lt;code&gt;falcosidekick&lt;/code&gt; pour un Meetup CNCF Paris. J&amp;rsquo;y aborde ce que sont &lt;code&gt;falco&lt;/code&gt; et &lt;code&gt;falcosidekick&lt;/code&gt; et je montre comment on peut se servir des &lt;em&gt;outputs&lt;/em&gt; de &lt;code&gt;falcosidekick&lt;/code&gt; pour réagir en cas de détection de comportements suspects.&lt;/p&gt;
&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/UCXyHRhPbdg?start=2138"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Enjoy&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Monitorer son application Go en local</title><link>https://thomas.labarussias.fr/posts/monitorer-golang-app-local/</link><pubDate>Sat, 27 Jun 2020 00:00:00 +0000</pubDate><guid>https://thomas.labarussias.fr/posts/monitorer-golang-app-local/</guid><description>&lt;p&gt;Récemment, après plusieurs jours en production, nous avons détecté au boulot que notre pod &lt;a class="link" href="https://github.com/Issif/cercat" target="_blank" rel="noopener"
&gt;Cercat&lt;/a&gt; semblait avoir une &lt;em&gt;memory leak&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Rien de complexe dans notre cas (ouf), cela a facilement été réglé à coup de &lt;em&gt;profiles Go&lt;/em&gt; mais une question s&amp;rsquo;est posée : &lt;em&gt;&amp;ldquo;Aurais-je pu le détecter avant d&amp;rsquo;envoyer en prod en sachant que l&amp;rsquo;évolution de la consommation mémoire était relativement lente?&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://thomas.labarussias.fr/posts/monitorer-golang-app-local/img/cercat-memory-leak.png"
width="2824"
height="810"
srcset="https://thomas.labarussias.fr/posts/monitorer-golang-app-local/img/cercat-memory-leak_hu_387ac51a4d525200.png 480w, https://thomas.labarussias.fr/posts/monitorer-golang-app-local/img/cercat-memory-leak_hu_c468438cbf63fa30.png 1024w"
loading="lazy"
alt="cercat memory leak"
class="gallery-image"
data-flex-grow="348"
data-flex-basis="836px"
&gt;&lt;/p&gt;
&lt;p&gt;Je me suis donc mis en tête d&amp;rsquo;avoir une solution clé en main pour &lt;em&gt;monitorer&lt;/em&gt; en local une application &lt;em&gt;Go&lt;/em&gt; lors de son développement.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;idée, très simple au final, est d&amp;rsquo;utiliser une instance de &lt;a class="link" href="https://github.com/netdata/netdata" target="_blank" rel="noopener"
&gt;Netdata&lt;/a&gt; dans un &lt;em&gt;Docker&lt;/em&gt; qui appelle l&amp;rsquo;endpoint &lt;em&gt;expvar&lt;/em&gt; de mon application &lt;em&gt;Go&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Micro tuto pour comprendre le principe :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Préparer notre application&lt;/p&gt;
&lt;p&gt;Un micro code pour l&amp;rsquo;exemple :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;expvar&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// package pour exposer les métriques Go par défaut et notre métrique custom&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;math/rand&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;net/http&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;time&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fake&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="nx"&gt;expvar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NewFloat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;custom.fake&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// une métrique custom complètement fausse &lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ListenAndServe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;:1111&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// on démarre un serveur http sur le port 1111&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// une boucle qui met à jour aléatoirement notre métrique custom&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fake&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Float64&lt;/span&gt;&lt;span class="p"&gt;()&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="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Intn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&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="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Le code est commenté pour comprendre à quoi sert chaque ligne.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;On prépare la configuration de &lt;em&gt;Netdata&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;go_expvar.conf&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;#39;golang-app&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;golang-app&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# le nom de notre app Go dans Netdata&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;http://golang-app:1111/debug/vars&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# le port est à adapter en fonction de l&amp;#39;application&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;collect_memstats&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# on active la collecte des métriques mémoires&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;extra_charts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# la collecte de notre métrique custom&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;custom&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;fake&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;custom&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;units&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;no&lt;/span&gt;-&lt;span class="l"&gt;unit&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;custom&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;expvar.custom.fake&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;chart_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;line&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- {&lt;span class="nt"&gt;expvar_key: &amp;#39;custom.fake&amp;#39;, expvar_type: float, id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;custom_fake}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;python.d.conf&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;go_expvar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;yes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# active le monitoring des applications Go&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;On démarre le tout via &lt;em&gt;docker-compose&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker-compose.yaml&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;3&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;netdata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;netdata/netdata:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;container_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;netdata&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;19999:19999&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;${PWD}/python.d.conf:/etc/netdata/python.d.conf:ro&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# pour activer le monitoring des applications GO&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;${PWD}/go_expvar.conf:/etc/netdata/python.d/go_expvar.conf:ro&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# pour configurer la collecte des métriques des applications Go&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;/etc/passwd:/host/etc/passwd:ro&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;/etc/group:/host/etc/group:ro&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;/proc:/host/proc:ro&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;/sys:/host/sys:ro&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;/var/run/docker.sock:/var/run/docker.sock:ro&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# pour moniter le Docker Go&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cap_add&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;SYS_PTRACE&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;security_opt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;apparmor:unconfined&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;golang-app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;golang:alpine&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;container_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;golang-app&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;1111:1111&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# le port d&amp;#39;écoute de notre application, à adapter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;${PWD}:/app&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;working_dir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/app&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;go run main.go &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# la commande pour lancer l&amp;#39;application, à adapter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Le plus important est d&amp;rsquo;adapter le port d&amp;rsquo;écoute et la commande de démarrage en fonction de votre application.&lt;/p&gt;
&lt;p&gt;On démarre tout :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker-compose -f docker-compose.yaml up -d
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;On vérifie que tout est bien démarré :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ docker ps
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;5f9a07fa2e1f netdata/netdata:latest &lt;span class="s2"&gt;&amp;#34;/usr/sbin/run.sh&amp;#34;&lt;/span&gt; About a minute ago Up About a minute &lt;span class="o"&gt;(&lt;/span&gt;healthy&lt;span class="o"&gt;)&lt;/span&gt; 0.0.0.0:19999-&amp;gt;19999/tcp netdata
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;4e9d30d12bec golang:alpine &lt;span class="s2"&gt;&amp;#34;go run main.go&amp;#34;&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt; days ago Up About a minute 0.0.0.0:1111-&amp;gt;1111/tcp golang-app
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;L&amp;rsquo;instance &lt;em&gt;Netdata&lt;/em&gt; est accessible via &lt;a class="link" href="http://localhost:19999" target="_blank" rel="noopener"
&gt;http://localhost:19999&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Après quelques secondes on obtient nos métriques.&lt;/p&gt;
&lt;p&gt;Les métriques du container de notre application :&lt;/p&gt;
&lt;p&gt;&lt;img src="https://thomas.labarussias.fr/posts/monitorer-golang-app-local/img/netdata_golang_1.png"
width="1905"
height="955"
srcset="https://thomas.labarussias.fr/posts/monitorer-golang-app-local/img/netdata_golang_1_hu_d24007b824a86d3b.png 480w, https://thomas.labarussias.fr/posts/monitorer-golang-app-local/img/netdata_golang_1_hu_3de1aab8dafc5a06.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="199"
data-flex-basis="478px"
&gt;&lt;/p&gt;
&lt;p&gt;Les métriques &lt;em&gt;expvar&lt;/em&gt; de notre application :&lt;/p&gt;
&lt;p&gt;&lt;img src="https://thomas.labarussias.fr/posts/monitorer-golang-app-local/img/netdata_golang_2.png"
width="1905"
height="955"
srcset="https://thomas.labarussias.fr/posts/monitorer-golang-app-local/img/netdata_golang_2_hu_1b8c92edf2077fe3.png 480w, https://thomas.labarussias.fr/posts/monitorer-golang-app-local/img/netdata_golang_2_hu_8f7514472e366e65.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="199"
data-flex-basis="478px"
&gt;&lt;/p&gt;
&lt;p&gt;Notre métrique custom :&lt;/p&gt;
&lt;p&gt;&lt;img src="https://thomas.labarussias.fr/posts/monitorer-golang-app-local/img/netdata_golang_3.png"
width="1633"
height="271"
srcset="https://thomas.labarussias.fr/posts/monitorer-golang-app-local/img/netdata_golang_3_hu_2cd042be8c60b6a.png 480w, https://thomas.labarussias.fr/posts/monitorer-golang-app-local/img/netdata_golang_3_hu_abc10117540262d2.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="602"
data-flex-basis="1446px"
&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Mettre à jour notre application&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;est très simple, il suffit de redémarrer le container &lt;em&gt;Go&lt;/em&gt; :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ docker restart 4e9d30d12bec
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;em&gt;Enjoy&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Cercat</title><link>https://thomas.labarussias.fr/posts/cercat/</link><pubDate>Fri, 17 Apr 2020 00:00:00 +0000</pubDate><guid>https://thomas.labarussias.fr/posts/cercat/</guid><description>&lt;p&gt;En cette période de confinement, les &lt;em&gt;phishers&lt;/em&gt; s&amp;rsquo;en donnent à coeur joie. La question qui se pose alors est : &lt;strong&gt;Comment les détecter le plus tôt possible?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Comme les sites de &lt;em&gt;phishing&lt;/em&gt; servent souvent à récupérer des données confidentielles (n° de carte, mots de passe, etc), ils profitent de toutes les méthodes récentes pour récupérer des certificats gratuits afin de se donner une belle image avec un joli cadenas dans la barre d&amp;rsquo;URL.&lt;/p&gt;
&lt;p&gt;Quelques recherches sur ce sujet m&amp;rsquo;a fait découvrir un superbe projet de chez &lt;strong&gt;Calidog&lt;/strong&gt; : &lt;a class="link" href="https://certstream.calidog.io/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;CertStream&lt;/strong&gt;&lt;/a&gt;. Ils mettent à disposition un flux donnant en temps réel les certificats émis par &lt;em&gt;Let&amp;rsquo;s Encrypt&lt;/em&gt;, &lt;em&gt;Cloudflare&lt;/em&gt;, &lt;em&gt;AWS&lt;/em&gt;, &amp;hellip;&lt;/p&gt;
&lt;p&gt;Il ne reste plus qu&amp;rsquo;à s&amp;rsquo;y connecter, faire une correspondance des domaines avec une &lt;em&gt;regexp&lt;/em&gt; pour avoir en temps réel, les possibles sites de &lt;em&gt;phishing&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;D&amp;rsquo;autres ont eu la même idée : &lt;a class="link" href="https://github.com/AssuranceMaladieSec/CertStreamMonitor" target="_blank" rel="noopener"
&gt;&lt;strong&gt;CertStreamMonitor&lt;/strong&gt;&lt;/a&gt; mais les performances m&amp;rsquo;ont déçu (100% d&amp;rsquo;utilisation permanente d&amp;rsquo;un CORE) et j&amp;rsquo;ai trouvé intéressant de le faire moi-même.&lt;/p&gt;
&lt;p&gt;Je vous présente donc &lt;strong&gt;&lt;a class="link" href="https://github.com/Issif/cercat" target="_blank" rel="noopener"
&gt;Cercat&lt;/a&gt;&lt;/strong&gt; aka &lt;em&gt;Certificate Catcher&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Le principe est simple, le service se connecte via &lt;em&gt;websocket&lt;/em&gt; au &lt;em&gt;stream&lt;/em&gt; de &lt;strong&gt;Certstream&lt;/strong&gt;, compare le domaine certifié à une &lt;em&gt;regexp&lt;/em&gt; et si il y a correspondance, un message est posté sur &lt;strong&gt;Slack&lt;/strong&gt; :&lt;/p&gt;
&lt;p&gt;&lt;img src="https://raw.githubusercontent.com/issif/cercat/master/screenshot.png"
loading="lazy"
alt="Certcat slack screenshot"
&gt;&lt;/p&gt;
&lt;p&gt;et dans les logs :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2020/04/14 17:29:40 [INFO] : A certificate for &amp;#39;www.XXXX.fr&amp;#39; has been issued : {&amp;#34;domain&amp;#34;:&amp;#34;www.XXXX.fr&amp;#34;,&amp;#34;SAN&amp;#34;:[&amp;#34;www.XXXX.fr&amp;#34;],&amp;#34;issuer&amp;#34;:&amp;#34;Let&amp;#39;s Encrypt&amp;#34;,&amp;#34;Addresses&amp;#34;:[&amp;#34;XX.XX.XX.183&amp;#34;,&amp;#34;XX.XX.XX.182&amp;#34;]}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2020/04/14 17:29:41 [INFO] : A certificate for &amp;#39;XXXX.fr&amp;#39; has been issued : {&amp;#34;domain&amp;#34;:&amp;#34;XXXX.fr&amp;#34;,&amp;#34;SAN&amp;#34;:[&amp;#34;mail.XXXX.fr&amp;#34;,&amp;#34;XXXX.fr&amp;#34;,&amp;#34;www.XXXX.fr&amp;#34;],&amp;#34;issuer&amp;#34;:&amp;#34;Let&amp;#39;s Encrypt&amp;#34;,&amp;#34;Addresses&amp;#34;:[&amp;#34;XX.XX.XX.108&amp;#34;]}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;La configuration est dans le &lt;a class="link" href="https://github.com/Issif/cercat/blob/master/README.md" target="_blank" rel="noopener"
&gt;README&lt;/a&gt; et des binaires pré-compilés sont fournis &lt;a class="link" href="https://github.com/Issif/cercat/releases" target="_blank" rel="noopener"
&gt;ICI&lt;/a&gt; parce que je suis gentil.&lt;/p&gt;
&lt;p&gt;En faisant des tests sur les domaines en &lt;code&gt;.fr&lt;/code&gt; je suis d&amp;rsquo;ailleurs tombé sur ça, un bel exemple de &lt;em&gt;phishing&lt;/em&gt; :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;domain&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;google-france.fr&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;SAN&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;eset.fr.nf&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;google-france.fr&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;page-accueil.info&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;www.eset.fr.nf&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;www.google-france.fr&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;www.page-accueil.info&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;issuer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Let&amp;#39;s Encrypt&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Addresses&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;X.X.X.24&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;En espérant que ça serve à d&amp;rsquo;autres.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Enjoy&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Falcosidekick 100k Pulls</title><link>https://thomas.labarussias.fr/posts/falcosidekick-100k-pulls/</link><pubDate>Tue, 18 Feb 2020 00:00:00 +0000</pubDate><guid>https://thomas.labarussias.fr/posts/falcosidekick-100k-pulls/</guid><description>&lt;p&gt;Un petit post d&amp;rsquo;auto-promo (après des mois d&amp;rsquo;absences&amp;hellip;).&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai noté récemment que mon petit &lt;code&gt;falcosidekick&lt;/code&gt; a dépassé les &lt;em&gt;100000 pulls&lt;/em&gt; sur le &lt;code&gt;DockerHub&lt;/code&gt;. Je suis bluffé, surtout que je sais que des entités grosses et connues l&amp;rsquo;utilisent (je ne sais pas si je peux dire qui, donc je me tais, &lt;em&gt;sorry&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;Un petit graphe pour montrer l&amp;rsquo;historique (la légende est illisible, mais les dates sont obtenables en survolant) :&lt;/p&gt;
&lt;div&gt;
&lt;svg class='line'&gt;&lt;/svg&gt;
&lt;script src="https://cdn.jsdelivr.net/npm/chart.xkcd@1/dist/chart.xkcd.min.js"&gt;&lt;/script&gt;
&lt;script&gt;
const svgline = document.querySelector('.line');
new chartXkcd.Line(svgline, {
title: 'Docker Pulls',
xLabel: 'Pulls',
yLabel: 'Date',
data: {
labels:['2019-08-28','2019-08-29','2019-08-30','2019-08-31','2019-09-01','2019-09-02','2019-09-03','2019-09-04','2019-09-05','2019-09-06','2019-09-07','2019-09-08','2019-09-09','2019-09-10','2019-09-11','2019-09-12','2019-09-13','2019-09-14','2019-09-15','2019-09-16','2019-09-17','2019-09-18','2019-09-19','2019-09-20','2019-09-21','2019-09-22','2019-09-23','2019-09-24','2019-09-25','2019-09-26','2019-09-27','2019-09-28','2019-09-29','2019-09-30','2019-10-01','2019-10-02','2019-10-03','2019-10-04','2019-10-05','2019-10-06','2019-10-07','2019-10-08','2019-10-09','2019-10-10','2019-10-11','2019-10-12','2019-10-13','2019-10-14','2019-10-15','2019-10-16','2019-10-17','2019-10-18','2019-10-19','2019-10-20','2019-10-21','2019-10-22','2019-10-23','2019-10-24','2019-10-25','2019-10-26','2019-10-27','2019-10-28','2019-10-29','2019-10-30','2019-10-31','2019-11-01','2019-11-02','2019-11-03','2019-11-04','2019-11-05','2019-11-06','2019-11-07','2019-11-08','2019-11-09','2019-11-10','2019-11-11','2019-11-12','2019-11-13','2019-11-14','2019-11-15','2019-11-16','2019-11-17','2019-11-18','2019-11-19','2019-11-20','2019-11-21','2019-11-22','2019-11-23','2019-11-24','2019-11-25','2019-11-26','2019-11-27','2019-11-28','2019-11-29','2019-11-30','2019-12-01','2019-12-02','2019-12-03','2019-12-04','2019-12-05','2019-12-06','2019-12-07','2019-12-08','2019-12-09','2019-12-10','2019-12-11','2019-12-12','2019-12-13','2019-12-14','2019-12-15','2019-12-16','2019-12-17','2019-12-18','2019-12-19','2019-12-20','2019-12-21','2019-12-22','2019-12-23','2019-12-24','2019-12-25','2019-12-26','2019-12-27','2019-12-28','2019-12-29','2019-12-30','2019-12-31','2020-01-01','2020-01-02','2020-01-03','2020-01-04','2020-01-05','2020-01-06','2020-01-07','2020-01-08','2020-01-09','2020-01-10','2020-01-11','2020-01-12','2020-01-13','2020-01-14','2020-01-15','2020-01-16','2020-01-17','2020-01-18','2020-01-19','2020-01-20','2020-01-21','2020-01-22','2020-01-23','2020-01-24','2020-01-25','2020-01-26','2020-01-27','2020-01-28','2020-01-29','2020-01-30','2020-01-31','2020-02-01','2020-02-02','2020-02-03','2020-02-04','2020-02-05','2020-02-06','2020-02-07','2020-02-08','2020-02-09','2020-02-10','2020-02-11','2020-02-12','2020-02-13','2020-02-14','2020-02-15','2020-02-16','2020-02-17','2020-02-18'],
datasets: [{
label: 'Pulls',
data: [2,2,9,106,108,134,173,434,492,615,761,761,816,950,1084,1104,1111,1111,1111,1157,1194,1210,1232,1232,1232,1232,1235,7685,7988,8042,8086,8086,8086,8087,8188,8200,8250,8373,8401,8408,8409,8524,8532,8603,8659,8707,8707,8771,8842,8992,9467,9713,9995,10255,10572,10903,10986,11041,11467,12042,12206,12277,12380,12470,12490,12642,12707,12783,13239,13754,14426,15159,15837,16155,16292,16776,17425,18001,18931,19596,20055,20321,20694,21490,22307,23572,24904,25591,25738,26321,27371,28516,29413,30216,30967,31052,31591,32710,34168,35164,35858,36239,36536,36849,37305,39011,40333,41472,42265,42508,43081,44534,45853,47028,47575,47880,47884,48428,48877,48882,49219,49683,49784,49786,49981,50538,50625,50860,51338,51413,51419,51501,51809,52676,53759,54978,55761,55828,56622,58214,59431,60331,62154,63643,64460,65872,67662,69453,71212,73267,74537,75335,76767,79124,81637,83863,86340,87692,88663,89862,91420,92794,94149,95124,95836,96571,97335,98296,99070,99906,100752,101480,102182,102885,103582],
}]
},
options: { // optional
yTickCount: 20,
}
});
&lt;/script&gt;
&lt;/div&gt;
&lt;p&gt;Merci à tous ceux qui l&amp;rsquo;utilisent et bien sûr à toute l&amp;rsquo;équipe derrière &lt;code&gt;falco&lt;/code&gt;. J&amp;rsquo;ai d&amp;rsquo;autres idées en réserve pour améliorer, j&amp;rsquo;espère avoir le temps de m&amp;rsquo;y atteler.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Enjoy&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Falcosidekick 2.9.0 : nouvelle intégration et nouvel avatar</title><link>https://thomas.labarussias.fr/posts/falcosidekick-v-2-9-0-new-avatar/</link><pubDate>Sat, 05 Oct 2019 00:00:00 +0000</pubDate><guid>https://thomas.labarussias.fr/posts/falcosidekick-v-2-9-0-new-avatar/</guid><description>&lt;p&gt;Je viens de sortir la version &lt;a class="link" href="https://github.com/falcosecurity/falcosidekick/releases/tag/2.9.0" target="_blank" rel="noopener"
&gt;&lt;strong&gt;2.9.0&lt;/strong&gt;&lt;/a&gt; de &lt;strong&gt;falcosidekick&lt;/strong&gt; et en outre un nouvel output, &lt;a class="link" href="https://www.opsgenie.com/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Opsgenie&lt;/strong&gt;&lt;/a&gt;, j&amp;rsquo;ai également refait l&amp;rsquo;avatar du projet. Il est désormais en couleurs et a une forme globale carrée, pour faciliter l&amp;rsquo;utilisation en icône (&lt;strong&gt;Slack&lt;/strong&gt;, &lt;strong&gt;Teams&lt;/strong&gt;, &amp;hellip;).&lt;/p&gt;
&lt;p&gt;Voilà le résultat :&lt;/p&gt;
&lt;p&gt;&lt;img src="https://raw.githubusercontent.com/falcosecurity/falcosidekick/master/imgs/falcosidekick_color.png"
loading="lazy"
alt="falcosidekick new avatar"
&gt;&lt;/p&gt;
&lt;p&gt;Ce qui donne ceci dans &lt;strong&gt;Slack&lt;/strong&gt; :&lt;/p&gt;
&lt;p&gt;&lt;img src="https://thomas.labarussias.fr/posts/falcosidekick-v-2-9-0-new-avatar/img/slack_with_new_falcosidekick_avatar.png"
width="794"
height="374"
srcset="https://thomas.labarussias.fr/posts/falcosidekick-v-2-9-0-new-avatar/img/slack_with_new_falcosidekick_avatar_hu_f0022fa476a909bc.png 480w, https://thomas.labarussias.fr/posts/falcosidekick-v-2-9-0-new-avatar/img/slack_with_new_falcosidekick_avatar_hu_91a0ecc7b86ce830.png 1024w"
loading="lazy"
alt="slack avec le nouvel avatar"
class="gallery-image"
data-flex-grow="212"
data-flex-basis="509px"
&gt;&lt;/p&gt;
&lt;p&gt;En ce qui concerne &lt;a class="link" href="https://www.opsgenie.com/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Opsgenie&lt;/strong&gt;&lt;/a&gt;, voilà le résultat :&lt;/p&gt;
&lt;p&gt;&lt;img src="https://raw.githubusercontent.com/falcosecurity/falcosidekick/master/docs/outputs/images/opsgenie.png"
loading="lazy"
alt="OpeGenie"
&gt;&lt;/p&gt;
&lt;p&gt;Le repo &lt;a class="link" href="https://github.com/falcosecurity/falcosidekick" target="_blank" rel="noopener"
&gt;Github&lt;/a&gt; et l&amp;rsquo;image sur le &lt;a class="link" href="https://hub.docker.com/r/falcosecurity/falcosidekick/" target="_blank" rel="noopener"
&gt;DockerHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Enjoy&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Falco Probes</title><link>https://thomas.labarussias.fr/posts/falco-probes/</link><pubDate>Mon, 23 Sep 2019 00:00:00 +0000</pubDate><guid>https://thomas.labarussias.fr/posts/falco-probes/</guid><description>&lt;p&gt;Je traîne pas mal sur le &lt;strong&gt;slack&lt;/strong&gt; de &lt;a class="link" href="https://sysdig.slack.com/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;sysdig&lt;/strong&gt;&lt;/a&gt;, où on parle bien entendu de &lt;strong&gt;falco&lt;/strong&gt;. Un problème très récurrent des utilisateurs est l&amp;rsquo;existence ou non de modules &lt;em&gt;kernel&lt;/em&gt; précompilés pour leurs versions de &lt;em&gt;kernel&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Quand le module n&amp;rsquo;est pas présent sur la machine hôte, l&amp;rsquo;installeur tente de le télécharger depuis un &lt;em&gt;bucket S3&lt;/em&gt;, c&amp;rsquo;est pratique, mais étant donné l&amp;rsquo;immense variété d&amp;rsquo;architectures et de versions de &lt;em&gt;kernel&lt;/em&gt; dans la nature, impossible de tous les avoir tout prêts au chaud sur &lt;em&gt;S3&lt;/em&gt;. Jusqu&amp;rsquo;à présent, la seule manière pour savoir si la version du module pour son &lt;em&gt;kernel&lt;/em&gt; est présente ou non sur le &lt;em&gt;bucket&lt;/em&gt; est d&amp;rsquo;aller sur la page indigeste qui est celle-ci : &lt;a class="link" href="https://s3.amazonaws.com/download.draios.com/stable/sysdig-probe-binaries/index.html" target="_blank" rel="noopener"
&gt;https://s3.amazonaws.com/download.draios.com/stable/sysdig-probe-binaries/index.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Pas très pratique (ça oblige à faire du &lt;em&gt;ctrl+F&lt;/em&gt; pour recherhcer) et surtout la page est de plus en plus volumineuse.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai donc codé un petit machin qui parse cet &lt;em&gt;index&lt;/em&gt; et ressort le tout sous forme de tableaux dans lequels on peut chercher et également transmettre les diens vers les modules.&lt;/p&gt;
&lt;p&gt;Le domaine est temporaire jusqu&amp;rsquo;à nouvel ordre : &lt;strong&gt;&lt;a class="link" href="https://thomas.labarussias.fr/falco-probes/?falcoversion=0.17.0" target="_blank" rel="noopener"
&gt;https://thomas.labarussias.fr/falco-probes/?falcoversion=0.17.0&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;En espérant que ça serve à quelqu&amp;rsquo;un d&amp;rsquo;autre que moi, en tout cas c&amp;rsquo;est très pratique pour vérifier si les soucis d&amp;rsquo;installation de &lt;strong&gt;falco&lt;/strong&gt; d&amp;rsquo;une personne viennent de l&amp;rsquo;absence du module ou non.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Enjoy&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Chart XKCD</title><link>https://thomas.labarussias.fr/posts/chart-xkcd/</link><pubDate>Thu, 12 Sep 2019 00:00:00 +0000</pubDate><guid>https://thomas.labarussias.fr/posts/chart-xkcd/</guid><description>&lt;p&gt;Je suis tombé &lt;a class="link" href="https://github.com/timqian/chart.xkcd" target="_blank" rel="noopener"
&gt;chart.xkcd&lt;/a&gt; parmi les flux RSS que je suis. J&amp;rsquo;ai trouvé l&amp;rsquo;idée amusante et le rendu agréable, j&amp;rsquo;en ai donc fait un micro &lt;em&gt;shortcode&lt;/em&gt; pour &lt;strong&gt;Hugo&lt;/strong&gt; :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;svg&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;{{ .Get &amp;#34;name&amp;#34; }}&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;svg&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;https://cdn.jsdelivr.net/npm/chart.xkcd@1/dist/chart.xkcd.min.js&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;svg&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Get&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;safeJS&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;.{{ .Get &amp;#34;name&amp;#34; }}&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;chartXkcd&lt;/span&gt;&lt;span class="p"&gt;.{{&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Get&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;safeJS&lt;/span&gt; &lt;span class="p"&gt;}}(&lt;/span&gt;&lt;span class="nx"&gt;svg&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Get&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;safeJS&lt;/span&gt; &lt;span class="p"&gt;}},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Inner&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;safeJS&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;A caler dans &lt;code&gt;layout/shortcodes/chart-xkcd.html&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Trois types de diagrammes sont dispos pour le moment : &lt;a class="link" href="#line" &gt;&lt;strong&gt;Line&lt;/strong&gt;&lt;/a&gt;, &lt;a class="link" href="#pie" &gt;&lt;strong&gt;Pie&lt;/strong&gt;&lt;/a&gt;, &lt;a class="link" href="#bar" &gt;&lt;strong&gt;Bar&lt;/strong&gt;&lt;/a&gt;, &lt;a class="link" href="#xy" &gt;&lt;strong&gt;XY&lt;/strong&gt;&lt;/a&gt;, &lt;a class="link" href="#radar" &gt;&lt;strong&gt;Radar&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Les options de chaque diagramme sont trouvables dans la &lt;a class="link" href="https://timqian.com/chart.xkcd/" target="_blank" rel="noopener"
&gt;doc&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="exemples"&gt;Exemples
&lt;/h2&gt;&lt;h3 id="line"&gt;Line
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;chart&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;xkcd&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;line&amp;#34;&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Line&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;A vs B&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;xLabel&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Abscisse&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;yLabel&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Ordonnee&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;labels&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;2&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;3&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;4&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;5&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;6&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;7&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;8&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;9&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;10&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;datasets&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;A&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;250&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2900&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;B&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;yTickCount&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="err"&gt;/chart-xkcd &amp;gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div&gt;
&lt;svg class='line'&gt;&lt;/svg&gt;
&lt;script src="https://cdn.jsdelivr.net/npm/chart.xkcd@1/dist/chart.xkcd.min.js"&gt;&lt;/script&gt;
&lt;script&gt;
const svgline = document.querySelector('.line');
new chartXkcd.Line(svgline, {
title: 'A vs B',
xLabel: 'Abscisse',
yLabel: 'Ordonnee',
data: {
labels:['1', '2', '3', '4', '5', '6','7', '8', '9', '10'],
datasets: [{
label: 'A',
data: [30, 2500, 200, 300, 250 ,800, 1500, 2900, 5000, 800],
}, {
label: 'B',
data: [0, 145, 300, 770, 80, 45, 50, 1080, 40, 150],
}]
},
options: {
yTickCount: 10,
}
});
&lt;/script&gt;
&lt;/div&gt;
&lt;h3 id="pie"&gt;Pie
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;chart&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;xkcd&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pie&amp;#34;&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Pie&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;A B C D E&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;labels&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;A&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;B&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;C&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;D&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;E&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;datasets&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;122&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;130&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;44&lt;/span&gt;&lt;span class="p"&gt;,],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;innerRadius&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// mettre à 0 pour obtenir un diagramme camembert (pie chart)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;legendPosition&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;chartXkcd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;positionType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;upRight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="err"&gt;/chart-xkcd &amp;gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div&gt;
&lt;svg class='pie'&gt;&lt;/svg&gt;
&lt;script src="https://cdn.jsdelivr.net/npm/chart.xkcd@1/dist/chart.xkcd.min.js"&gt;&lt;/script&gt;
&lt;script&gt;
const svgpie = document.querySelector('.pie');
new chartXkcd.Pie(svgpie, {
title: 'A B C D E',
data: {
labels:[ 'A', 'B', 'C', 'D', 'E'],
datasets: [{
data: [200, 122, 60, 130, 44,],
}]
},
options: {
innerRadius: 0.5,
legendPosition: chartXkcd.config.positionType.upRight,
}
});
&lt;/script&gt;
&lt;/div&gt;
&lt;h3 id="bar"&gt;Bar
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;chart&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;xkcd&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;bar&amp;#34;&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Bar&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;A B C D&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;labels&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;A&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;B&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;C&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;D&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;datasets&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;yTickCount&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="err"&gt;/chart-xkcd &amp;gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div&gt;
&lt;svg class='bar'&gt;&lt;/svg&gt;
&lt;script src="https://cdn.jsdelivr.net/npm/chart.xkcd@1/dist/chart.xkcd.min.js"&gt;&lt;/script&gt;
&lt;script&gt;
const svgbar = document.querySelector('.bar');
new chartXkcd.Bar(svgbar, {
title: "A B C D",
data: {
labels:['A', 'B', 'C', 'D'],
datasets: [{
data: [20, 33, 5, 12],
}]
},
options: { // optional
yTickCount: 8,
}
});
&lt;/script&gt;
&lt;/div&gt;
&lt;h3 id="xy"&gt;XY
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;chart&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;xkcd&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;xy&amp;#34;&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;XY&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;A vs B&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;xLabel&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Abscisse&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;yLabel&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Ordonnee&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;datasets&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;A&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;45&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;B&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;53&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;xTickCount&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;yTickCount&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;showLine&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;dotSize&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="err"&gt;/chart-xkcd &amp;gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div&gt;
&lt;svg class='xy1'&gt;&lt;/svg&gt;
&lt;script src="https://cdn.jsdelivr.net/npm/chart.xkcd@1/dist/chart.xkcd.min.js"&gt;&lt;/script&gt;
&lt;script&gt;
const svgxy1 = document.querySelector('.xy1');
new chartXkcd.XY(svgxy1, {
title: 'A vs B',
xLabel: 'Abscisse',
yLabel: 'Ordonnee',
data: {
datasets: [{
label: 'A',
data: [{ x: 1, y: 30 }, { x: 3, y: 8 }, { x: 5, y: 45 }, { x: 7, y: 22 }, { x: 9, y: -4 }],
}, {
label: 'B',
data: [{ x: -2, y: 12 }, { x: 4, y: -20 }, { x: 6, y: 53 }, { x: 8, y: 12 }, { x: 10, y: 20 }],
}],
},
options: {
xTickCount: 10,
yTickCount: 10,
showLine: false,
dotSize: 1,
}
});
&lt;/script&gt;
&lt;/div&gt;
&lt;p&gt;Avec &lt;code&gt;options: {showLine: true}&lt;/code&gt; :&lt;/p&gt;
&lt;div&gt;
&lt;svg class='xy2'&gt;&lt;/svg&gt;
&lt;script src="https://cdn.jsdelivr.net/npm/chart.xkcd@1/dist/chart.xkcd.min.js"&gt;&lt;/script&gt;
&lt;script&gt;
const svgxy2 = document.querySelector('.xy2');
new chartXkcd.XY(svgxy2, {
title: 'A vs B',
xLabel: 'Abscisse',
yLabel: 'Ordonnee',
data: {
datasets: [{
label: 'A',
data: [{ x: 1, y: 30 }, { x: 3, y: 8 }, { x: 5, y: 45 }, { x: 7, y: 22 }, { x: 9, y: -4 }],
}, {
label: 'B',
data: [{ x: -2, y: 12 }, { x: 4, y: -20 }, { x: 6, y: 53 }, { x: 8, y: 12 }, { x: 10, y: 20 }],
}],
},
options: {
xTickCount: 10,
yTickCount: 10,
showLine: true,
dotSize: 1,
}
});
&lt;/script&gt;
&lt;/div&gt;
&lt;h3 id="radar"&gt;Radar
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;chart&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;xkcd&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;radar&amp;#34;&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Radar&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;A vs B&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;labels&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;c&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;d&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;e&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;datasets&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;A&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;B&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;showLegend&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;dotSize&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;showLabels&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="err"&gt;/chart-xkcd &amp;gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div&gt;
&lt;svg class='radar'&gt;&lt;/svg&gt;
&lt;script src="https://cdn.jsdelivr.net/npm/chart.xkcd@1/dist/chart.xkcd.min.js"&gt;&lt;/script&gt;
&lt;script&gt;
const svgradar = document.querySelector('.radar');
new chartXkcd.Radar(svgradar, {
title: 'A vs B',
data: {
labels: ['a', 'b', 'c', 'd', 'e'],
datasets: [{
label: 'A',
data: [3, 1, 3, 3, 2],
}, {
label: 'B',
data: [1, 3, 2, 3, 1],
}],
},
options: {
showLegend: true,
dotSize: .7,
showLabels: true,
},
});
&lt;/script&gt;
&lt;/div&gt;</description></item><item><title>Falcosidekick 2.8.0</title><link>https://thomas.labarussias.fr/posts/falcosidekick-v-2-8-0/</link><pubDate>Wed, 11 Sep 2019 00:00:00 +0000</pubDate><guid>https://thomas.labarussias.fr/posts/falcosidekick-v-2-8-0/</guid><description>&lt;p&gt;Nouvelle release, la &lt;a class="link" href="https://github.com/Issif/falcosidekick/releases/tag/2.8.0" target="_blank" rel="noopener"
&gt;&lt;strong&gt;2.8.0&lt;/strong&gt;&lt;/a&gt;, de mon proxy pour &lt;a class="link" href="https://falco.org/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;falco&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;La grosse feature étant l&amp;rsquo;ajout de &lt;a class="link" href="https://nats.io/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;NATS&lt;/strong&gt;&lt;/a&gt; (une &lt;em&gt;message queue&lt;/em&gt; en &lt;strong&gt;Go&lt;/strong&gt;) comme sortie.&lt;/p&gt;
&lt;p&gt;Le repo &lt;a class="link" href="https://github.com/falcosecurity/falcosidekick" target="_blank" rel="noopener"
&gt;Github&lt;/a&gt; et l&amp;rsquo;image sur le &lt;a class="link" href="https://hub.docker.com/r/falcosecurity/falcosidekick/" target="_blank" rel="noopener"
&gt;DockerHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Enjoy&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Utiliser k3d pour avoir un cluster k8s en local</title><link>https://thomas.labarussias.fr/posts/utiliser-k3d/</link><pubDate>Thu, 05 Sep 2019 00:00:00 +0000</pubDate><guid>https://thomas.labarussias.fr/posts/utiliser-k3d/</guid><description>&lt;p&gt;Afin de parfaire mes connaissances sur &lt;a class="link" href="https://kubernetes.io/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;kubernetes&lt;/strong&gt;&lt;/a&gt;, &lt;em&gt;aka&lt;/em&gt; &lt;strong&gt;k8s&lt;/strong&gt; pour les intimes, j&amp;rsquo;avais envie de monter un &lt;em&gt;cluster&lt;/em&gt; sur mon &lt;em&gt;laptop&lt;/em&gt;, pas juste un noeud tout seul. Jusqu&amp;rsquo;à présent je n&amp;rsquo;avais testé que des solutions pour avoir des &lt;strong&gt;k8s&lt;/strong&gt; mono-noeud, c&amp;rsquo;est sympa, mais trop éloigné de la réalité, surtout si on veut tester des méthodes de résilience, d&amp;rsquo;&lt;em&gt;auto-scaling&lt;/em&gt; de &lt;em&gt;pods&lt;/em&gt;, de &lt;em&gt;deployments&lt;/em&gt;, de &lt;em&gt;daemonset&lt;/em&gt;, etc.&lt;/p&gt;
&lt;p&gt;Et là, la révélation ! Je connaissais déjà &lt;a class="link" href="https://github.com/rancher/k3s" target="_blank" rel="noopener"
&gt;&lt;strong&gt;k3s&lt;/strong&gt;&lt;/a&gt;, le &lt;strong&gt;k8s&lt;/strong&gt; ultra allégé de chez &lt;a class="link" href="https://rancher.com/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;rancher&lt;/strong&gt;&lt;/a&gt; et il s&amp;rsquo;avère qu&amp;rsquo;ils ont développé un petit utilitaire pour monter un &lt;em&gt;cluster&lt;/em&gt; dans des &lt;em&gt;containeurs&lt;/em&gt; &lt;strong&gt;docker&lt;/strong&gt; avec, le bien nommé &lt;a class="link" href="https://github.com/rancher/k3d" target="_blank" rel="noopener"
&gt;&lt;strong&gt;k3d&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Après plusieurs heures de tests, je suis emballé, c&amp;rsquo;est ultra rapide, ultra &lt;em&gt;light&lt;/em&gt; et ça fonctionne avec tous les outils classiques. Un &lt;strong&gt;ingress controller&lt;/strong&gt; basé sur &lt;strong&gt;traefik&lt;/strong&gt; est directement déployé, donc on a de base un environnement fonctionnel. Simple. Efficace.&lt;/p&gt;
&lt;h2 id="installation-de-k3d"&gt;Installation de k3d
&lt;/h2&gt;&lt;p&gt;Rien de compliqué pour l&amp;rsquo;installer, plusieurs méthodes sont fournies sur le &lt;a class="link" href="https://github.com/rancher/k3d#get" target="_blank" rel="noopener"
&gt;repo Github officiel&lt;/a&gt;. Comme c&amp;rsquo;est du &lt;strong&gt;go&lt;/strong&gt;, aucune dépendance. &lt;em&gt;Easy&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id="créer-son-premier-cluster"&gt;Créer son premier cluster
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;~ $ k3d create -n mon-cluster-test --publish &lt;span class="m"&gt;80&lt;/span&gt; --publish &lt;span class="m"&gt;8080&lt;/span&gt; --publish &lt;span class="m"&gt;443&lt;/span&gt; -w &lt;span class="m"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2019/09/05 23:16:34 Created cluster network with ID cae80bddca7cf614494b9d97f7d6edf2b14d45864ef1aa0b1a899a93122ecc1b
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2019/09/05 23:16:34 Created docker volume k3d-mon-cluster-test-images
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2019/09/05 23:16:34 Creating cluster &lt;span class="o"&gt;[&lt;/span&gt;mon-cluster-test&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2019/09/05 23:16:34 Creating server using docker.io/rancher/k3s:v0.7.0...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2019/09/05 23:16:34 Pulling image docker.io/rancher/k3s:v0.7.0...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2019/09/05 23:16:47 Booting &lt;span class="m"&gt;2&lt;/span&gt; workers &lt;span class="k"&gt;for&lt;/span&gt; cluster mon-cluster-test
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2019/09/05 23:16:48 Created worker with ID b0c019c001376c9aa07f8fb65b52da1b2d52fbe61f25cb24c7198c5b122a2a09
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2019/09/05 23:16:49 Created worker with ID a9d959899a2119606248bf8dd5d681f05efb7232d19c5f8206ffb5025f10885b
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2019/09/05 23:16:49 SUCCESS: created cluster &lt;span class="o"&gt;[&lt;/span&gt;mon-cluster-test&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2019/09/05 23:16:49 You can now use the cluster with:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;KUBECONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;k3d get-kubeconfig --name&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mon-cluster-test&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl cluster-info
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Sur ma machine, l&amp;rsquo;exécution a pris environ 20s, en sachant que 95% du temps est lié la récupération de l&amp;rsquo;image &lt;strong&gt;k3s&lt;/strong&gt;. Impressionnant.&lt;/p&gt;
&lt;p&gt;Une petite explication des arguments :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-n&lt;/code&gt; : le nom de notre cluster &lt;strong&gt;k8s&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--publish 80 --publish 8080 --publish 443&lt;/code&gt; : les ports qu&amp;rsquo;on va exposer, comme c&amp;rsquo;est fait avec la commande &lt;a class="link" href="https://docs.docker.com/engine/reference/run/#expose-incoming-ports" target="_blank" rel="noopener"
&gt;&lt;em&gt;docker run&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-w 2&lt;/code&gt; : le nombre de &lt;em&gt;workers&lt;/em&gt; qu&amp;rsquo;on veut&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On peut lister nos &lt;em&gt;clusters&lt;/em&gt; :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;~ $ k3d ls
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;+------------------+------------------------------+---------+---------+
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; NAME &lt;span class="p"&gt;|&lt;/span&gt; IMAGE &lt;span class="p"&gt;|&lt;/span&gt; STATUS &lt;span class="p"&gt;|&lt;/span&gt; WORKERS &lt;span class="p"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;+------------------+------------------------------+---------+---------+
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; mon-cluster-test &lt;span class="p"&gt;|&lt;/span&gt; docker.io/rancher/k3s:v0.7.0 &lt;span class="p"&gt;|&lt;/span&gt; running &lt;span class="p"&gt;|&lt;/span&gt; 2/2 &lt;span class="p"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;+------------------+------------------------------+---------+---------+
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;L&amp;rsquo;image est effectivement de taille réduite (&lt;em&gt;proportionnellement aux autres solutions&lt;/em&gt;) :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;REPOSITORY TAG IMAGE ID CREATED SIZE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rancher/k3s v0.7.0 f1ec9d3fbf66 &lt;span class="m"&gt;6&lt;/span&gt; weeks ago 119MB
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="se-connecter-au-cluster"&gt;Se connecter au cluster
&lt;/h2&gt;&lt;p&gt;Comme précisé dans les logs de création, on peut récupérer le &lt;em&gt;kubeconfig&lt;/em&gt; associé pour utiliser les outils classiques (&lt;a class="link" href="https://github.com/kubernetes/kubernetes/tree/master/pkg/kubectl" target="_blank" rel="noopener"
&gt;&lt;strong&gt;kubectl&lt;/strong&gt;&lt;/a&gt;, &lt;a class="link" href="https://github.com/derailed/k9s" target="_blank" rel="noopener"
&gt;&lt;strong&gt;k9s&lt;/strong&gt;&lt;/a&gt;, &lt;a class="link" href="https://github.com/helm/helm" target="_blank" rel="noopener"
&gt;&lt;strong&gt;helm&lt;/strong&gt;&lt;/a&gt;, etc) :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;~ $ &lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;KUBECONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;k3d get-kubeconfig --name&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mon-cluster-test&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;~ $ kubectl get nodes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;NAME STATUS ROLES AGE VERSION
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;k3d-mon-cluster-test-server Ready master 2m v1.14.4-k3s.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;k3d-mon-cluster-test-worker-0 Ready worker 2m v1.14.4-k3s.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;k3d-mon-cluster-test-worker-1 Ready worker 2m v1.14.4-k3s.1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="premier-déploiement"&gt;Premier déploiement
&lt;/h2&gt;&lt;p&gt;Afin de tester tout cela, nous allons appliquer un premier &lt;em&gt;deployment&lt;/em&gt; et tenter d&amp;rsquo;y accéder. Cela sera un simple &lt;em&gt;micro-service&lt;/em&gt; qui nous répondra quelques infos sur lui-même (sur quel &lt;em&gt;noeud&lt;/em&gt; il tourne, son nom, le contenu de la requête &lt;em&gt;HTTP&lt;/em&gt; qu&amp;rsquo;il a reçue, etc). Le container qui sera utilisé est fourni par ailleurs par ceux derrière &lt;strong&gt;traefik&lt;/strong&gt; : &lt;a class="link" href="https://hub.docker.com/r/containous/whoami" target="_blank" rel="noopener"
&gt;&lt;strong&gt;containous/whoami&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="création-dun-namespace-dédié"&gt;Création d&amp;rsquo;un namespace dédié
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;~ $ kubectl create namespace whoami
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;C&amp;rsquo;est juste histoire de bien segmenter les choses.&lt;/p&gt;
&lt;h3 id="application-du-deployment"&gt;Application du &lt;em&gt;deployment&lt;/em&gt;
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;~ $ kubectl create deployment whoami --image&lt;span class="o"&gt;=&lt;/span&gt;containous/whoami -n whoami
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="scaling-du-replicaset"&gt;&lt;em&gt;Scaling&lt;/em&gt; du &lt;em&gt;replicaSet&lt;/em&gt;
&lt;/h3&gt;&lt;p&gt;Nous avons un &lt;em&gt;cluster&lt;/em&gt; à 2 noeuds, ça serait dommage de n&amp;rsquo;avoir qu&amp;rsquo;un seul &lt;em&gt;pod&lt;/em&gt;, augmentons à 2 le &lt;em&gt;replicaSet&lt;/em&gt; associé :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;~ $ kubectl scale --replicas &lt;span class="m"&gt;2&lt;/span&gt; deployment/whoami -n whoami
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;~ $ kubectl get rs -n whoami
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;NAME DESIRED CURRENT READY AGE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;whoami-756586b9ff &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt; 4m33s
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="création-du-service"&gt;Création du &lt;em&gt;service&lt;/em&gt;
&lt;/h3&gt;&lt;p&gt;Nous avons 2 &lt;em&gt;pods&lt;/em&gt;, nous allons créer un &lt;em&gt;service&lt;/em&gt; pour avoir une répartition de charge :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;~ $ kubectl create service clusterip whoami --tcp&lt;span class="o"&gt;=&lt;/span&gt;80:80 -n whoami
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="création-de-lingress"&gt;Création de l&amp;rsquo;&lt;em&gt;ingress&lt;/em&gt;
&lt;/h3&gt;&lt;p&gt;Tout est prêt au sein de notre &lt;em&gt;cluster&lt;/em&gt;, il est temps de nous permettre d&amp;rsquo;accéder à notre &lt;em&gt;micro-service&lt;/em&gt;, on va utiliser une ressource de type &lt;em&gt;ingress&lt;/em&gt; :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;~ $ cat &lt;span class="s"&gt;&amp;lt;&amp;lt;EOF | kubectl apply -n whoami -f -
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;apiVersion: extensions/v1beta1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;kind: Ingress
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;metadata:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; name: whoami
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; annotations:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; ingress.kubernetes.io/ssl-redirect: &amp;#34;false&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;spec:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; rules:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; - http:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; paths:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; - path: /
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; backend:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; serviceName: whoami
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; servicePort: 80
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="testons-le-micro-service"&gt;Testons le &lt;em&gt;micro-service&lt;/em&gt;
&lt;/h3&gt;&lt;p&gt;A la création du cluster, nous avons publier le port 80 au niveau de l&amp;rsquo;host, il est temps de trouver le port qui a été associé (&lt;em&gt;bind&lt;/em&gt;) :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;~ $ docker inspect --format&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;{{range $p, $conf := .NetworkSettings.Ports}} {{$p}} -&amp;gt; {{(index $conf 0).HostPort}} {{end}}&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;$(&lt;/span&gt;docker ps --filter &lt;span class="s2"&gt;&amp;#34;name=k3d-mon-cluster-test-server&amp;#34;&lt;/span&gt; -q&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;443/tcp -&amp;gt; &lt;span class="m"&gt;32810&lt;/span&gt; 6443/tcp -&amp;gt; &lt;span class="m"&gt;6443&lt;/span&gt; 80/tcp -&amp;gt; &lt;span class="m"&gt;32811&lt;/span&gt; 8080/tcp -&amp;gt; &lt;span class="m"&gt;32809&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;L&amp;rsquo;&lt;em&gt;ingress&lt;/em&gt; écoute sur le port 80, le port associé est donc le 32811 dans mon cas. Faisons plusieurs appels et vérifions :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;~ $ curl http://localhost:32811
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Hostname: whoami-756586b9ff-4mqb6
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;IP: 127.0.0.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;IP: ::1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;IP: 10.42.2.4
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;IP: fe80::a89f:5eff:fef5:d426
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;RemoteAddr: 10.42.1.3:36824
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;GET / HTTP/1.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Host: localhost:32811
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;User-Agent: curl/7.47.0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Accept: */*
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Accept-Encoding: gzip
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;X-Forwarded-For: 10.42.1.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;X-Forwarded-Host: localhost:32811
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;X-Forwarded-Port: &lt;span class="m"&gt;32811&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;X-Forwarded-Proto: http
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;X-Forwarded-Server: traefik-56688c4464-wlk2r
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;X-Real-Ip: 10.42.1.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;~ $ curl http://localhost:32811
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Hostname: whoami-756586b9ff-6wn52
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;IP: 127.0.0.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;IP: ::1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;IP: 10.42.0.4
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;IP: fe80::7c0f:1fff:fe2b:bcb2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;RemoteAddr: 10.42.1.3:41180
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;GET / HTTP/1.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Host: localhost:32811
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;User-Agent: curl/7.47.0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Accept: */*
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Accept-Encoding: gzip
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;X-Forwarded-For: 10.42.1.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;X-Forwarded-Host: localhost:32811
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;X-Forwarded-Port: &lt;span class="m"&gt;32811&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;X-Forwarded-Proto: http
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;X-Forwarded-Server: traefik-56688c4464-wlk2r
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;X-Real-Ip: 10.42.1.1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Nous avons bien 2 réponses différentes :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Hostname: whoami-756586b9ff-4mqb6
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;IP: 10.42.2.4
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Hostname: whoami-756586b9ff-6wn52
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;IP: 10.42.0.4
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Qui correspondent à nos 2 &lt;em&gt;pods&lt;/em&gt; :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;~ $ kubectl get pods -n whoami
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;NAME READY STATUS RESTARTS AGE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;whoami-756586b9ff-4mqb6 1/1 Running &lt;span class="m"&gt;0&lt;/span&gt; 24m
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;whoami-756586b9ff-6wn52 1/1 Running &lt;span class="m"&gt;0&lt;/span&gt; 20m
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;em&gt;Enjoy&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Falcosidekick fait désormais partie de l'organisation Falcosecurity</title><link>https://thomas.labarussias.fr/posts/falcosidekick-migre-vers-falcosecurity/</link><pubDate>Wed, 28 Aug 2019 00:00:00 +0000</pubDate><guid>https://thomas.labarussias.fr/posts/falcosidekick-migre-vers-falcosecurity/</guid><description>&lt;p&gt;Les mainteneurs de &lt;strong&gt;falco&lt;/strong&gt; m&amp;rsquo;ont proposé de migrer &lt;strong&gt;falcosidekick&lt;/strong&gt; au sein de l&amp;rsquo;organisation officielle &lt;strong&gt;falcosecurity&lt;/strong&gt;. Il devient donc un projet officiel 🎉😍.&lt;/p&gt;
&lt;p&gt;Le repo &lt;a class="link" href="https://github.com/falcosecurity/falcosidekick" target="_blank" rel="noopener"
&gt;Github&lt;/a&gt; et l&amp;rsquo;image sur le &lt;a class="link" href="https://hub.docker.com/r/falcosecurity/falcosidekick/" target="_blank" rel="noopener"
&gt;DockerHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Au passage, j&amp;rsquo;ai sorti la &lt;a class="link" href="https://github.com/Issif/falcosidekick/releases/tag/2.7.1" target="_blank" rel="noopener"
&gt;&lt;strong&gt;2.7.1&lt;/strong&gt;&lt;/a&gt; qui met à jour la version de Go utilisée (1.12).&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Enjoy&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Falcosidekick 2.7.0</title><link>https://thomas.labarussias.fr/posts/falcosidekick-v-2-7-0/</link><pubDate>Tue, 27 Aug 2019 00:00:00 +0000</pubDate><guid>https://thomas.labarussias.fr/posts/falcosidekick-v-2-7-0/</guid><description>&lt;p&gt;Nouvelle release, la &lt;a class="link" href="https://github.com/Issif/falcosidekick/releases/tag/2.7.0" target="_blank" rel="noopener"
&gt;&lt;strong&gt;2.7.0&lt;/strong&gt;&lt;/a&gt;, de mon proxy pour &lt;a class="link" href="https://falco.org/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;falco&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;La grosse feature étant l&amp;rsquo;ajout de &lt;a class="link" href="https://grafana.com/oss/loki" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Loki&lt;/strong&gt;&lt;/a&gt; comme sortie :&lt;/p&gt;
&lt;p&gt;&lt;img src="https://raw.githubusercontent.com/falcosecurity/falcosidekick/master/docs/outputs/images/loki.png"
loading="lazy"
alt="Grafana Loki"
&gt;&lt;/p&gt;
&lt;p&gt;Le repo &lt;a class="link" href="https://github.com/falcosecurity/falcosidekick" target="_blank" rel="noopener"
&gt;Github&lt;/a&gt; et l&amp;rsquo;image sur le &lt;a class="link" href="https://hub.docker.com/r/falcosecurity/falcosidekick/" target="_blank" rel="noopener"
&gt;DockerHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Enjoy&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Falcosidekick 2.6.0</title><link>https://thomas.labarussias.fr/posts/falcosidekick-v-2-6-0/</link><pubDate>Mon, 26 Aug 2019 00:00:00 +0000</pubDate><guid>https://thomas.labarussias.fr/posts/falcosidekick-v-2-6-0/</guid><description>&lt;p&gt;Nouvelle release, la &lt;a class="link" href="https://github.com/Issif/falcosidekick/releases/tag/2.6.0" target="_blank" rel="noopener"
&gt;&lt;strong&gt;2.6.0&lt;/strong&gt;&lt;/a&gt;, de mon proxy pour &lt;a class="link" href="https://falco.org/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;falco&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;La grosse feature étant l&amp;rsquo;ajout du &lt;strong&gt;SMTP&lt;/strong&gt; (envoi d&amp;rsquo;email) comme sortie :&lt;/p&gt;
&lt;p&gt;&lt;img src="https://raw.githubusercontent.com/falcosecurity/falcosidekick/master/docs/outputs/images/smtp_html.png"
loading="lazy"
alt="SMTP html"
&gt;&lt;/p&gt;
&lt;p&gt;Afin de respecter les standards, la version &lt;em&gt;html&lt;/em&gt; contient également la version &lt;em&gt;plaintext&lt;/em&gt;. Il est aussi possible d&amp;rsquo;envoyer uniquement la version &lt;em&gt;plaintext&lt;/em&gt;, utile pour certains systèmes de &lt;em&gt;ticketing&lt;/em&gt; qui utilisent l&amp;rsquo;email pour la création.&lt;/p&gt;
&lt;p&gt;Le repo &lt;a class="link" href="https://github.com/falcosecurity/falcosidekick" target="_blank" rel="noopener"
&gt;Github&lt;/a&gt; et l&amp;rsquo;image sur le &lt;a class="link" href="https://hub.docker.com/r/falcosecurity/falcosidekick/" target="_blank" rel="noopener"
&gt;DockerHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Enjoy&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Proxifier Traefik par Traefik</title><link>https://thomas.labarussias.fr/posts/traefik-proxyfier-dashboard/</link><pubDate>Mon, 26 Aug 2019 00:00:00 +0000</pubDate><guid>https://thomas.labarussias.fr/posts/traefik-proxyfier-dashboard/</guid><description>&lt;p&gt;&lt;a class="link" href="https://traefik.io/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Traefik&lt;/strong&gt;&lt;/a&gt; possède une &lt;em&gt;UI&lt;/em&gt; basique qui est par défaut exposée sur un port différent. Il est possible de faire en sorte que &lt;strong&gt;Traefik&lt;/strong&gt; serve lui même de proxy, cela permet :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ne plus avoir à utiliser un port différent pour accéder l&amp;rsquo;&lt;em&gt;UI&lt;/em&gt;, mais un domaine classique (&amp;quot;&lt;em&gt;traefik.mondomaine.net&lt;/em&gt;&amp;quot; par ex.)&lt;/li&gt;
&lt;li&gt;forcer l&amp;rsquo;accès en http&lt;strong&gt;s&lt;/strong&gt; avec en prime un certificat &lt;a class="link" href="https://letsencrypt.org/fr/" target="_blank" rel="noopener"
&gt;&lt;em&gt;Let&amp;rsquo;s Encrypt&lt;/em&gt;&lt;/a&gt; automatique et gratuit&lt;/li&gt;
&lt;li&gt;permettre de rajouter une authentification, par défaut, l&amp;rsquo;&lt;em&gt;UI&lt;/em&gt; est ouverte à tout une fois activée&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Dans mon cas, je fais tourner &lt;strong&gt;Traefik&lt;/strong&gt; dans un container, mais ça marchera pareil si vous le faîtes tourner directement sur l&amp;rsquo;&lt;em&gt;host&lt;/em&gt;, prenez juste soin de filtrer le port de l&amp;rsquo;&lt;em&gt;UI&lt;/em&gt; (&lt;em&gt;8080&lt;/em&gt; par défaut) pour qu&amp;rsquo;il n&amp;rsquo;accepte que les connexions de la boucle local (&lt;em&gt;127.0.0.1&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;Voilà ce qu&amp;rsquo;il faut avoir à minima dans sa configuration &lt;em&gt;config.toml&lt;/em&gt; :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;span class="lnt"&gt;42
&lt;/span&gt;&lt;span class="lnt"&gt;43
&lt;/span&gt;&lt;span class="lnt"&gt;44
&lt;/span&gt;&lt;span class="lnt"&gt;45
&lt;/span&gt;&lt;span class="lnt"&gt;46
&lt;/span&gt;&lt;span class="lnt"&gt;47
&lt;/span&gt;&lt;span class="lnt"&gt;48
&lt;/span&gt;&lt;span class="lnt"&gt;49
&lt;/span&gt;&lt;span class="lnt"&gt;50
&lt;/span&gt;&lt;span class="lnt"&gt;51
&lt;/span&gt;&lt;span class="lnt"&gt;52
&lt;/span&gt;&lt;span class="lnt"&gt;53
&lt;/span&gt;&lt;span class="lnt"&gt;54
&lt;/span&gt;&lt;span class="lnt"&gt;55
&lt;/span&gt;&lt;span class="lnt"&gt;56
&lt;/span&gt;&lt;span class="lnt"&gt;57
&lt;/span&gt;&lt;span class="lnt"&gt;58
&lt;/span&gt;&lt;span class="lnt"&gt;59
&lt;/span&gt;&lt;span class="lnt"&gt;60
&lt;/span&gt;&lt;span class="lnt"&gt;61
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;################################################################&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Configuration globale&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;################################################################&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;defaultEntryPoints&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;http&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;entryPoints&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;entryPoints&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;:80&amp;#34;&lt;/span&gt; &lt;span class="c"&gt;# traefik ecoute sur le port 80&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;entryPoints&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;entryPoint&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https&amp;#34;&lt;/span&gt; &lt;span class="c"&gt;# redirection http &amp;gt; https&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;entryPoints&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;:443&amp;#34;&lt;/span&gt; &lt;span class="c"&gt;# traefik ecoute sur le port 443&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;entryPoints&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;minVersion&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;VersionTLS12&amp;#34;&lt;/span&gt; &lt;span class="c"&gt;# version minimum de TLS acceptee&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;entryPoints&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ui&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;127.0.0.1:8080&amp;#34;&lt;/span&gt; &lt;span class="c"&gt;# on ecoute uniquement sur la boucle locale pour ce port&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;entryPoints&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ui&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;entryPoints&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ui&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;basic&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;XXXX:YYYY&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c"&gt;# les identifiants au format htpasswd&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;################################################################&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Configuration pour let&amp;#39;s encrypt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;################################################################&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;acme&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;xxx@yyy.zzz&amp;#34;&lt;/span&gt; &lt;span class="c"&gt;# votre mail pour lets encrypt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;storage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/certs/acme.json&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;entryPoint&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;onDemand&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="c"&gt;# demande automatique de certificat&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;acmeLogging&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;acme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;httpChallenge&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;entryPoint&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;http&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;################################################################&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Configuration de l&amp;#39;API de Traefik&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;################################################################&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;entryPoint&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;ui&amp;#34;&lt;/span&gt; &lt;span class="c"&gt;# l API ecoutera sur cet entrypoint&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;dashboard&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statistics&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;recentErrors&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;################################################################&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Configuration pour l&amp;#39;UI de Traefik&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;################################################################&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;frontends&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;frontends&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ui&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;backend&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;ui&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;passHostHeader&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;frontends&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ui&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;default&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;rule&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Host:ui.mondomaine.net&amp;#34;&lt;/span&gt; &lt;span class="c"&gt;# votre domaine a configurer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;backends&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;backends&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ui&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;backends&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ui&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;servers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;default&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;http://127.0.0.1:8080&amp;#34;&lt;/span&gt; &lt;span class="c"&gt;# le backend a utiliser qui s avere etre l entrypoint de l API&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;em&gt;Enjoy&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Conversion de Types en Go</title><link>https://thomas.labarussias.fr/posts/golang-conversion-types/</link><pubDate>Wed, 21 Aug 2019 00:00:00 +0000</pubDate><guid>https://thomas.labarussias.fr/posts/golang-conversion-types/</guid><description>&lt;hr&gt;
&lt;h1 id="int64--string"&gt;int64 🠮 string
&lt;/h1&gt;&lt;h2 id="formatint"&gt;&lt;a class="link" href="https://golang.org/pkg/strconv/#FormatInt" target="_blank" rel="noopener"
&gt;FormatInt&lt;/a&gt;
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;strconv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FormatInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;base&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="itoa"&gt;&lt;a class="link" href="https://golang.org/pkg/strconv/#Itoa" target="_blank" rel="noopener"
&gt;Itoa&lt;/a&gt;
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;strconv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Itoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Itoa is equivalent to FormatInt(int64(i), 10). &lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h1 id="string--int64"&gt;string 🠮 int64
&lt;/h1&gt;&lt;h2 id="parseint"&gt;&lt;a class="link" href="https://golang.org/pkg/strconv/#ParseInt" target="_blank" rel="noopener"
&gt;ParseInt&lt;/a&gt;
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;strconv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ParseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;base&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;bitSize&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="atoi"&gt;&lt;a class="link" href="https://golang.org/pkg/strconv/#Atoi" target="_blank" rel="noopener"
&gt;Atoi&lt;/a&gt;
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;strconv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Atoi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Atoi is equivalent to ParseInt(s, 10, 0), converted to type int. &lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h1 id="string--time"&gt;string 🠮 Time
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;Pour le &lt;a class="link" href="https://godoc.org/time#pkg-constants" target="_blank" rel="noopener"
&gt;layout&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Pour la &lt;a class="link" href="https://godoc.org/time#LoadLocation" target="_blank" rel="noopener"
&gt;location&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="parse"&gt;&lt;a class="link" href="https://godoc.org/time#Parse" target="_blank" rel="noopener"
&gt;Parse&lt;/a&gt;
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="parseinlocation"&gt;&lt;a class="link" href="https://godoc.org/time#ParseInLocation" target="_blank" rel="noopener"
&gt;ParseInLocation&lt;/a&gt;
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ParseInLocation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;loc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h1 id="time--string"&gt;Time 🠮 string
&lt;/h1&gt;&lt;p&gt;Pour le &lt;a class="link" href="https://godoc.org/time#pkg-constants" target="_blank" rel="noopener"
&gt;layout&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="timeformat"&gt;&lt;a class="link" href="https://godoc.org/time#Time.Format" target="_blank" rel="noopener"
&gt;Time.Format&lt;/a&gt;
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Time&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;layout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Décoder du base64 en Go</title><link>https://thomas.labarussias.fr/posts/decoder-du-base64-en-go/</link><pubDate>Mon, 19 Aug 2019 00:00:00 +0000</pubDate><guid>https://thomas.labarussias.fr/posts/decoder-du-base64-en-go/</guid><description>&lt;p&gt;Je tentais de décoder la partie &lt;em&gt;payload&lt;/em&gt; d&amp;rsquo;un token &lt;em&gt;JWT&lt;/em&gt; (&lt;a class="link" href="https://scotch.io/tutorials/the-anatomy-of-a-json-web-token" target="_blank" rel="noopener"
&gt;https://scotch.io/tutorials/the-anatomy-of-a-json-web-token&lt;/a&gt;) quand j&amp;rsquo;ai eu l&amp;rsquo;erreur suivante :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;panic: illegal base64 data at input byte &lt;span class="m"&gt;349&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Ma façon de faire était pourtant classique et a toujours fonctionné auparavant :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;StdEncoding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DecodeString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Et le décodage du &lt;em&gt;string&lt;/em&gt; via un autre outil ne posait pas de souci. 😧&lt;/p&gt;
&lt;p&gt;La solution se trouvait une fois de plus dans la documentation de &lt;strong&gt;Go&lt;/strong&gt; : &lt;a class="link" href="https://golang.org/pkg/encoding/base64/#pkg-variables" target="_blank" rel="noopener"
&gt;https://golang.org/pkg/encoding/base64/#pkg-variables&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Il existe plusieurs fonctions de décodage qui prennent ou non en compte les caractères de &lt;em&gt;padding&lt;/em&gt;, en changeant pour :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RawStdEncoding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DecodeString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Mon &lt;em&gt;payload&lt;/em&gt; était décodé.&lt;/p&gt;
👍</description></item><item><title>A propos</title><link>https://thomas.labarussias.fr/about/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://thomas.labarussias.fr/about/</guid><description>&lt;p&gt;Mon profil &lt;a class="link" href="https://www.linkedin.com/in/thomas-labarussias/" target="_blank" rel="noopener"
&gt;Linkedin&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;TL;DR:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ingénieur diplômé des Arts &amp;amp; Métiers en conception mécanique et gestion de production industrielle&lt;/li&gt;
&lt;li&gt;Utilisateur de GNU/Linux depuis 2 décennies&lt;/li&gt;
&lt;li&gt;Passionné de métrologie/monitoring&lt;/li&gt;
&lt;li&gt;Fondamentalement un OPS (DevOPS/SRE)&lt;/li&gt;
&lt;li&gt;7 ans d&amp;rsquo;astreinte&lt;/li&gt;
&lt;li&gt;FinOps&lt;/li&gt;
&lt;li&gt;Go developer&lt;/li&gt;
&lt;li&gt;OSS contributor&lt;/li&gt;
&lt;li&gt;DevRel&lt;/li&gt;
&lt;li&gt;Speaker&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Archives</title><link>https://thomas.labarussias.fr/archives/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://thomas.labarussias.fr/archives/</guid><description/></item><item><title>Search</title><link>https://thomas.labarussias.fr/search/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://thomas.labarussias.fr/search/</guid><description/></item><item><title>Talks</title><link>https://thomas.labarussias.fr/talks/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://thomas.labarussias.fr/talks/</guid><description>&lt;p&gt;A titres personnel et professionnel, j&amp;rsquo;ai eu le privilège au cours des années de donner de nombreuses conférences et de participer à des podcasts en tant qu&amp;rsquo;invité.&lt;/p&gt;
&lt;p&gt;Vous trouverez ci-dessous une liste (non exhaustive) de ces conférences et podcasts dont les captations sont en ligne.&lt;/p&gt;
&lt;h3 id="2025"&gt;2025
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&amp;#x1f1eb;&amp;#x1f1f7; &lt;a class="link" href="https://www.youtube.com/watch?v=hkKCLgy0qGk" target="_blank" rel="noopener"
&gt;&lt;code&gt;Jouer au Data Engineer en local avec DuckDB (BDXIO 2025)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&amp;#x1f1eb;&amp;#x1f1f7; &lt;a class="link" href="https://www.youtube.com/watch?v=R1LG-D6MeOI" target="_blank" rel="noopener"
&gt;&lt;code&gt;Comment le Cloud a transformé le métier de Développeur (chillotech)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2024"&gt;2024
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&amp;#x1f1eb;&amp;#x1f1f7; &lt;a class="link" href="https://www.podcastics.com/podcast/episode/table-ronde-sur-lopen-source-283257/" target="_blank" rel="noopener"
&gt;&lt;code&gt;Table Ronde sur l'Open Source (WeSpeakCloud)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&amp;#x1f1eb;&amp;#x1f1f7; &lt;a class="link" href="https://www.youtube.com/watch?v=9P65jDKf8MM" target="_blank" rel="noopener"
&gt;&lt;code&gt;Sécurité des conteneurs avec Falco ! - WORKSHOP COMPLET (La Tangente)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&amp;#x1f1eb;&amp;#x1f1f7; &lt;a class="link" href="https://www.youtube.com/watch?v=Mx28fhyKX7Q" target="_blank" rel="noopener"
&gt;&lt;code&gt;Réagir à temps aux menaces dans Kubernetes avec Falco (Voxxed Days Luxembourg 2024)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&amp;#x1f1eb;&amp;#x1f1f7; &lt;a class="link" href="https://www.youtube.com/watch?v=MpmitmMqQlk" target="_blank" rel="noopener"
&gt;&lt;code&gt;SRE, Falco, Go: la tech vue par Thomas Labarussias (La Tangente podcast)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&amp;#x1f1ec;&amp;#x1f1e7; &lt;a class="link" href="https://www.youtube.com/watch?v=ScluwvDdYqg" target="_blank" rel="noopener"
&gt;&lt;code&gt;Let’s dissect malwares by collecting their syscalls with eBPF (KCD Czech &amp;amp; Slovak 2024)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&amp;#x1f1ec;&amp;#x1f1e7; &lt;a class="link" href="https://www.youtube.com/watch?v=8V0I5ygZz3Q&amp;amp;t=186s" target="_blank" rel="noopener"
&gt;&lt;code&gt;Innovations and Interviews (KCD Istanbul 2024)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&amp;#x1f1ec;&amp;#x1f1e7; &lt;a class="link" href="https://www.youtube.com/watch?v=bzDWBihArQY&amp;amp;t=72s" target="_blank" rel="noopener"
&gt;&lt;code&gt;Cloud-native threat detection with Falco&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&amp;#x1f1ec;&amp;#x1f1e7; &lt;a class="link" href="https://www.youtube.com/watch?v=csKxijmMVNk" target="_blank" rel="noopener"
&gt;&lt;code&gt;How Falco Brought Real-Time Observability to Infrastructure&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2023"&gt;2023
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&amp;#x1f1eb;&amp;#x1f1f7; &lt;a class="link" href="https://www.podcastics.com/podcast/episode/falco-244969/" target="_blank" rel="noopener"
&gt;&lt;code&gt;Falco (WeSpeakCloud)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&amp;#x1f1ec;&amp;#x1f1e7; &lt;a class="link" href="https://www.youtube.com/watch?v=m6rEiKAkWK8" target="_blank" rel="noopener"
&gt;&lt;code&gt;Use Falco and eBPF to protect your applications (Conf42 Observability 2023)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&amp;#x1f1ec;&amp;#x1f1e7; &lt;a class="link" href="https://youtu.be/zThi9fnUXwE?t=110" target="_blank" rel="noopener"
&gt;&lt;code&gt;What happened in Kubecon Amsterdam (Interview) (KubeCon Europe 2023)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&amp;#x1f1ec;&amp;#x1f1e7; &lt;a class="link" href="https://www.youtube.com/watch?v=sAmiBCt3qc4" target="_blank" rel="noopener"
&gt;&lt;code&gt;Enhanced Security for Multi-Tenant Architectures: Key Components and Best Practices (Multi-Tenancy Con 2023)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2022"&gt;2022
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&amp;#x1f1eb;&amp;#x1f1f7; &lt;a class="link" href="https://www.youtube.com/watch?v=5VSjIrSM3Tw" target="_blank" rel="noopener"
&gt;&lt;code&gt;Détecter et réagir aux menaces contre votre cluster Kubernetes avec Falco (Open Source Experience 2022)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&amp;#x1f1eb;&amp;#x1f1f7; &lt;a class="link" href="https://www.youtube.com/watch?v=haQGJUZ2RWw" target="_blank" rel="noopener"
&gt;&lt;code&gt;Détecter et gérer la sécurité dans un contexte Kubernetes (Meetup CNCF X WeScale)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&amp;#x1f1ec;&amp;#x1f1e7; &lt;a class="link" href="https://www.youtube.com/watch?v=KFt2gwlslb8" target="_blank" rel="noopener"
&gt;&lt;code&gt;Extend Falco with Plugins: Trigger Alerts with any Stream of Events (CNCF)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2021"&gt;2021
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&amp;#x1f1eb;&amp;#x1f1f7; &lt;a class="link" href="https://medium.com/electro-monkeys/74-argocd-et-l%C3%A8re-du-gitops-avec-thomas-labarussias-et-victor-boissi%C3%A8re-45d33beabed0" target="_blank" rel="noopener"
&gt;&lt;code&gt;ArgoCD et l’ère du GitOps (Electro Monkeys)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&amp;#x1f1eb;&amp;#x1f1f7; &lt;a class="link" href="https://youtu.be/1TY2M6RyalU?list=PLZ_TUMnTqfu87lInu7CV6YugTehBRgw1C&amp;amp;t=4280" target="_blank" rel="noopener"
&gt;&lt;code&gt;Ajuster la taille de son cluster Kubernetes pour aider les développeurs dans leurs recettes (Meetup AWS User Group Paris)&lt;/code&gt;&lt;/a&gt; (&lt;a class="link" href="https://docs.google.com/presentation/d/1ABG4XnZdBSTZ1wwHlFm3ROB1N84uFDZPsRRIUvRfDkQ/edit?usp=sharing" target="_blank" rel="noopener"
&gt;&lt;em&gt;slides&lt;/em&gt;&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&amp;#x1f1eb;&amp;#x1f1f7; &lt;a class="link" href="https://www.youtube.com/watch?v=3CU5yu-TdNU" target="_blank" rel="noopener"
&gt;&lt;code&gt;Détection et Réaction aux menaces dans Kubernetes avec Falco (Paris Container Days 2021)&lt;/code&gt;&lt;/a&gt; (&lt;a class="link" href="https://docs.google.com/presentation/d/1qGaIWUhNKMdGLb8YwetmbKFxFyY1krvy_c8A7hzg-Nk/edit?usp=sharing" target="_blank" rel="noopener"
&gt;&lt;em&gt;slides&lt;/em&gt;&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&amp;#x1f1eb;&amp;#x1f1f7; &lt;a class="link" href="https://www.youtube.com/watch?v=4jPlzr1-Oek" target="_blank" rel="noopener"
&gt;&lt;code&gt;Continuous Deployment d’applications dans Kubernetes avec Argo CD (DevNation Day France 2021)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&amp;#x1f1eb;&amp;#x1f1f7; &lt;a class="link" href="https://youtu.be/UCXyHRhPbdg?t=2138" target="_blank" rel="noopener"
&gt;&lt;code&gt;Détection et réaction aux menaces dans Kubernetes - Meetup CNCF Paris&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&amp;#x1f1eb;&amp;#x1f1f7; &lt;a class="link" href="https://www.youtube.com/watch?v=bzDWBihArQY&amp;amp;t=72s" target="_blank" rel="noopener"
&gt;&lt;code&gt;Ajuster la taille de son cluster Kubernetes pour aider les développeurs dans leurs recettes (AWS User Group France)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&amp;#x1f1ec;&amp;#x1f1e7; &lt;a class="link" href="https://youtu.be/UCXyHRhPbdg?t=2114" target="_blank" rel="noopener"
&gt;&lt;code&gt;Detection and Reaction to threats in Kubernetes (Cloud Native Computing Paris)&lt;/code&gt;&lt;/a&gt; (&lt;a class="link" href="https://docs.google.com/presentation/d/19rtiON2kMK_OAWEXtLhPW6IEmi74vEyXVWUno384S9Q/edit?usp=sharing" target="_blank" rel="noopener"
&gt;&lt;em&gt;slides&lt;/em&gt;&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&amp;#x1f1ec;&amp;#x1f1e7; &lt;a class="link" href="https://youtu.be/KCp6vAdWOD0?t=601" target="_blank" rel="noopener"
&gt;&lt;code&gt;FalcOMG That's AWESOME - New Things, Fixed Things, and YOU (KubeCon Europe 2021)&lt;/code&gt;&lt;/a&gt; (&lt;a class="link" href="https://static.sched.com/hosted_files/kccnceu2021/a1/FalcOMG%20That%27s%20AWESOME%20-%20New%20Things%2C%20Fixed%20Things%2C%20and%20YOU%20%5BKubeCon%20%2B%20CloudNativeCon%20Europe%202021%5D.pdf" target="_blank" rel="noopener"
&gt;&lt;em&gt;slides&lt;/em&gt;&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&amp;#x1f1ec;&amp;#x1f1e7; &lt;a class="link" href="https://www.youtube.com/watch?v=KYpkD-sMVmk" target="_blank" rel="noopener"
&gt;&lt;code&gt;Falcosidekick: building a micro service for enhancing, and distributing Falco Data (Cloud Native Data Management Days)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&amp;#x1f1ec;&amp;#x1f1e7; &lt;a class="link" href="https://www.youtube.com/watch?v=F0qWkJ68lyE" target="_blank" rel="noopener"
&gt;&lt;code&gt;Detection and Reaction to threats in Kubernetes with Falco and a FaaS (Ekoparty 2021)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2020"&gt;2020
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&amp;#x1f1eb;&amp;#x1f1f7; &lt;a class="link" href="https://medium.com/electro-monkeys/46-la-s%C3%A9curit%C3%A9-dans-tous-ses-%C3%A9tats-d%C3%A9tection-de-comportements-ind%C3%A9sirables-gr%C3%A2ce-%C3%A0-falco-avec-5c3834ad28b8" target="_blank" rel="noopener"
&gt;&lt;code&gt;La sécurité dans tous ses états — détection de comportements indésirables grâce à Falco (Electro Monkeys)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>