SRE : les pratiques de run de demain - A Boulay - Duck Conf 2022

L’acronyme SRE, pour Site Reliability Engineering, est progressivement apparu dans notre vocabulaire il y a quelques années déjà, mais a pris une tout autre ampleur récemment.

Dans cette conférence, Adrien Boulay nous propose un tour d’horizon de ce qu’est le SRE, son origine et de ce qu’implique sa mise en œuvre.

SRE : découvrez les pratiques de RUN de demain

Mise en contexte

Lorsque l’on contribue à la production logicielle, il vient toujours un moment où ce logiciel - ainsi que ses évolutions futures - devra être mis à disposition de ses utilisateurs. C’est ce que l’on appelle communément la « mise en production ». Mais avant d’y arriver, ce logiciel passe souvent par 3 phases distinctes.

  1. La phase d’innovation, où l’on cherche à expérimenter, valider des hypothèses, collecter des retours. L’enjeu est d’abord d’ « aller vite » !

  2. Cette phase est suivie par un moment d’industrialisation, qui vise à compléter les hypothèses validées, abandonner celles qui se sont révélées fausses, et équiper le produit pour assurer sa pérennité (on regarde sa performance ou sa maintenabilité par exemple).

  3. S’ensuit une phase de production, où le logiciel finalisé (en tout cas, pour l’instant) est mis en production. Il rentre alors dans la phase de “run” avec les problématiques que celà implique (monitoring entre autres).

Lorsque l’on observe ces différentes phases, on y découvre deux besoins qui s’opposent :

  1. D’une part, il y aura des besoins d’évolution rapides et de changement que l’on retrouvera dans les phases d’innovation et d’industrialisation.
  2. De l’autre, on trouvera un besoin de stabilité dans la phase de production.

Traditionnellement, les phases 1 et 2 sont gérées par une équipe de développement (Dev) tandis que la phase 3 est confiée à une équipe d’exploitation, parfois appelée opération (Ops).

De cette opposition constatée (entre changement et stabilité), et parfois inconciliable, l’industrie va alors voir émerger une nouvelle approche visant à prendre en compte l’ensemble des besoins : L’approche DevOps.

Hélas…

Dans bien des contextes, DevOps se résume à la mise en œuvre d’un outil de CI (Continuous Integration).

La scission entre Dev et Ops n’est alors pas résolue. Ce que l’on appelle le “mur de l’incompréhension” (parfois aussi appelé le “mur de la production”) n’est pas brisé, car l’aspect organisationnel sous-jacent du DevOps est ignoré.

Le besoin d’équilibre entre changement et stabilité n’étant pas traité, on observe alors des mises en œuvre de DevOps sous la forme d’anti-patterns :

  • Un « ops » dans une équipe de dev, avec un silo implicite entre les développeurs et l’ops. Cela peut aller jusqu'à la création de backlog ou de rituels séparés entre les développeurs et les ops.
  • L’OPS “outillage” qui va permettre de faciliter la mise en production en mettant des outils en place (SonarQube, etc.). Notez ici que le silo est toujours présent à la sortie.

Pour aller plus loin sur les anti-patterns DevOps, voir https://web.devopstopologies.com/

Ce modèle reste simpliste, car les équipes sont dans un écosystème qui va impacter les flux de MEP de l’extérieur (par exemple, des équipes sécurités, besoin de validation par des membres extérieurs à l’équipe, etc.).

Que faire alors ?

Pour sortir d’un mode de fonctionnement où l’effort de synchronisation entre les parties prenantes est très important, une des réponses pour fluidifier la livraison du logiciel est de rendre les équipes autonomes.

Ces équipes :

  • Ont besoin des compétences transverses (ce qui constitue une difficulté de recrutement supplémentaire pour l’équipe RH).
  • Doivent être en mesure de faire évoluer leurs projets en autonomie
    Par exemple : « Dans bien des contextes, combien d’attente (en semaines) pour des ouvertures d’un port 22 ? »

Une équipe aura de grandes chances d’être autonome si les équipes réussissent à intégrer ces compétences transverses pour intervenir de bout en bout et qu’elles sont responsables des évolutions qu’elles apportent.

Rendre autonome dans l’usage des plateformes

« Si l’utilisateur est censé être autonome vis-à-vis d’un service web, pourquoi ne pas être en mesure de le faire entre le service WEB et la plateforme sur laquelle elle s’appuie ? … et on peut appliquer le même raisonnement plus bas »

De ce point de vue, on commence à considérer les plateformes comme des produits que l’on consomme, sur lesquels s’appliquent 3 enjeux :

  • Les plateformes doivent être fiables
  • Elles doivent être adaptées au(x) besoin(s).
  • Elles doivent être facile d’accès pour ceux qui vont les manipuler.

Cependant, une fois le service en production et ouvert à son public, de nouvelles problématiques apparaissent.

Quand la charge opérationnelle augmente… et que le SRE rentre en jeu.

Lorsque le service rendu par l’équipe devient disponible à son public, ce service va générer un nouveau type de tâches : la charge opérationnelle. Celle-ci prend diverses formes selon le contexte, mais ce sont souvent les tâches nécessaires pour assurer le fonctionnement du service.

Si elles ne représentent généralement que quelques actions ponctuelles lors de l’ouverture du service, avec le temps et le nombre d’usagers grandissant, le temps à consacrer pour ses actions va progressivement grandir jusqu’à empiéter sur les activités de développement et pénaliser l’équipe. Quand les tâches s’accumulent jusqu’à l’immobilisation, on appelle cela l’effet marais.

Ce qu’on l’on appelle SRE (Site Reliability Engineering), c’est l’ensemble des pratiques et méthodes que Google a mis en place chez eux vers 2005 pour résoudre cette problématique. Ces pratiques visent à renforcer la confiance dans le produit en se positionnant d’un point de vue utilisateur.

Précision importante

«  SRE n’est pas DevOps […], ce sont deux philosophies qui se synergisent très bien, mais qui ne sont pas identiques. Là où le DevOps va être focalisé sur les aspects du delivery, le SRE va prendre un point de vue run et produit face aux utilisateurs ».

L’activité d’une équipe SRE va essentiellement se répartir entre deux types de charges :

  1. La charge opérationnelle qui pourra occuper au maximum 50% du temps de l’équipe. Dans cette charge, on trouvera évidemment la gestion d’incidents de production, mais on y ajoutera également des actions comme la rédaction de post-mortem (pour capitaliser sur les incidents et les modes de résolution).
  2. Le temps d’ingénierie (~50%) qui sera quant à lui consacré à des tâches d'ingénierie (d’où le E dans l'acronyme SRE) visant à réduire la charge opérationnelle.
    Ce travail prend diverses formes, mais il couvre autant les tâches actuelles (automatisation de tâches existantes par exemple) que l’anticipation de besoins futurs.

Interactions et émergence d’une équipe SRE

Dans un contexte de développement logiciel, il est probable que l’organisation ne ressente pas initialement le besoin d’intégrer une équipe SRE.

Dans un premier temps, l’équipe de développement se concentrera sur la phase de build de l’application jusqu’au moment où celle-ci sera suffisamment développée pour nécessiter le besoin d’une expertise pour les problématiques associées à la phase de run. L’équipe intégrera alors des experts SRE sous une forme que l’on peut comparer à une “stream aligned team” (telle que décrite dans Team Topology”). L’expertise SRE vient alors en renfort pour conseiller et accompagner les équipes pour rendre l’application “opérable” en production.

Dans un deuxième temps, l’équipe SRE pourra progressivement prendre en charge le suivi de l’application en production - ce qu’on appelle généralement le run - et assurera la gestion des tâches opérationnelles.

Cependant, si l’application doit évoluer ou s’avère trop difficile à opérer dans son état actuel, l’équipe de développement en reprendra la responsabilité et sera en charge de rendre cette application opérable en production.

À ce stade, il est important de rappeler que tout cela n’est possible que si de l’observabilité a été mise en place (voir la slide ci-dessous). Une fois outillée, l’équipe est alors en mesure de se saisir des métriques, de leur donner une signification métier afin de basculer vers du monitoring.

« Le SRE va aller encore plus loin que ça, il s’en sert pour conduire le changement »

Pour poursuivre la dynamique visant à réconcilier les aspects antagonistes du build et du run, Google met en place une gestion du changement qui va se baser sur des objectifs métiers.

En définissant ces objectifs sous la forme de Service Level Objective (SLO), il est alors possible de définir avec précision - métriques à l’appui - le contrat qui permettra de considérer que le service est fonctionnel du point de vue de l’utilisateur final.

De ce SLO, on pourra alors calculer un error budget permettant de vérifier que les évolutions apportées n’impactent pas (ou peu) l’expérience utilisateur.

Ces SLOs, associés à cette mécanique d’error budget, constitue un contrat qui rassemble toutes les parties (produit, stakeholder, développement, opération) autour d’un accord qui doit être coconstruit.

En suivant ce budget, on est alors capable de piloter les envies d’évolution au regard de l’expérience utilisateur. Si le budget a été totalement épuisé par des incidents ou un grand volume d’évolutions ayant eu un impact sur les utilisateurs, le contrat permettra de bloquer les évolutions jusqu’à ce que le budget se soit reconstitué et/ou qu’une solution ait été trouvée pour apporter des évolutions sans impact.

Pour approfondir le sujet des SLO, voir “SLO : la puissance insoupçonnée des métriques“ https://blog.octo.com/slo-la-puissance-insoupconnee-des-metriques/

« Si un incident arrive, alors le coût de remédiation va piocher dans le budget »

SRE et les tests

Testing shows the presence, not the absence of bugs

Dijkstra (1960)

Afin de limiter la consommation de l’error budget, il devient important de raccourcir la boucle de feedback pour s’assurer au plus tôt du bon fonctionnement de l’application avant même de le mettre en production.

Une démarche SRE va s’appuyer sur différentes typologies de tests automatisés qui viendront soulager les équipes d’une partie du travail de validation.

On s’appuiera d’abord sur des tests automatisés au sens classique du développement logiciel (tests unitaires, d'intégration, etc.) que l’on pourra déployer au cours de phases de développement, l’enjeu étant toujours de réduire la boucle de feedback en cas de régression du système.

SRE ajoute une couche de test supplémentaire pour évaluer le bon fonctionnement de l’environnement de production. Par exemple, on y trouvera des tests système, des tests de fonctionnement (type probe), la mesure du drift (écart entre les environnements de production et de développement), ainsi que des tests pour sécuriser l’outillage interne des équipes.

Lorsque l’on souhaite limiter au maximum l’impact de modification sur les utilisateurs finaux, la mesure du drift gagne en importance puisqu’elle permet d’assurer que les environnements pré-production soient aussi proches que possible du fonctionnement de la production (modulo certaines contraintes réglementaires comme le RGPD par exemple).

Toujours plus loin dans une démarche de fiabilisation, les SRE vont déclencher volontairement des défaillances afin de mettre le système à l’épreuve. Cette démarche est aujourd’hui connue sous le nom de Chaos Engineering (il commence d’ailleurs à émerger des outils open-source qui permettent de faciliter ce genre d’exploration).

Les SRE vont proactivement tester les pannes du système selon une méthode stricte :

  • On commence par identifier un point d’échec du système et on définit une procédure de remédiation en conséquence pour minimiser au maximum le temps d’une panne.

  • On lance l’expérimentation en déclenchant la condition d'échec. De vraies alertes sont déclenchées.

  • On restaure le système et on dresse un post-mortem pour documenter les apprentissages de la pratique. Ceux-ci seront ensuite utilisés pour améliorer le système et l’organisation (outillage, procédure, formation et même le monitoring).

Rendre le système autonome

On pourrait penser qu’une fois que le système est testé automatiquement, qu’il est surveillé au travers de sondes et d’outils de monitoring, que les seuils d’alerte et que l’error budget ont été définis, il n’est plus possible d’aller plus loin.

Et pourtant, c’est toujours possible, car l’étape suivante sera de rendre le système autonome !

Évidemment, on n’imagine pas rendre l’ensemble du système autonome d’un coup. C’est l’aboutissement d’un processus qui passe par 5 étapes :

Imaginons que notre système ait besoin d’une base de données qui rencontre un problème A, les 5 étapes d’automatisation d’une tâche serait alors :

  1. La correction à l’incident est apportée manuellement sur l’infrastructure.

  2. Au bout d’un certain nombre de répétitions de cette action manuelle, un script sera écrit pour régler A plus efficacement et pour éviter les potentielles erreurs manuelles.

  3. À force de répétitions du problème A, le script deviendra générique, car il pourra s’adapter aux systèmes similaires.

C’est souvent à cette étape 3 que les équipes s’arrêtent.
Changeons maintenant de prisme et passons côté développeur d’une solution :

  1. Le script pourra ensuite être mis à disposition de toutes les équipes (“sur étagère”). L’équipe ayant édité le script sera en charge de le maintenir et d’y apporter des évolutions.
  2. Le système déclenche automatiquement le script en fonction de déclencheurs spécifiques, le script faisant désormais partie intégrante de solution.

À l’issue de ce processus et associé au monitoring, on peut alors décider de lancer le script sans intervention d’un opérateur si l’on est capable d’identifier les bonnes causes.

Même si cela peut paraître complexe à se représenter dans nos systèmes, ces pratiques sont aujourd’hui déjà utilisées dans nos SI à travers des solutions comme FlyWay (migration automatique de base de données) ou des opérateurs (Kubernetes ou non) autour de solutions comme Kafka ou Postgresql.

Conclusion et takeaways

Dans ce talk, Adrien Boulay nous propose de découvrir comment les équipes de Google et leurs ingénieurs SRE adaptent leurs façons de faire pour être en mesure d’opérer leur production tout en restant dans ce qu’ils appellent le mode sublinéaire, un mode où la charge opérationnelle (que l’on appelle aussi toil) ne grandit pas à la même vitesse que le nombre d’utilisateurs et évite à l’équipe de se retrouver débordé_._

Au cours de cette conférence, quatre éléments au centre d’une démarche SRE ont été abordé :

  1. Sans observabilité, pas de pilotage de la production, car le système devient opaque pour celles et ceux qui doivent s’en occuper. Investir dans l'observabilité des systèmes est un vecteur d’amélioration central car il permet de définir des objectifs sous la forme de Service Level Objectives (SLO) et ainsi constituer un Error Budget.

  2. La démarche SRE repose sur des pratiques d'ingénierie logiciel appliquées à l’ensemble du système, notamment celle de s’appuyer sur des tests automatisés (jusqu’en production) et des outils afin de réduire autant que possible la boucle de feedback.

  3. Une fois les premiers points suffisamment développés, il devient possible d’automatiser le système pour qu’il soit capable de réagir dans certaines situations.

  4. Enfin, l’autonomisation des équipes :
    Afin d’opérer efficacement un système en production, il convient d’aider les équipes à être autonomes sur leur périmètre et notamment qu’elles soient en mesure de maîtriser l’ensemble de la chaîne, de la phase de développement au suivi de la production.