BT

Diffuser les Connaissances et l'Innovation dans le Développement Logiciel d'Entreprise

Contribuez

Sujets

Sélectionner votre région

Accueil InfoQ Articles Startup Architecture : Vert.x et Kubernetes chez Coursier Privé

Startup Architecture : Vert.x et Kubernetes chez Coursier Privé

À l'occasion de Microsoft experiences '16, InfoQ FR a pu échanger avec Vincent Wuhrlin et Théo Bolognini de Coursier Privé sur leur architecture technique et notamment leur stack Vert.x, packagée en Docker et déployée via Kubernetes sur Azure.

InfoQ FR : Bonjour Vincent, bonjour Théo, avant d'entrer dans l'architecture technique, pouvez-vous nous parler de votre service en termes métier ?

Vincent : Coursier Privé est un outil flexible et modulaire qui optimise les flux de livraison au sein de son écosystème, en centralisant et en coordonnant tous les acteurs (donneurs d’ordre, entrepôts urbains et prestataires de livraisons) sur une seule et unique interface.

Basée sur l’automatisation de la gestion d’activité, combinée à des briques de service améliorant l’expérience utilisateur, la technologie est disponible sous forme de modules à forte valeur ajoutée.

Chaque acteur peut ainsi : 1. Connecter son propre réseau de livreurs pour contrôler et améliorer le service rendu à ses utilisateurs. 2. Faire appel au réseau déjà connecté à la technologie pour faire livrer ses colis.

CoursierPrivé.com s’appuie sur ses propres algorithmes d’optimisation et des méthodes d’analyse big data pour apporter des solutions en temps réel aux problématiques de livraisons urbaines.

InfoQ FR : Est-ce que vous pouvez nous décrire votre architecture globale ?

Vincent : Commençons par l'architecture fonctionnelle : typiquement, aujourd'hui, on a une architecture qui est simple, avec des microservices dans le cloud, load-balancés, avec à chaque fois donc plusieurs instances du microservice. On a ensuite quatre applications qui tournent autour :

  • notre site web, qui peut aussi interagir avec ces microservices,
  • un autre dashboard, puisqu'on a une plateforme SaaS de mise en relation,
  • une API mobile, qui est une API spécifique aux terminaux mobiles pour pouvoir gérer les courses, un petit peu à la Uber,
  • et enfin une API REST, qui est l'API donneurs d'ordre qui permet de commander des courses via l'application.

Donc quatre applications qui gravitent autour des microservices, et qui interagissent entre elles grâce à l'Event Bus de Vert.x, qui repose lui-même sur un cluster Hazelcast. C'est l'architecture, en vue bas niveau.

On a donc cinq applications : les microservices et composants qui tournent autour, et ces cinq applications ont des cycles de vie, comme tout logiciel informatique, différents, avec des dépendances entre eux.

Ensuite, on a une architecture plus technique, qui est là plutôt liée à une technologie, Kubernetes. On a été les premiers à l'intégrer dans Azure puisque Théo travaille sur cette technnologie depuis maintenant septembre, c'était une technologie qui était à peine en 1.0 en septembre, qui était proposée bien sûr sur Google Cloud puisque c'est Google, qui commençait je crois à être sur AWS, par contre sur Azure il n'y avait strictement rien, et Théo a travaillé avec une personne à Seattle de chez Microsoft qui commençait à travailler sur la gestion native des services Azure dans Kubernetes.

Théo : Pour la petite histoire, Azure a commencé à développer ses services de conteneurs Docker en offre services avec une technologie qui s'appelle Mesos, et qui est donc l'orchestrateur de conteneurs Docker qu'Azure avait mis en avant. À la base, Azure voulait développer leur service de conteneur avec Kubernetes, mais à cause du développement qui était un peu tardif, à cause des versions qui étaient assez peu développées à ce moment-là, ils n'ont pas vraiment choisi cette voie là, et donc ça fait un peu près un an qu'il y a du travail qui est fait chez Microsoft Seattle pour intégrer Kubernetes (qui est donc un projet libre) sur Azure et permettre de pouvoir utiliser cette technologie là en mode un peu plus natif, sans avoir besoin de faire des tweaks, des hacks, des déploiements custom pour pouvoir utiliser cette technologie.

Pour rester un peu sur Kubernetes, il va permettre l'orchestration des conteneurs Docker au travers de plusieurs machines, que ce soit à travers le monde, à travers des data centers, ou de clusteriser sur un même data center, et Kubernetes permet ce que ne permet pas Docker tout seul, c'est-à-dire la gestion de la communication entre conteneurs Docker sur plusieurs machines, ce que ne permet pas par défaut le Docker Engine comme il est développé de base. Ça permet en gros, si on revient un peu sur l'aspect applicatif, sur ces quatre applications qui marchent entre elles, nous notre objectif a été en termes d'architecture de porter ces applications et de les intégrer dans des conteneurs Docker. Toutes nos applications Vert.x Java sont intégrées dans un conteneur Docker spécifique qui va être facilement déployable sur n'importe quelle machine ayant le Docker Engine.

InfoQ FR : Vous avez donc quatre conteneurs : un conteneur par application ?

Théo : Exactement. On va avoir donc un conteneur par application, un conteneur pour le Dashboard, un pour l'API, un conteneur pour les services qui nous permettent de faire fonctionner tout ça en même temps, et donc on se retrouve avec cinq conteneurs qui sont maintenus et qui sont gérés indépendamment les uns des autres. Et c'est pour ça qu'on part sur une architecture dite microservices puisque chaque application et chaque conteneur sont indépendants l'un de l'autre, et sont capables de fonctionner de manière indépendante. Il y a des mises à jour au niveau de ce fonctionnement, on peut mettre à jour un conteneur sans que cela n'impacte forcément un autre qui est dans le même environnement.

InfoQ FR : Les quatre applications sont-elles toutes en Vert.x ?

Théo : Oui, et Hazelcast clusterise l'Event Bus.

InfoQ FR : Et votre storage ?

Vincent : On a du MongoDB pour tout ce qui est, comment dire, données propres au métier. On a aussi de l'elasticsearch parce qu'on a une petite partie des data qui sont visualisées sur Kibana, mais plutôt exploitation ; et là on est en train de développer sur Azure une partie data plutôt métier qui sera sur PowerBI directement. Mais en tous cas, on utilise elasticsearch pour une partie Big Data et bien sûr pour un aspect recherche dans les données.

Théo : On utilise elasticsearch surtout dans le cluster. Toutes nos applications sont des conteneurs Docker, quoi qu'il arrive, MongoDB, elasticsearch, Kibana, etc. Et on utilise forcément elasticsearch dans tout ce qui est cluster, pour faire une centralisation des logs, puiqu'on va se retrouver avec énormément de replicas des mêmes applications, et elles vont toutes générer du log, et donc il va falloir qu'on aie des solutions de monitoring de logs et de centralisation. C'est pour ça qu'on utilise la technologie qu'on appelle ELK (elasticsearch, Kibana & Logstash), et donc elasticsearch va nous permettre de stocker la Data, Logstash va nous permettre de la shipper et Kibana va nous permettre de l'afficher, tout simplement. C'est vraiment une brique qui a été importante à implémenter pour faciliter l'utilisation, quand on se retrouve avec 40 replicas, c'est pas possible...

InfoQ FR : Vous l'utilisez en SaaS (Elastic Cloud) ?

Théo : Non pas du tout, on a customisé les images Docker et on a créé des images Docker pour notre propre besoin en utilisant des produits Elastic, dont elasticsearch.

C'est vraiment intéressant justement, avec l'environnement Kubernetes qui nous permet vraiment de clusterer des conteneurs, c'est qu'elasticsearch en production on l'a en répliqué en trois parties, c'est-à-dire qu'on a la partie Client, la partie Data qui va stocker de la Data, et on a la partie Master qui va gérer le cluster elasticsearch. Et tous ces nodes là, on peut les répliquer, les scaler, vers le haut, les scaler vers le bas, et derrière ça on a aussi des solutions de backup, là par exemple notre Data va être backupée sur du storage répliqué Azure qui va nous permettre d'assurer la pérénnité des données si jamais on a des problèmes au niveau des VM, si on a des problèmes au niveau du cluster. Si quelque chose se passe mal, on a toujours la data qui est en backup de manière linéaire depuis les nodes d'elasticsearch.

InfoQ FR : Vous faites donc des Snapshots sur storage, c'est bien ça ?

Théo : Exactement et même plus que ça en fait, on a un système sur Kubernetes qui nous permet de monter directement sur un conteneur Docker, et sur Kubernetes le concept appelle le conteneur Docker un pod, le pod est un conteneur Docker. Et on a la possibilité de monter un disque Azure directement sur un pod spécifique. Et donc de s'abstraire de toute problématique de montage sur la machine en elle-même, de montage sur un système de fichier spécifique, on a juste à monter ce VHD et lui, il est déjà répliqué puisqu'il fait partie du service Azure Storage, qui lui-même est répliqué dans le Data Center. Notre application écrit directement en fait, utilise ce filesystem nativement, comme un système local, mais il est répliqué et sauvegardé dans les storages Azure, ce qui est vraiment intéressant. Au lieu d'utiliser les stockages de la machine directement, on va utiliser un stockage externe déjà répliqué.

Vincent : Juste pour rebondir sur le système Vert.x plus event bus et Hazelcast, on a pris beaucoup de temps à stabiliser tout ça, parce que c'est encore neuf, il n'y a pas beaucoup de documentation en prod sur clusters, etc, c'est un peu dommage. Il y a des astérisques qui disent parfois "attention", bon bref c'est un peu caché. Mais on apprécie énormément. Avant on était sur Redis, on avait une architecture master/slave dessus, là on est passé sur Hazelcast qui est un autre système avec n noeuds qui sont tous reliés les uns aux autres, il y a quand même un master mais chacun peut devenir master par un système d'élection, et du coup aujourd'hui, orchestrer un besoin fonctionnel dans le cluster, on a un besoin tout simple, par exemple on a 30 instances d'une application, si on doit en killer 20 pour réduire à 10 pour réduire notre charge, faire un verrou distribué, synchronisé pour que chaque application se locke les unes par rapport aux autres, c'est fait en vingt lignes de code.

C'est ça qu'on apprécie maintenant, c'est que c'est très simple de synchroniser plusieurs instances, alors que c'est quand même des problématiques cloud qui sont complexes. Et puis au final, là aujourd'hui on veut par exemple des microservices, on peut upscaler 40, 50, 60 instances, on peut downscaler jusqu'à zéro, là si on veut downscaler jusqu'à zéro, on va avoir des erreurs techniques sur le Dashboard, avec les microservices, on peut de nouveau upscaler jusqu'à 10, les clusters se stabilisent automatiquement à 10 et ça re-marche. On a vraiment une totale souplesse, simplement en un clic de souris, et bien sûr l'usage à terme c'est d'automatiser sa descente de charge et s'adapter aux métriques d'exploitation.

Théo : Et ce qui est hyper intéressant c'est qu'on a une scalabilité sur toute la chaîne, c'est-à-dire du front jusqu'à l'infrastructure. Pour être capable de pouvoir scaler nos machines, qui font partie de notre cluster d'exploitation, on va être capable de scaler nos conteneurs Docker, qui sont donc nos applications, et ça va nous permettre d'avoir une infrastructure qui suit les demandes aussi du front et des applicatifs au final. Ça c'est hyper intéressant.

On a de l'autoscale qui est possible sur Azure, c'est vraiment pas loin car Kubernetes intègre une sorte de technologie d'autoscaling en fonction de l'utilisation de CPU de chaque node, donc on peut faire de l'optimisation CPU. Le truc étant que ça continue de se développer et que toutes ces problématiques là sont déjà gérées sur GCE par exemple, parce que Kubernetes est obligé de pouvoir le faire.

Vincent : Aujourd'hui on a les métriques CPU et mémoire de l'addition de tous les pods, donc on sait en temps réel ce qui se passe, il suffit de récupérer cette API Kubernetes et d'augmenter le nombre d'instances.

Théo : En une seule ligne en fait, c'est que nos ressources Kubernetes sont définies par des fichiers de déploiement, tout simplement, et ces ressources sont dynamiques. Donc en fait un déploiement peut être édité à la volée et donc le nombre de replicas de notre application sont éditables à la volée. Donc à partir ce moment là, on peut totalement avoir un autoscaling dynamique de nos applications. Après c'est un peu dangereux parce que l'autoscaling est un peu bancal, parce que des fois il réagit mal.

InfoQ FR : Quelle est votre stratégie de construction de votre environnement Kubernetes ?

Théo : Aujourd'hui, dans Kubernetes, s'il y a vraiment quelque chose de compliqué, c'est l'installation, c'est-à-dire le "bring up" sur des machines quelconques. Tous les cloud providers en fournissent, mais ce qui est compliqué c'est d'automatiser tout ça : la création des machines sur la plateforme, et l'installation de manière automatique de Kubernetes avec le master et les nodes qui s'ensuivent. Tout ça, on appelle ça le "bring up" et il y a des solutions qui existent sur lesquelles on bosse aussi en contribution parce que ce sont des projets open source. Il y en a une en particulier qu'on utilise actuellement qui s'appelle kubernetes-anywhere, et cette solution justement est développée par Kubernetes et nous permet de déployer des clusters sur Azure, mais aussi sur GCE et sur Amazon.

Et donc on utilise la technologie Terraform dans cet outil là pour avoir un sampling, un templating de déploiement infrastructure, et ensuite un templating de déploiement Kubernetes. Il y a vraiment deux niveaux : l'infrastructure et ensuite Kubernetes.

InfoQ FR : Vous utilisez Terraform sur Azure ?

Théo : Oui, exactement. À la base on utilisait Ansible, et on a abandonné Ansible pour Terraform, et derrière ça on utilise une image Docker custom qui s'appelle Ignition, qui va nous permettre d'automatiser le déploiement de Kubernetes sur notre cluster de machines. Ça c'est vraiment la partie qui est intéressante parce que ce petit outil est très facilement modifiable et on peut ajouter des fonctionnalités en fonction de nos besoins, comme justement le déploiement de disque dur persistant en ajout, des choses dont on aurait vraiment besoin en fonction de nos besoins personnels. Actuellement, nous, sur nos machines, on utilise des disques durs éphémères que propose Azure, toutes les machines qui sont de la série DS ou DS GS ont des disques durs SSD locaux qui nous permettent d'avoir des perfs en termes d'entrée/sortie sur le disque énormes, que ne propose pas Azure en service pur. Et donc on arrive à atteindre des 40.000 entrées/sorties sur disque, qu'on ne pourrait pas avoir en termes de stockage classique, et donc on a tweaké ce petit outil, kubernetes-anywhere, qui nous permet de monter sur chaque node de notre cluster, à chaque fois, ce fameux SSD éphémère, et on monte donc le coeur de Docker sur ce SSD là. Et donc toutes nos applications ont accès à ce vivier d'entrées et sorties.

Vincent : Ça c'est un concept un peu tordu, mais aujourd'hui on a pas trop de recul sur ça, mais on peut se dire qu'avec l'architecture à disposition des ressources (la réplication), on pourrait avoir une base de données éphémères, parce que la probabilité que toutes les machines de base de données se crashent en même temps est faible.

Théo : Le seul risque étant que si le data center se casse la gueule, là ce mécanisme ne marcherait plus. Mais il y a encore des possibilités de faire du multi clustering à travers différents datacenters qui sont de la réplication aussi et qui nous permettent encore de voir plus loin. Kubernetes permet ça : d'avoir un cluster à un endroit T, et un autre cluster à un autre endroit.

InfoQ FR : Y-a-t-il dans Azure le concept de multi-datacenters dans une même région (une AZ au sens AWS par exemple) ?

Théo : Oui, sur Azure, ils appellent ça le "failure domain", et chez Kubernetes aussi on a ça, donc lors du déploiement, nos machines sont déployées dans trois failure domains différents. Donc on a cette sécurité là. Azure fournit cette brique là, c'est-à-dire qu'on déploie des virtual machines dans un "availability set", donc en gros ces machines là font partie de l'availability set, et en gros ne peuvent pas être mises à jour en même temps et sont toutes dans un failure domain différent, et Kubernetes aussi dans son déploiement intègre cette ressource là de failure domain. Donc on a un link entre ces deux ressources là, qui permettent vraiment d'avoir une sécurité à ce niveau là. Et on a aussi les persistent disks qui nous permettent d'externaliser la donnée sur du vraiment service Azure. Donc après si le data center tombe, on est d'accord que ça a énormément de problématiques là-dessus.

Je pense qu'à terme, quand le développement du business sera important, on aura beaucoup de data à gérer, on sera répliqué à travers plusieurs datacenters ce qui nous assurera une pérennité des données encore plus forte.

InfoQ FR : Quels sont les plus gros avantages de Kubernetes, pour vous ?

Vincent : Ce qui est marrant dans Kubernetes, c'est un peu l'aspect "virus", c'est-à-dire que quand on connaît pas trop Kubernetes, souvent on arrive, on déploie un pod, si on le tue, automatiquement il se redéploie n'importe où. Il revit automatiquement.

Théo : Il y a plusieurs niveaux de gestion, c'est-à-dire que Kubernetes abstrait plusieurs concepts, abstrait le conteneur Docker en rappelant le pod, mais abstrait aussi tout ce qui est réplication en... le fait est qu'un pod est géré par un replication controller ; et donc ce replication controller dans le cluster s'assure que tu as demandé trois pods, tu auras toujours trois pods. Tu en as un qui se fait killer, le replication controller va être obligé d'en redéployer un autre, et va assurer la pérennité de ton redéploiement.

Ça c'est hyper intéressant parce que ça c'est pour les conteneurs Docker, mais il y a aussi ce même mécanisme là pour tout ce qui est exposition de nos applications vers l'extérieur, le load-balancing, et le fait de pouvoir dispatcher le trafic réseau entre tous nos pods. Et ce qu'on fait, c'est que dans notre architecture, on a un load-balancer Azure en entrée, à l'entrée de notre cluster, notre balancer va prendre le trafic entrant, et lui va le dispatcher ensuite vers Kubernetes. Kubernetes en fait abstrait la couche et le link que tu as entre le load balancer Azure, et sa propre ressource de load balancer à lui. Parce que lui il a une ressource qui s'appelle le service, et le service c'est lui qui s'occupe d'attribuer des adresses IP, et de les load balancer entre les différents replicas de ton pod. Et ça en gros, ce qui est hyper intéressant c'est que l'intégration, vraiment pour avoir un exemple concret d'intégration Kubernetes dans Azure, c'est ça, c'est que dans GCE, quand tu définis un service Kubernetes, tu dis que tu veux un type load balancé. Et en gros, GCE va automatiquement sur son infrastructure, te faire un lien, te créer un load balancer, et t'attribuer une adresse publique pour ce fameux pod que tu as voulu load balancer. Et ça, ce n'était pas le cas sur Azure au début.

Et donc il y a eu une intégration de faite, ce qui fait qu'aujourd'hui maintenant quand je dis que je veux un type de service load balancé, Azure automatiquement va me fournir une adresse IP publique et va me load balancer mon application et va me créer ce lien-là. Ça, ça fait partie des travaux que fait un certain Cole (NdR: Cole Mickens) qui travaille à Microsoft Seattle, qui est en train de développer ça encore et encore. Et c'est aussi le persistent disk qui abstrait toute la problématique de montage de disque et ainsi de suite, ça aussi c'est de l'intégration native Azure Kubernetes, qui est disponible sur notre plateforme, mais qui n'était pas disponible sur Azure.

Tout ça, ça répond quand même à des problématiques de base, on ne peut pas utiliser une techno comme Kubernetes si on a pas ce genre d'intégration.

Mais on a eu la chance de tomber sur ce fameux Cole, par hasard sur Slack, parce que j'avais justement des problèmes d'intégration sur Azure, et on a commencé à discuter, et c'est vrai que ça a matché, et on est vraiment au plus proche du développement parce qu'on a vraiment ce contact là à Microsoft Seattle. Lui-même a été embauché dans le pôle Azure Container pour apporter Kubernetes à Azure, et faire en sorte que les choses aillent plus vite, parce qu'Azure a compris, du moins Microsoft a compris, que Kubernetes était vraiment une brique très importante, et que Mesos reste encore trop lourd. Et avec une différence d'inertie forte.

InfoQ FR : Et en termes de CI/CD (Intégration Continue et Déploiement Continu) ?

Théo : On a beaucoup travaillé pour avoir un pipeline de build et de déploiement automatisé. On utilise Jenkins, qui d'ailleurs est déployé lui-même en tant que conteneur Docker. On a même un master Jenkins qui instancie des slaves dans notre cluster, dynamiquement, selon les jobs en cours.

Jenkins surveille donc les repositories GitHub et BitBucket, builde, puis pushe les images Docker construites sur DockerHub. Jenkins exécute ensuite les commandes Kubernetes nécessaires pour qu'en quelques minutes, les développeurs puissent voir leur nouvelle version s'exécuter sur notre cluster de dev. Donc intégration continue et déploiement continu.

Ensuite en préproduction et production, ce qui est important pour nous c'est de déployer de façon sélective. On va pouvoir dire que l'on prend le tag v0.2 sur Jenkins pour le déployer sur la pré-prod par exemple, et Kubernetes va récupérer ce tag automatiquement. Il faut garder cet aspect humain.

Et tout ça apporte un confort et une flexibilité hallucinante en termes de dev. Pour info, from scratch, de vraiment zéro, on peut tout redéployer en 15 minutes.

InfoQ FR : Merci Vincent et Théo et à bientôt !

Vincent et Théo : À bientôt !

Evaluer cet article

Pertinence
Style

Contenu Éducatif

BT