Comment améliorer la résilience de votre système informatique ?
🚨

Comment améliorer la résilience de votre système informatique ?

PLAN

Introduction

  1. Augmenter la résilience avec le partitionnement aléatoire
  2. Concevoir des architectures résilientes avec l'approche cellulaire
  3. Tester la résilience des systèmes distribués avec l'ingénierie du chaos

Conclusion

INTRODUCTION

Ces dernières années, différents styles architecturaux de développement de logiciels ont émergé pour répondre à des besoins spécifiques, chacun avec ses propres avantages et inconvénients.

En cas d'erreur, l'architecture traditionnelle monolithique présente le risque d'effondrement total du système. L'architecture microservices quant à elle, divise le système en petites unités indépendantes, mais elle reste vulnérable aux pannes. Au lieu de rechercher une fiabilité totale, il est préférable de mettre l'accent sur la résilience, qui est liée à la capacité d'un système à résoudre les problèmes et à maintenir son fonctionnement. En effet, dans le contexte des systèmes informatiques, la seule constante c’est que "Tout se casse un jour".

"Everything fails, all the time" Werner Vogels, CTO Amazon

Dans cet article, nous allons présenter quelques approches pour renforcer la solidité et la résilience des systèmes informatiques, dont l'approche cellulaire ainsi que l'ingénierie du chaos.

Contexte

Prenons un cas fictif d'une entreprise de commerce électronique avec une architecture microservices déployée sur des clusters Kubernetes EKS gérés par AWS.

Un jour, suite à un incident et des alertes d’indisponibilité dans la zone de disponibilité active (eu-west-3), les ingénieurs basculent vers une autre zone passive (eu-west-1), mais rencontrent le même problème. Cet incident a résulté en un downtime de 5 heures sur leur site.

Après des investigations, les ingénieurs ont conclu que l'incident est dû au comportement d'un groupe d'utilisateurs ou à un flux de demandes. Ce phénomène est connu par le nom de "la pilule empoisonnée" qui a un effet global, même si on change d’environnement. Plusieurs solutions sont possibles pour éviter que ça se reproduise, parlons tout d’abord de l’approche du partitionnement aléatoire.

Augmenter la résilience avec le partitionnement aléatoire

Le partitionnement ordinaire gère toutes les demandes avec une flotte d'agents, ce qui permet une gestion efficace en cas de défaillance d'un agent. Cependant, les problèmes surviennent lorsque les défaillances sont causées par le type ou le flux de demandes (Attaque DDoS par exemple), ce qui peut entraîner des pannes générales du système.

image

C'est là qu'intervient le partitionnement aléatoire. Celui-ci divise la flotte en groupes de serveurs, chaque groupe étant chargé de gérer les demandes d'une population de clients spécifique. Par conséquent, si un problème survient avec les demandes d'un client, seule la partie responsable de ce client est affectée, ce qui réduit considérablement l'impact global. Pour bien comprendre ce concept, nous allons prendre le cas d’une flotte constituée de 8 agents qui gère les demandes provenant de 8 clients ; nous attribuons dès lors une lettre à chaque catégorie de clients.

image

Si on suppose que le client A est à la source du problème (demande dangereuse ou attaque par flux de demandes), tous les agents qui gèrent ce client seront endommagés ( -1- et -4- ). Ainsi, une perte de 25% de l’effectif d’agents sera constatée mais l’impact du problème sera réduit. En effet, même les clients qui partagent ces serveurs avec le client A auront d’autres agents pour traiter leurs demandes ( Clients B et F ).

image

Par exemple, le service AWS Route53 d’Amazon utilise le partitionnement aléatoire pour la gestion des noms de domaine. Cette méthode donne à chaque nom de domaine une partition distincte, ce qui garantit que les attaques DDoD ne touchent que les serveurs concernés sans affecter les autres clients partageant les serveurs.

En addition du partitionnement aléatoire, l'adoption de l'architecture cellulaire est une autre stratégie cruciale pour améliorer la résilience des systèmes informatiques. Cette méthode améliore la disponibilité des services et réduit la surface d'impact des pannes.

Concevoir des architectures résilientes avec l'approche cellulaire

Une architecture cellulaire est un modèle d'architecture qui groupe un sous système avec tous ses composants dans des unités appelées cellules, garantissant ainsi une gestion décentralisée.

Une cellule est donc une entité totalement autoconsistante qui peut être gérée, distribuée et observée indépendemment.

Les cellules doivent contenir tout ce qu'il faut pour leur fonctionnement (service, couche données, load balancer). Nous veillons à ce que rien ne puisse intéragir avec la cellule sauf à partir des portes d'entrée que nous définissons. Ainsi nous garantissons qu'en cas de défaillance, nous allons limiter sa propagation ainsi que dans une cellule.

Pour assurer le bon fonctionnement de notre système, on met en place un plan de contrôle qui sera responsable du placement, de la supervision, du déploiement et de la migration. Le routage vers la cellule correspondante sera effectué par un routeur global.

image

Nous commençons à observer la différence entre la logique de "multi-zones de présence" et celle de l'architecture cellulaire. Il est toutefois possible de combiner les avantages des deux approches en répartissant nos cellules sur différentes zones de disponibilité (AZ) pour garantir une plus grande disponibilité.

À ce niveau, nous avons identifié les différents niveaux sur lesquels nous devons nous concentrer pour concevoir des systèmes résilients :

  • Le niveau logiciel avec des applications tolérantes aux pannes
  • Le niveau infrastructure avec une infrastructure souple, élastique et “self-healing”.
  • Le niveau opérationnel avec une supervision, une observabilité et une gestion d'incidents efficace.

Cependant, nous n'avons pas encore abordé un niveau très intéressant, celui des tests. Il est essentiel de tester régulièrement la capacité de nos systèmes à résister à des conditions inattendues. C'est là que l'ingénierie du chaos entre en jeu. Explorons comment cette discipline d'expérimentation sur des systèmes en production renforce la confiance dans leur capacité à résister aux défaillances.

Tester la résilience des systèmes distribués avec l'ingénierie du chaos

L'ingénierie du chaos est une discipline d'expérimentation sur les systèmes distribués pour renforcer leur résilience face à des conditions turbulentes en production. Initialement développée par Netflix, elle repose sur des outils et des processus dédiés. L'ingénierie du chaos ne se demande pas si notre système va échouer un jour, mais en partant du principe que cela se produira tôt ou tard, la question à se poser est : 'Comment pouvons-nous le casser ?’ Dans la plupart des cas, nous mettons en place des processus de test pour couvrir toutes les étapes d'implémentation avant la mise en production. Cependant, cela ne suffit pas ! Nous devons également effectuer des tests dans nos environnements de production pour avoir la confiance nécessaire en nos systèmes. Ces tests visent à étudier le comportement du système face à une panne et à identifier les éventuelles faiblesses inconnues.

L’ingénierie du chaos n'est pas aussi chaotique que son nom le laisse entendre. Elle est soumise à des normes et des procédures claires :

image
  1. Définir notre "État stable". On précise les métriques qui caractérisent cet état et valider le résultat de notre test.
  2. Définir notre hypothèse: ” Est ce que le composant X sera résilient face à l'événement Y ? ”
  3. Définir le périmètre du test: Allons-nous tester un environnement technique bien défini ? Allons-nous inclure le comportement humain dans le scope de l'expérience ?
  4. Communiquer l'existence du test pour éviter la propagation des pannes résultantes.
  5. Introduire les variables qui simulent un événement réel : des serveurs qui tombent en panne, des disques durs qui fonctionnent mal, des connexions réseau qui sont coupées, etc.
  6. Valider ou pas l'hypothèse en analysant les métriques et en cherchant une différence entre l'état actuel et l'état stable.
  7. Améliorer le système en cas d'impacts sur son fonctionnement, et retour à l'état stable de nouveau.

Dans la majorité des cas, lancer ces tests manuellement n'est pas suffisant pour affirmer la résilience du système surtout avec la fréquence des livraisons avec les démarches agiles et DevOps. Donc il est conseillé d'automatiser ces expériences.

AWS met à dispositions des services afin de simuler des événements réels sur les systèmes. Le service “AWS Fault Injection Simulator” offre la possibilité de simuler des pannes sur des cibles qu'on définit. Des exemples de pannes peuvent être : l'injection d'une latence, la terminaison d'instances, l'augmentation de consommation d'une tâche, etc..

Des conseils à mettre en tête en effectuant des expériences:

  • Commencez petit
  • Entraînez-vous aussi proche de la production
  • Démarrez par des expériences simples, gagnez en confiance et automatisez
  • Minimisez la surface d'impact

Conclusion

La quête de la résilience des systèmes informatiques est essentielle face aux pannes et aux défaillances inévitables. Nous avons exploré des approches clés pour renforcer la solidité et la résilience de vos systèmes : le partitionnement aléatoire, l'architecture cellulaire et l'ingénierie du chaos.

Rappelons-nous que "Tout se casse un jour", mais en adoptant des pratiques résilientes, nous sommes mieux préparés à relever les défis et à assurer la continuité de nos systèmes dans un monde numérique en constante évolution.

Article issu de notre participation à AWS Summit Paris 2023

Merci pour votre lecture. Cet article vous a plu, partagez sur vos réseaux 😉

Tarek Jarrar - juin, 2023

image