Retours sur le BreizhCamp 2015

Toujours aussi déjanté, toujours aussi passionnant, toujours aussi diversifié… le BreizhCamp, bien sûr ! Quelques retours sur les conférences de cette édition qui a encore une fois tenu ses promesses. C’est de la note brute, que chacun y trouve ce qui lui plait. Et ça ne concerne que le second jour, je n’ai pas pu aller aux autres sessions. Snif…

Keynote jour 2

Une première partie par un intervenant d’OVH, qui utilisait une métaphore sympa sur le Mont Saint Michel pour parler de réduction des goulets d’étranglement.

La seconde partie par la fondatrice de la startup B Sensory. Passionnante car passionnée elle-même, et c’est bien d’entendre parler du pouvoir de la littérature dans une assemblée de geeks. Et je dois dire que pour le sujet (littérature érotique + objet connecté vibrant), je trouve que nous avons bien démenti notre réputation de lourdeaux ! Enfin, perso, c’est l’impression que j’ai eue…

Docker en production

Plein d’excellents conseils avancés sur Docker. Et Nico avait enlevé son costard orange, donc on pouvait ouvrir les yeux sans se les brûler Sourire

–net = host excellent pour la performance, mais on perd par contre en isolation, car les conteneurs sont tous reliés en passant par la machine hôte.

Pour contrer les limites réseau de Docker, en attendant qu’elles soient résolues dans Docker lui-même (peut-être), quelques solutions : OpenVSwitch, Weave (mais vu comme un hack pourri par les conférenciers) et libNetwork (ex-SocketPlane) = VXLan seulement, mais pas sécurisé.

Question perso : est-ce qu’à un certain degré de complexité (en particulier quand on veut échanger entre deux hébergeurs), on ne ferait pas mieux de simplement revenir à la couche de niveau supérieur HTTP et échanger comme si les différents services exposés par Docker étaient carrément des services extérieurs ?

Citation de https://www.seancassidy.me/dont-pipe-to-your-shell.html pour expliquer à quel point faire un pipe d’un fichier téléchargé dans un shell pour installer quelque chose est dangereux, y compris après vérification du script, s’il y a interruption du chargement.

BUILDON trigger pour que les images soient rebuildées lorsque les images de base sont changées, de façon que l’image soit toujours sur une image Ubuntu bien patchée à jour. Et dans tous les cas, il faut rebuilder souvent pour cela.

Attention à la fasse sécurité du groupe Docker, car les droits sont équivalents à root. Et sur le point de vue de la sécurité, prendre les précautions sur le démon, car il n’a pas TLS d’activé par défaut.

IPS : certains peuvent avoir des soucis à valider la non-altération des images, qui sont en lecture seule. De plus, la présence d’un agent va à l’encontre de la philosophie de processus unique dans Docker (perso, l’exception sur des processus annexes ou utilitaires me parait tout à fait bénigne…)

Sur Docker, pas de live migration ni de fault tolerance, donc toujours intéressant de garder une couche de vraie virtualisation.

Si on veut passer en mode 100% conteneur, il faut changer de point de vue et passer en mode de pensée “conteneur éphémère”, stateless.

Attention au Single Point Of Failure que constituent le registre, l’annuaire et l’orchestration, domaines sur lesquels les outils ne sont pas encore mûrs.

Le load balancing peut se faire au niveau HTTP avec libNetworks.

Manque d’outillage à ce jour pour le tuning, et les conférenciers s’interrogent sur la capacité réelle des cgroups à limiter les impacts inter-conteneurs (CPU, RAM, I/O).

Attention, le bridge network fait perdre en performance. Par contre, sur de la production, il faut brancher le conteneur Docker directement sur la carte réseau.

Pour ce qui est de la supervision, une approche est de mettre un agent de supervision sur le host (et au passage, ne pas oublier de superviser le démon Docker lui-même) de type nagios-docker ou sensu (qui doivent faire du docker exec, mais ne sont pas présents sur le conteneur lui-même). Et sinon, docker stats donne déjà pas mal de contenu.

Pour les logs, pas de syslog dans le conteneur pour respecter le principe du processus unique (j’ai déjà dit ce que je pensais de cette règle). Eventuellement, ce qui peut être fait est d’envoyer sur le syslog de l’hôte. Logstash est plus récent que syslog et à favoriser. Bien penser à l’asynchronisme pour les forts volumes de façon à ne pas impacter la performance (je pensais que c’était le cas par défaut). Donc, par exemple, pousser dans un volume et paramétrer Logstash pour qu’il vienne dedans pour consommer la donnée.

Bonne pratiques : utiliser les variables d’environnement, le service discovery et le pattern Ambassador.

–add-host à regarder.

Pour ce qui est du backup, se servir du fait que les couches sont partagées et en lecture seule peut faire gagner énormément de place.

 

Security matters (quick talk)

Intéressant d’analyser la liste des autorités de certification racines dans les navigateurs. Il y en aurait un relié à l’armée turque. Ca vaudrait aussi le coup de comparer les navigateurs entre eux de ce point de vue.

Ce qu’on appelle les Extended Validation Certificates sont ceux qui apparaissent avec un nom long dans la barre d’adresse URL des browsers. Ils ne sont pas techniquement plus sûrs, mais la présence d’un nom en lien validé avec le domaine est quand même un plus.

Let’s encrypt est un projet de génération d’autorités de certificats gratuites, qui fonctionne en automatisant la validation de l’identité du demandeur en lui demandant d’installer un callback sur son propre site pour valider qu’il en est le propriétaire. Pas bête comme idée pour shunter toute la partie de validation physique que font les autorités traditionnelles avec le numéro de SIRET, etc.

Rust

Christophe Augier (@tytouf) de WindRiver présente. Super intéressant même si on n’a pas nécessairement le besoin souvent de travailler avec ce genre d’outils. Et le conférencier avait bien préparé et était pédagogue donc on ressort avec une bonne compréhension des concepts. En une heure, je me sens plus capable de m’attaquer à la doc ou de lire un bout de code et de comprendre à peu près ce qu’il fait et sa syntaxe.

Rust = langage de programmation orienté système, mais qui élimine les segfaults et garantit la sûreté du threading. Binding pour s’accrocher sur du code legacy en C ou autre. Plus de 10 ans de développement derrière ce langage, et la version 1.0 sortie le 15 mai 2015.

Orientation des RFC par la communauté (comme Python avec les PEP) : open governance en plus de open source. Compilateur LLVM. Rust utilisé pour Servo, le moteur de navigateur web multithreadé poussé par Mozilla, qui est à l’origine de Rust. Crates.IO pour la gestion des dépendances et des packages (outil Cargo équivalent à NPM). Caractères directement en Unicode.

La règle de nommage des structures (et bien sûr pour d’autres entités) est vérifiée directement par le compilateur.

Les énumérations permettent de définir différents types qui demanderont chacun des ensembles de types différents. Par exemple, une figure peut être de type Cercle (point, rayon) ou de type Carre (cote).

Inutile de déclarer la fonction avant de l’utiliser comme on est obligé de faire en C, même si c’est navrant, de l’aveu même de l’orateur.

Contrôle / Simplicité / Sûreté ne peuvent pas être tous présents dans la gestion de la mémoire. Rust sacrifie surtout le second critère.

Box::new = affectation sur le tas mémoire.

Si personne n’a plus l’ownership sur une box mémoire, on peut la désallouer.

Il ne peut y avoir qu’un seul propriétaire pour la variable. Si on affecte une valeur sur une autre variable, ça plante dès la compilation (« use  of moved value »). Même chose si une fonction utilise une variable qu’on lui a passée : elle prend alors possession de la variable, et donc si on appelle deux fois à la suite la même fonction, le compilateur plante. Evite d’avoir plein de pointeurs sur la même zone mémoire. Pour les types primitifs, pas de problème, car il y a alors copie de la valeur. Pour régler ce souci, on peut faire en sorte que la fonction renvoie la possession de la variable qui lui a été passée. Mais le plus simple est d’utiliser la fonction de borrowing, avec une référence qui permet d’emprunter la ressource (symbole &). Par contre, les références sont immuables pour sécuriser le contenu. Si on souhaite les changer, il faut rajouter &mut au lieu de & seul. La sûreté est gérée par le fait qu’on ne peut avoir qu’une seule référence muable.

Le compilateur vérifie également qu’on référence des objets qui ont au moins le cycle de vie de la référence. Sinon, il dit que la durée de vie de l’objet n’est pas assez longue, au lieu de risquer un problème à la runtime où on pointerait sur un espace mémoire abandonné, et potentiellement utilisé depuis pour autre chose. On peut faire du référence counting avec clone(), comme les smart pointers en C++ (ça ne clone pas la valeur, il y a bien une seule utilisation mémoire, mais ça permet de compter, et donc de purger quand il n’y a plus de clone).

Pour la gestion de la concurrence entre thread, c’est pratique, car Rust ne donne pas un pointeur sur lequel tout le monde peut lire ou écrire, mais compte le nombre de références et permet d’être explicite sur l’autorisation de mutable (qui ne peut être donnée qu’une fois) ou sur la copie de lecture (qui évite les phantom reads, puisqu’il s’agit d’une copie).

Les interfaces sont remplacées par des traits, qui peuvent être ajoutés directement sur les types, sans obliger à hériter une nouvelle classe. On peut par exemple surcharger un entier. Le trait send et le trait sink permettent de partager la donnée de manière sûre entre les threads. Mutex implémente le trait send, et Arc fait de la référence counting atomique entre les threads, et donc gère quant à lui le partage. Dans le code, on fait ensuite un lock pour bloquer le Mutex et un unwrap pour sortir la donnée. Le lock sera automatiquement relâché au moment où on va sortir de la portée.

On peut utiliser la notion de channel, qui force à avoir un send() et un recv(). Pour échanger de la donnée. Au final, Rust va libérer la mémoire pour nous, mais sans GC : c’est juste qu’il analyse – avec l’aide du développeur – la façon dont la mémoire est utilisée. Il empêche la modification de ressources pendant l’utilisation, ainsi que l’accès à de la mémoire qui n’est plus utilisé. Ce mode est d’ailleurs utilisé pour tout type de ressource, et pas seulement la mémoire. Il y a par exemple un trait drop qui fait un peu comme dipose, et qui peut être utilisé pour libérer un fichier dès qu’on a fini la fonction qui l’utilisait.

Pattern Option<T> = Some<T>, None comme dans F# pour éviter de devoir gérer des null. Même chose pour les exceptions qui n’existent pas en Rust, et sont remplacées par une Option<> = Res<T>, Err<U>. Rust fait également du pattern matching sur les types complexes, dits énumérations. Il y a aussi un système de closures, donc on est partis d’un langage proche du système, mais en fait on retombe sur une formulation et des capacités très proches des langages fonctionnels.

Il y a également des macros embarquées (symbole « ! »). Permet de faire de la métaprogrammation.

ASP.NET V5

Notre conférence, en co-présentation avec Benjamin Talmard de Microsoft. Le but était de montrer la simplicité de la nouvelle version d’ASP.NET V5, surtout en lien avec .NET Core. On peut désormais créer un service REST en quelques lignes de code seulement, avec un éditeur de texte au lieu de Visual Studio, un chargement dynamique des dépendances et une exécution dans une CLR modulaire. NodeJS n’a qu’à bien se tenir !

L’exemple utilisé pour la dernière démo est sur https://github.com/jp-gouigoux/mathapi

Rest Groovy

Compte gratuit possible sur APISpark.

Commence par retour sur les principes énoncés par Roy Fielding. Hypermedia As The Engine Of Application State = Hypermedia APIs, HAL, JSON-LD, Siren, etc.

HTTP Status Dogs pour faire apprendre les status codes de manière amusante.

gServ pour exposer de l’API en Groovy. Ratpack est utilisable en Groovy mais aussi en Java. Il permet de créer des délégations entre les handlers. Restlet Framework permet d’exposer, mais aussi de consommer du REST. L’annotation @Grab(nom du fichier) récupère automatiquement les dépendances. Utilisation aussi de @GrabResolver pour donner le serveur sur lequel faire le Grab.

Pour le client depuis un navigateur : Restangular (va au-delà de la pile REST d’Angular) / Restful.js (indépendante de tout FW JavaScript) / autre pour faire de la consommation côté client. Et pour le client depuis un serveur : wslite, etc.

‘http://starwars.apispark.net/v1/people/1’.toURL().text : fait l’appel, car Groovy peut décorer une chaîne avec sa fonction ! Par contre, l’API bloque son UserAgent par défaut, et il faut changer le requestProperties.

Attention, l’URL ci-dessus ne marchait pas (peut-être juste manquait-il HTTPS) et il semblerait que ce soit plutôt quelque chose comme swapi.co/api/planets/1. (avec starships, vehicles, films, etc. comme collections, mais la racine /api donne la liste). DJANGO permet de montrer l’API de manière propre sur l’appel (pas tout à fait le même type d’outil que Swagger, mais un facilitateur également).

httpie est une sorte de curl amélioré qui formate correctement le JSON affiché en retour, fait du pretty-print en couleurs, etc. Postman est capable dans sa version 3 de prendre une définition Swagger en entrée.

Debogage de JavaScript

Alert remplacée par console.log (et on peut mettre dedans un objet, un bout de DOM, etc.)

Console.trace (ne génère pas d’erreur)

Console.count pour les compteurs

Console.table pour afficher les propriétés sous forme de tableau (on peut passer une seconde propriété qui est la liste des colonnes qu’on veut voir lorsque les objets sont trop gros).

Note : IE8 n’active la console que si les outils de dév sont actifs.

Break on subtree modification sur un breakpoint : va s’arrêter sur le code qui modifie le bout de DOM donné.

La case à cocher Async dans la stack trace permet de remonter jusqu’au code depuis lequel le lancement de la commande asynchrone avait été faite.

Simuler la latence du réseau : fonction dans les outils mobiles (deuxième icone en haut à droite dans les outils de développement de Chrome) qui permet de changer le type de réseau.

Snippet permettant de glisser des propriétés devant les champs, de façon à pouvoir tracer les accès en lecture et/ou en écriture sur un attribut donné : debugAccess(l’objet, ‘la propriété’)

Angular.element($0).scope() permet d’accéder aux controleurs Angular.

Node-inspector

Github.com/jollivetc pour récupérer quelques outils.

Push & JSONPatch

Cédric Tran-Xuan de StreamData.IO présente.

Nouvelles technologies ~ 100 centrales nucléaires en 2015. QCon London : retour d’un ingé Google expliquant qu’une réduction de 5% de la consommation a permis d’éviter la construction d’un datacenter.

Applications de plus en plus en « temps réel », dont avec énormément de pull, même s’il n’y a rien de changé => plus performant de passer au push, pour ne pousser que lorsque c’est nécessaire, voir diffuser en triangle pour économiser en descendant.

On peut gagner aussi beaucoup de temps en faisant de l’incrémental. JSON-Patch, RFC 6902, permet de définir la mise à jour d’un document JSON. A croiser avec l’intérêt de faire un PUT uniquement de la propriété voulue sur un tiers : 1) il y a une norme pour ça, et 2) c’est un argument GreenIT qui permet de dire au client que nous DEVONS faire comme ça pour ne pas exploser ses ressources et économiser sa bande passante, ses serveurs, etc.

Ce sont des triplettes { op, path, value } avec op = replace / add / remove, mais aussi copy / move / test. http://jsonpatch.com pour plus de détails. On peut bien sûr patcher un envoi à un serveur, mais on peut aussi demander l’envoi d’un patch pour n’avoir que la mise à jour des données, et pas toute la liste. JSONPatch est implémenté dans de nombreux langages, y compris C#. JSONPatch, en fait c’est un DiffGram, mais en JSON au lieu de XML.

Techniques de push : encore plus efficace serait d’envoyer juste l’info en push comme quoi il y a eu changement, puis laisser le client décider de faire l’appel dans l’autre sens pour récupérer la donnée elle-même (avec JSONPatch, au passage).

Exemple utilisé sur les Vélib typique de données nombreuses, mais dont une part faible est modifiée à chaque instant, donc intérêt particulier à ne surtout pas tout télécharger à chaque fois, mais à recevoir uniquement les changements.

Difficile de faire ouvrir un port, et certains load balancers ne supportent pas les websockets. Le système de handshake nécessite un support par le serveur. D’ailleurs, les websockets sont sans garantie de reconnexion lors de la perte de déconnexion.

Conclusion

Comme d’hab’, de la top qualité de présentations au BreizhCamp ! Dommage d’avoir pu être présent que le second jour… Merci à tous les intervenants pour nous offrir de tels concentrés de savoir !

About JP Gouigoux

Jean-Philippe Gouigoux est Architecte Logiciel, MVP Connected Systems Developer. Il intervient régulièrement à l'Université de Bretagne Sud ainsi qu'à l'Agile Tour. Plus de détails sur la page "Curriculum Vitae" de ce blog.
This entry was posted in Retours and tagged . Bookmark the permalink.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha Captcha Reload