Déployons des canaris sur Google Kubernetes Engine
Tags: kubernetes, cd, cloud, devops
Published: 2024-02-13 12:58:46

Dans le cadre de mon emploi chez _Stack Labs_, j'interviens auprès d'une entreprise qui découvre la conteneurisation et qui veut développer son nouveau système sur _Google Cloud Platform_. L'un des sujets qui leur importe est la **montée de version** : comment procéder ?
Parmi leurs exigences, ils souhaitaient minimiser la durée d’interruption du service pendant la montée de version, ainsi que l'interrompre en cas de problème. 
Notre proposition : le **déploiement en canari**. Dans ce billet, je vous présente (très) brièvement de quoi il s'agit, ainsi que la démonstration que j'ai préparée avec un collègue pour montrer à nos clients comment ça fonctionne.

## Déploiement en canari ?

Le déploiement en canari consiste, pour un serveur Web, à déployer la nouvelle version du serveur (le « _Canari_ ») en parallèle de l'ancienne (la « _version primaire_ »), et de diriger une partie du trafic sur cette nouvelle version. Si le _Canari_ est jugé conforme aux attentes pour les requêtes traitées, alors la portion du trafic qui lui est assignée augmente progressivement, jusqu'à arriver à un seuil critique : dès lors, la _version primaire_ est reconfigurée pour délivrer la nouvelle version, et tout le trafic lui est affecté ; quant au _Canari_, les ressources qui lui étaient allouées (p. ex. conteneurs) sont libérées.

Ci-suivent quelques liens pour des explications plus approfondies (et illustrées !) :
* [Une explication par Danilo Sato, sur le site de Martin Fowler](https://martinfowler.com/bliki/CanaryRelease.html) ;
* [Un résumé par _Amazon Web Services_](https://wa.aws.amazon.com/wellarchitected/2020-07-02T19-33-23/wat.concept.canary-deployment.en.html) ;
* [Une explication par _CodeFresh_](https://codefresh.io/learn/software-deployment/what-are-canary-deployments/) ;
* [Une explication par Isac Souza d’_Encora_](https://www.encora.com/insights/zero-downtime-deployment-techniques-canary-deployments).

Après avoir lu ces pages Web, des questions apparaissent. En tout cas, je m'en suis posé plusieurs. Dans les sous-sections suivantes, je vous les présente, et vous explique mes réponses actuelles.

### Le _Canari_ est conforme... ?

Déporter le trafic vers le _Canari_ a pour objectif de vérifier s'il est « conforme » ; certes, mais conforme à quoi ? 

Cela doit être défini par l'équipe d'exploitation.

Un critère apparemment fréquent est le code de statut en réponse aux requêtes : par exemple, si un large pourcentage des réponses portent un code _HTTP 2xx_, alors le déploiement peut se poursuivre, et il doit s'interrompre si les codes _HTTP 5xx_ sont majoritaires. Un autre critère est la latence de réponse : si elle est trop élevée, alors le déploiement doit s'interrompre.
Ces critères sont intégrés nativement à des outils d'automatisation des déploiements en canari (p. ex. _Flagger_), mais cela peut ne pas suffire : des critères orientés métier peuvent être plus pertinents pour valider la conformité du _Canari_.
Enfin, notons que ce type de déploiement n'est pas nécessairement automatisé. En effet, les opérateurs peuvent à chaque étape sélectionner une population de testeurs pour interagir avec le _Canari_, et décider quand passer à la prochaine étape (p. ex. après avoir collecté les avis de la population de testeurs, ou mesuré diverses métriques avec des outils de supervision).

### Déploiement d'un logiciel... ou de tout le système ?

Les ressources trouvables en ligne ne sont pas claires quant à ce qu'englobe le déploiement en canari. En effet, si les auteurs parlent du déploiement d'un logiciel, leurs illustrations présentent bien le routage entre deux systèmes indépendants : l'un pour la _version primaire_, l'autre pour le _Canari_. Considérant les grandes difficultés techniques qui viennent avec la première option (p. ex. compatibilités entre modules, routage entre composants du système), il me semble plus raisonnable que ce soit la seconde option qui soit réellement mise en œuvre dans l'industrie.

Cependant, cela ne vient pas sans défi.

En effet, le déploiement en canari ne s'étend pas toujours à l'ensemble du système. Je prend l'exemple de l'une de mes expériences professionnelles passées : le système est déployé dans un environnement cloud qui compte un cluster _Kubernetes_ et un _SGBD_ déployé par un _PaaS_. Dans ce contexte, le déploiement en canari ne concernait que les conteneurs déployés dans _Kubernetes_ : le contenu de la base de données était utilisé concurremment par la _version primaire_ et le _Canari_. Par conséquent, il était important lorsque le _Canari_ modifiait le schéma de la base de données que les deux versions soient compatibles avec cette modification, au risque de perturber le fonctionnement du système lors du déploiement. Ce point d'attention est soulevé dans plusieurs des liens mentionnés plus haut, tel que l'article de Danilo Sato. C'est un exemple de contraintes sur le développement imposé par une pratique d'exploitation du système.

D'autres préoccupations peuvent également survenir selon la nature des composants du système. Par exemple, l'explication d'_Encora_ indique qu'il faut être vigilant si certains composants possèdent un état (_stateful_) : dès qu'un utilisateur a été dirigé sur l'une des deux versions, il faut qu'il y soit toujours dirigé au cours du déploiement ; et il peut être nécessaire de conserver l'ancienne version primaire quelque temps après la fin du déploiement le temps que les sessions soient fermées.

## Démonstration

Afin de présenter le fonctionnement d'un déploiement en canari à mon client, j'ai préparé une démonstration avec un collègue. Vous pouvez retrouver les fichiers de configuration et les instructions sur le [dépôt dans le groupe GitLab de Stack Labs](https://gitlab.com/stack-labs/oss/gke-canary-release).
L’image ci-dessous (_très_ légèrement adaptée d’[une image de la documentation de _Flagger_](https://docs.flagger.app/tutorials/nginx-progressive-delivery)) illustre la démonstration.

![Fonctionnement de Flagger dans Kubernetes avec NGINX](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1e3ai9ojksajng393pzv.png)

Nous disposons d'un serveur Web qui affiche une unique page avec un dessin de chameau. Nous le déployons dans _Google Kubernetes Engine_ (_GKE_). En amont du serveur Web, nous déployons toujours dans _GKE_ un _Ingress Controller NGINX_ : il effectue le routage du trafic vers l'instance _primaire_ ou _Canari_ du serveur Web lors d'un déploiement.

Nous voulons mettre à jour le serveur Web. En effet, alors que le fond de la page est beige (_version primaire_), nous le voulons à présent vert (_Canari_).

Pour parvenir à déployer la nouvelle version sans interruption du service, nous utilisons le logiciel [_Flagger_](https://docs.flagger.app/) qui automatise le processus de déploiement. Pour valider la conformité du _Canari_, nous nous concentrons sur les codes de statut _HTTP_, mais [_Flagger_ intègre d'autres critères nativement, et permet également de définir des critères personnalisés, grâce à des requêtes sur _Prometheus_](https://docs.flagger.app/usage/metrics).

Dès le déploiement lancé, la version avec le fond beige cohabite avec celle au fond vert, et une portion croissante du trafic est dirigée vers cette dernière, comme expliqué précédemment.

Les étapes de la démonstration sont détaillées sur le dépôt _Git_, je vous invite à les parcourir et à réaliser vous-même la démonstration !

## Conclusion

Dans ce billet, je vous ai présenté une stratégie de déploiement en continu des logiciels : le déploiement en canari ; et je vous ai proposé quelques instructions pour le pratiquer par vous-même.

Le déploiement en canari est une solution technique parmi d'autres pour déployer un système en continu. Je vous suggère ci-dessous trois lectures pour approfondir le sujet du déploiement en continu. D'abord, le [mémoire de Master de Nichil Strasser](https://pub.fh-campuswien.ac.at/obvfcwhsacc/content/titleinfo/8874850/full.pdf), qui évalue les outils de déploiement en canari sur le marché. Puis, deux recommandations qui ouvrent les perspectives sur d'autres techniques de déploiement : un [dépôt _Git_ d'exemples sur _Kubernetes_](https://github.com/ContainerSolutions/k8s-deployment-strategies), et un [article de Mahdi Konzali](https://blog.ouidou.fr/modes-de-d%C3%A9ploiement-continu-rolling-upgrade-blue-green-canary-7d9abebd0806) qui les vulgarise. Enfin, nous pouvons élargir l’exigence de faible temps d’interruption de service de notre client à la notion de haute disponibilité. Un [article de Endo et coll.](https://journalofcloudcomputing.springeropen.com/articles/10.1186/s13677-016-0066-8), publié en 2016, balaye plusieurs définitions de la haute disponibilité ainsi que l’état de l’art des moyens de sa mise en œuvre dans un contexte _cloud_.

---

Merci d’avoir lu mon article ! Je suis Antoine, ingénieur _cloud_ & doctorant chez _Stack Labs_. Si vous voulez en savoir plus sur [_Stack Labs_](http://stack-labs.com) ou rejoindre une équipe de passionnés de tech, n’hésitez pas à nous contacter [ici](https://www.welcometothejungle.com/fr/companies/stack-labs). 

---

Crédits à Julia Craice sur _Unsplash_ pour l’image de couverture.