• Tarifs
  1. Accueil
  2. Blog
  3. Ingénierie Logicielle
  4. Stabiliser Keycloak à grande échelle : Outils de dépannage et d'investigation
stabilizing-keycloak-at-scale

Stabiliser Keycloak à grande échelle : Outils de dépannage et d'investigation

par Silvan Jegen

Cet article est également disponible en Allemand, Anglais, Indonésien, Italien et Portugais.

Silvan Jegen, ingénieur logiciel de Smallpdf, explore les problèmes rencontrés lors de l'authentification à travers Keycloak et comment y remédier.

Chez Smallpdf, nous avons introduit Keycloak pour l'authentification à l'été 2021. Comme pour la plupart de nos nouvelles implémentations, le processus d’introduction ne s'est pas fait sans heurts et a pris beaucoup plus de temps que prévu. Dans cet article, Silvan Jegen, ingénieur logiciel chez Smallpdf, se penche sur les problèmes rencontrés et sur les méthodes que nous avons utilisées pour les examiner et les résoudre.

Problèmes de stabilité

 

Notre configuration initiale comprenait plusieurs instances de Keycloak, chacune avec un cache Infinispan intégré. Lorsque nous avons mis ces instances en service, nous avons rapidement rencontré des problèmes de stabilité, les nœuds se retrouvant sans mémoire et devant être redémarrés. Ces redémarrages entraînaient également la perte des sessions utilisateur et la déconnexion des utilisateurs.

Plusieurs mois d'expérimentation ont suivi pour trouver une solution à ces problèmes de stabilité. Nous avons essayé différentes combinaisons de caches Infinispan intégrés et externes avec différentes options de persistance. Pendant un moment, nous avons utilisé l'option de persistance SIFS pour un cache Infinispan externe, mais après environ deux semaines, cette configuration a mené à une panne.

Nous avons finalement opté pour une configuration avec plusieurs instances Keycloak, toutes connectées à un cluster Infinispan externe. Lorsque nous avons déployé suffisamment de nœuds pour maintenir la charge de production à la fois du côté de Keycloak et du côté d'Infinispan, nous avons pu terminer cette expérience avec un système de production stable.

Quel a été le processus pour trouver notre configuration actuelle ?

Tests de charge

 

Notre expérience avec Keycloak+Infinispan avec RocksDB nous a montré que notre charge de travail de production n'était pas aussi proche des conditions de test de charge que nous le pensions. La première mesure que nous avons prise pour nous assurer que ces pannes ne se reproduiraient pas a donc consisté à recourir davantage aux tests de charge.

L'outil que nous avons utilisé pour cela était "k6", qui nous permet (grâce au script JavaScript) de générer des requêtes avec un contrôle fin et d'adapter la manière dont elles sont envoyées (c'est-à-dire la fréquence, la durée, etc.).

Nous avons dû passer d'un ancien système d'authentification à Keycloak et avons donc dû envoyer des demandes de subvention directes à notre instance Keycloak, simulant ainsi la création de nombreuses sessions dans notre cluster. Pour ce faire, nous avons utilisé le script suivant :

Pour exécuter ce script avec "k6" pendant une heure avec 16 connexions TCP afin d'envoyer des requêtes en parallèle, tu peux utiliser la ligne de commande suivante :

Remarque : lorsque tu utilises ce script, tu crées plusieurs sessions de subvention directe pour le même compte utilisateur. C'est possible, mais ce n'est pas forcément ce que tu veux tester.

La solution au problème

 

En utilisant "k6" pour charger les sessions et en examinant les métriques JVM et les journaux que nous collectons dans notre solution d'observabilité, nous pouvons vérifier s’il est possible de s’attendre à ce que notre configuration puisse supporter notre charge de production.

Il s'avère que le chargement direct des sessions dans Infinispan avec "k6", au lieu de passer par Keycloak, ne reflète pas exactement ce qui se passerait si nous utilisions Keycloak avec Infinispan en production. Pour obtenir les meilleurs résultats, nous recommandons donc d'envoyer les sessions à Keycloak à l'aide du script ci-dessus plutôt que de les charger directement dans Infinispan - même si cela est plus rapide.

Sessions perdues

 

Dès que nos clusters Keycloak et Infinispan se sont stabilisés, nous nous attendions à ce que le nombre d'erreurs de tokens de rafraîchissement que nous avions observées auparavant diminue. Bien que ce fut le cas, les erreurs restaient quand même plus nombreuses que prévu. Cela signifie que des milliers d'utilisateurs étaient encore déconnectés chaque jour parce qu'ils recevaient un message d'erreur en essayant de mettre à jour leur clé d'accès.

Obtenir plus d'informations

 

Nous sommes retournés à la table à dessin. Pour déboguer ce problème, nous avons d'abord consulté le registre des événements fourni avec Keycloak. Cependant, le niveau de consignation par défaut défini dans le système était trop élevé pour nous permettre d'obtenir les informations qui nous intéressaient. Pour obtenir des rapports plus détaillés, nous avons donc réglé le niveau sur "DEBUG". Sache cependant que ce niveau génère un grand nombre de données. Si tu sauvegardes ces rapports d'événements dans la base de données relationnelle de Keycloak et que tu as un trafic important, il est probable que cela te posera des problèmes.

Les rapports obtenus de cette manière ne contenaient toujours pas les détails d'erreur dont nous avions besoin pour identifier la source des erreurs de tokens de rafraîchissement. Nous avons fini par modifier le code de notre instance Keycloak pour ajouter plus de détails que les erreurs génériques fournies, ainsi que les identifiants de session. Ces modifications nous ont permis d'associer plus facilement les erreurs de tokens de rafraîchissement aux événements de connexion correspondants.

Avec ces informations supplémentaires en main, nous avons rapidement su où chercher : la grande majorité de nos erreurs de tokens de rafraîchissement étaient dues à des erreurs "session_not_found". Cela indiquait que Keycloak ne retrouvait pas les sessions de nos utilisateurs après un certain temps, bien que le temps écoulé jusqu'à la perte de la session semblait varier considérablement.

Création d'une configuration contrôlée

 

L'étape suivante consistait à reproduire le problème dans un environnement contrôlé. Nous avons trouvé que la meilleure façon de le faire était de créer une installation locale Keycloak+Infinispan à laquelle nous pouvions envoyer des requêtes en utilisant Postman. En utilisant cette installation locale, nous avons pu augmenter le niveau de journalisation à "TRACE" sans être submergés d'événements, puisqu'il n'y avait pas de trafic de production à prendre en compte.

Le niveau de débogage "TRACE" nous a permis de constater que les nouvelles sessions étaient initialement récupérées avec succès dans Infinispan après leur création. Cependant, avec le temps, Keycloak essayait quand même de récupérer une session du côté d'Infinispan. Sans raison identifiable, la session finissait par disparaitre.

Il s'est avéré que l'éviction et le rappel d'une session depuis le disque deux fois de suite a eu pour conséquence que la session n'a pas été trouvée au moment de la prochaine demande de token de rafraîchissement. Personne ne sait pourquoi cela se produit et nous n'en avons toujours pas trouvé la raison. La disparition de la session était la source des erreurs de token de rafraîchissement que nous observions dans notre environnement de production.

Qu'avons-nous appris ?

 

Le débogage de Keycloak est complexe, surtout s'il est exécuté avec un cluster Infinispan externalisé. Les métriques de la JVM et les logs fournis peuvent ne pas suffire.

Dans ce cas, une installation locale est une excellente méthode pour reproduire le problème que tu rencontres - même si cela nécessite de patcher Keycloak pour obtenir les données dont tu as besoin pour déboguer le problème par la suite. N'oublie pas non plus d'effectuer des tests de charge pour les changements que tu apportes à ton installation Keycloak. D'après notre expérience, cela t'évitera probablement quelques problèmes en production !

Nous remercions tout particulièrement Sam Smith et Zhandos Zhylkaidar pour leurs idées et leurs contributions à cet article.

Cet article t'a plu ? Tu trouveras bientôt sur le blog plus d'informations, d'idées et de conseils de la part des ingénieurs de Smallpdf.

Article traduit et adapté en français par Éloïse

silvan-jegen
Silvan Jegen
Staff Software Engineer @Smallpdf