Je suis en train de mettre en place un autoscaling dans Kubernetes (hébergé dans Google Kubernetes Engine) pour mon application Java Spring. J'ai rencontré deux problèmes :
-
L'application Spring utilise beaucoup de CPU au démarrage (à peu près 250mCPU*, parfois même 500mCPU), ce qui casse vraiment l'autoscaling, car certaines instances de cette application, après plus ou moins 1 minute (démarrage du contexte Spring, etc.), n'utilisent que 50mCPU. Comme dans certains environnements cette application utilise une faible quantité de mCPU (quasiment toujours la nuit), j'aimerais définir cpu=200mCPU demandé max (= limite 80% cpu) (voire moins !). Ainsi, l'autoscaling aurait beaucoup plus de sens. Mais je ne peux pas vraiment le faire à cause de ce démarrage intensif de Spring, qui ne se terminera pas si je lui attribue trop peu de CPU.
-
Lorsque l'application commence à recevoir du trafic (lorsqu'un nouveau pod est créé en raison d'un événement d'autoscaling), son utilisation du CPU peut sauter à quelque chose comme 200% de l'utilisation standard, puis revenir à 100% - cela ne semble pas être dû au fait que trop de requêtes sont envoyées à ce nouveau pod, cela ressemble plutôt à un démarrage plus lent de la JVM et à une réception de trop de trafic au début. On dirait que la JVM aurait besoin d'un genre de préchauffage (pour ne pas pousser 1/n du trafic vers le nouveau pod soudainement, mais rediriger le trafic vers ce nouveau pod plus lentement). Grâce à ce comportement, l'autoscaling devient parfois fou - lorsqu'il a vraiment besoin d'un seul pod de plus, il peut en monter beaucoup, pour ensuite en descendre...
* dans GKE, 1000mCPU = 1 cœur
Sur les images téléchargées, nous pouvons voir les graphiques du CPU. Sur la première, nous pouvons constater que l'utilisation du CPU après le démarrage est bien inférieure à celle du début. Sur la deuxième, nous pouvons repérer les deux problèmes : une utilisation élevée du CPU au démarrage, puis une période d'attente (le délai initial de la sonde de préparation* n'est pas encore terminé), et ensuite un pic élevé au début de la réception du trafic.
* J'ai défini un délai initial de la sonde de préparation pour être plus long que le chargement du contexte.
La seule solution que j'ai trouvée sur internet est d'ajouter un conteneur à ce pod, qui ne fera rien d'autre que "sleep x", puis mourra. Et définir pour ce conteneur un mCPU demandé à une quantité qui sera utilisée au démarrage de l'application Spring (ensuite je devrais augmenter la limite de CPU pour ce conteneur d'application Spring, mais cela ne devrait pas nuire, car l'autoscaling devrait empêcher l'application Spring de priver les autres applications du nœud).
Toute aide serait grandement appréciée.