Blog DevOps

Migrer une application vers GCP CloudRun : les avantages

Rédigé par Camil Sadiki | 14 avr. 2021 22:00:00

Des bonnes fonctionnalités...

CloudRun, qui est basé sur K-Native, est un framework conçu pour faire fonctionner des conteneurs sur un cluster Kubernetes géré, qui permet aux utilisateurs de déployer une application sans se soucier du framework ou des spécifications du déploiement.

Il n'est pas nécessaire de se plonger dans les fonctionnalités de Kubernetes difficiles à appréhender : équilibrage de charge, autoscaling, permissions, etc. Tout cela peut être facilement configuré en quelques clics sur la console GCP.

Sur le papier, cela semble assez génial, mais si vous choisissez de suivre la voie CloudRun, prenez garde à ses limites.

... avec quelques réserves

Pas facile de gérer les variables d'environnement

Pour spécifier des variables d'environnement à un déploiement CloudRun, il faut les lister une par une dans la ligne de commande, ce qui n'est pas, pour le moins, idéal :

Si vous deviez déployer votre application directement sur Kubernetes, vous auriez un manifeste de configmap commit sur git. Cela vous permettrait de déployer une révision de votre application avec une seule commande qui ne change pas en fonction du nombre de variables d'environnement que vous voulez utiliser dans votre déploiement.

L'accès au Secret Manager doit être configuré via Berglas

CloudRun n'offre pas d'intégration prête à l'emploi aux secrets stockés dans Secret Manager (par exemple, un service de GCP dont le but est de conserver des informations secrètes comme les mots de passe).

La solution pour qu'un conteneur puisse récupérer un mot de passe dans Secret Manager passe par Berglas et doit être configurée par le Dockerfile lui-même.

Voici un exemple de Berglas utilisé du point d'entrée du conteneur docker :

Berglas est un logiciel utilitaire conçu précisément à cet effet ; il fonctionne bien et est assez simple à utiliser. Cependant, j'aurais apprécié une façon moins hasardeuse de faire une intégration aussi simple entre les services de GCP.

Service réservé aux serveurs web

Une chose importante à garder à l'esprit quand on parle de CloudRun, c'est qu'il est entièrement conçu pour faire fonctionner des conteneurs de serveur web. Les conteneurs n'ont même pas de temps CPU lorsqu'aucune requête HTTP n'est traitée. C'est une excellente caractéristique, car elle permet de réduire la facture sans nuire aux performances : vous ne payez que pour le traitement des demandes et non pour avoir un conteneur inactif.

Néanmoins, vous devez vous assurer que le cycle de vie de votre application web est construit autour de la requête web, et qu'aucune opération louche ne doit se dérouler derrière le rideau. Ces opérations peuvent être des cronjobs ou des processus forkésdéclenchés après une requête web, par exemple, parce que ces processus n'auront pas de temps CPU donné pour exécuter leur tâche.

Et quelques lacunes majeures

D'une manière ou d'une autre, nous avons trouvé des solutions (parfois très farfelues) à tous les problèmes mentionnés ci-dessus.

Néanmoins, il y a un problème majeur que nous n'avons pas pu résoudre : le manque de liveness et readiness Probes.

Si vous ne connaissez pas les Kubernetes, vous ne reconnaîtrez peut-être pas le terme. Pourtant, une readiness probe n'est rien d'autre qu'un moniteur qui vérifiera si votre conteneur est prêt à faire face au trafic. La liveness probe est à peu près la même, mais seulement une fois que l'application a déjà servi le trafic. Habituellement, dans un serveur web, ce moniteur fait appel à une route HTTP : si le code de retour est compris entre 200 et 300, le système considère que le conteneur est prêt à servir.

Cloudrun, bien qu'il soit construit sur Kubernetes, ne permet pas aux utilisateurs de spécifier leurs liveness et readiness probes et choisit de décider si un service est prêt ou non à traiter les demandes d'une manière beaucoup plus simple : il sonde un port et si l'application s'y connecte, il est considéré comme prêt.

Même si elle n'est pas aussi utile que les liveness et readiness probes , cette solution devrait suffire dans la plupart des cas. C'est pourquoi nous n'avons pas considéré qu'il s'agissait d'un véritable problème.

Cependant, nous avons découvert par la suite que l'application gunicorn/flask que nous essayions de déployer dans CloudRun se connectait au port avant de pouvoir traiter les requêtes.

La conséquence de cela est que Cloudrun dirige le trafic vers un conteneur qui ne peut pas répondre, ce qui entraîne une augmentation du temps de traitement des requêtes et même des timeout.

Nous avons découvert ce problème en effectuant des tests de performance avec JMeter. Voici un graphique indiquant le nombre de hits par seconde que notre serveur web déployé par CloudRun a pu traiter.


Comme vous pouvez le voir, il y a de nombreuses baisses de performances évidentes, et nous avons déterminé que celles-ci se produisaient exclusivement sur les nouvelles créations de conteneurs. Aussi étrange que cela puisse paraître, plus de conteneurs signifie moins de performance.

Vous vous demandez peut-être comment nous avons résolu ce problème. Eh bien, nous ne l'avons pas fait. Du moins, pas avec CloudRun.

Nous avons décidé que les fonctionnalités intéressantes de ce nouveau service ne compensaient pas cet énorme problème de performances et nous avons migré l'application vers Kubernetes, un logiciel que nous connaissions mieux et que nous savions fonctionnel.

CloudRun est encore un service relativement nouveau et je suis sûr que GCP abordera à court terme nombre de ces limitations. Cela étant dit, je ne pense pas que le service soit prêt pour une utilisation en production ou du moins pas prêt pour la migration d'une application qui n'a pas été conçue spécifiquement pour fonctionner sur cette plateforme avec des modèles de conception serverless en place…