Bonnes pratiques pour l'exécution d'applications Kubernetes à coût maîtrisé sur GKE.

Ce document présente les fonctionnalités, les options et les bonnes pratiques pour exécuter des applications à coût maîtrisé sur Google Kubernetes Engine (GKE) dans le but de tirer profit de l'élasticité fournie par Google Cloud. Dans ce document, nous partons du principe que vous maîtrisez Kubernetes, Google Cloud, GKE et l'autoscaling.

Présentation

Avec l'adoption généralisée de Kubernetes, un nombre croissant d'entreprises et de fournisseurs de solutions PaaS (Platform as a Service) et SaaS (Software as a Service) utilisent des clusters Kubernetes mutualisés pour leurs charges de travail. Un même cluster peut donc exécuter des applications qui appartiennent à des équipes, des services, des clients ou des environnements différents. L'architecture mutualisée fournie par Kubernetes permet aux entreprises de gérer un nombre limité de grands clusters, plutôt que de nombreux clusters plus petits, tout en bénéficiant d'avantages tels qu'une utilisation judicieuse des ressources, un contrôle de gestion simplifié et une fragmentation réduite.

Au fil du temps, certaines de ces entreprises qui optent pour des clusters Kubernetes soumis à une croissance rapide, constatent une augmentation disproportionnée des coûts associés. En effet, les entreprises traditionnelles qui adoptent des solutions cloud comme Kubernetes ne disposent ni de développeurs ni d'opérateurs spécialisés dans le cloud. Cette inaptitude au cloud entraîne une instabilité des applications lors de l'autoscaling (par exemple, la fluctuation du trafic à une heure normale de la journée), d'une utilisation intensive ou de pics de trafic (comme dans le cas des publicités télévisées ou des événements de grande envergure, tels que le Black Friday et le Cyber Monday). Pour tenter de résoudre ce problème, ces entreprises ont tendance à surprovisionner leurs clusters comme elles le faisaient auparavant dans un environnement non élastique. Le surprovisionnement se traduit par une allocation de processeurs et de mémoire considérablement plus élevée que ce que les applications utilisent la plupart du temps.

Ce document présente les bonnes pratiques pour exécuter des charges de travail Kubernetes à coût maîtrisé sur GKE. Le schéma suivant illustre cette approche.

Approche d'optimisation des applications Kubernetes en termes de coûts

La création d'applications à coût maîtrisé suppose d'instaurer au sein des équipes une culture de l'économie. Outre le fait de placer la question des coûts au début du processus de développement, cette approche vous oblige à mieux comprendre l'environnement dans lequel fonctionnent vos applications, en l'occurrence l'environnement GKE.

Afin de réduire les coûts et d'assurer la stabilité de vos applications, vous devez paramétrer ou ajuster correctement certaines fonctionnalités et configurations (telles que l'autoscaling, les types de machines et la sélection des régions). Autre point important : votre type de charge de travail. En fonction de celui-ci et des besoins de votre application, vous devez appliquer différentes configurations afin de réduire davantage vos coûts. Enfin, vous devez surveiller vos dépenses et mettre en place des garde-fous, afin de pouvoir appliquer ces bonnes pratiques dès le début de votre cycle de développement.

Le tableau suivant résume les défis que GKE vous permet de relever. Nous vous invitons à lire l'ensemble de ce document, même si le tableau ci-dessous donne un aperçu des thèmes abordés.

Défi Mesures à engager
Je souhaite réaliser facilement des économies sur GKE. Sélectionnez la région appropriée, inscrivez-vous aux remises sur engagement d'utilisation et utilisez des types de machines E2.
Je souhaite comprendre les coûts liés à GKE. Observez vos clusters GKE, suivez les recommandations et activez la mesure de l'utilisation de GKE
Je veux tirer pleinement parti de l'élasticité de GKE pour mes charges de travail actuelles. Consultez les sections Autoscaler horizontal de pods, Autoscaler de cluster, et découvrez les bonnes pratiques concernant l'autoscaler et le surprovisionnement.
Je souhaite utiliser les types de machines les plus performants. Choisissez le type de machine adapté à votre charge de travail.
De nombreux nœuds de mon cluster sont inactifs. Consultez les bonnes pratiques concernant l'autoscaler de cluster.
Je souhaite réaliser des économies sur mes tâches par lot. Consultez les bonnes pratiques concernant les charges de travail par lot.
Je souhaite réaliser des économies sur mes charges de travail de diffusion. Consultez les bonnes pratiques concernant les charges de travail de diffusion.
J'ignore comment dimensionner mes demandes de ressources de pods. Utilisez l'autoscaler vertical de pods en observant les bonnes pratiques en termes de combinaison des autoscalers horizontal et vertical de pods.
Mes applications sont instables durant les activités d'autoscaling et de maintenance. Préparez vos applications cloud à l'utilisation de Kubernetes, puis découvrez le fonctionnement du module complémentaire Metrics-server et les moyens de surveiller celui-ci.
Comment faire pour que mes développeurs tiennent compte de l'utilisation des ressources par leurs applications ? Instaurez une culture de l'économie, envisagez d'utiliser GKE Enterprise Policy Controller, concevez votre pipeline CI/CD de façon à réduire les coûts pratiques et utilisez les quotas de ressources Kubernetes.
Quelles sont les autres mesures à envisager pour réduire davantage les coûts liés à mes écosystèmes ? Analysez les clusters de développement de petite taille, étudiez vos stratégies de journalisation et de surveillance, et examinez le trafic de sortie interrégional dans les clusters régionaux et multizones.

Options et fonctionnalités d'optimisation des coûts de GKE

Les applications Kubernetes à coût maîtrisé s'appuient massivement sur l'autoscaling GKE. Pour équilibrer les coûts, la fiabilité et le scaling des performances sur GKE, vous devez comprendre comment fonctionne l'autoscaling et connaître les options à votre disposition. Cette section aborde l'autoscaling GKE et d'autres configurations utiles à coût maîtrisé concernant les charges de travail de diffusion et de traitement par lot.

Ajuster l'autoscaling GKE

L'autoscaling est la stratégie utilisée par GKE pour permettre aux clients de Google Cloud de ne payer que le strict nécessaire, en réduisant au minimum le temps d'activité de l'infrastructure. En d'autres termes, l'autoscaling permet de réduire les coûts 1) en faisant démarrer les charges de travail et leur infrastructure sous-jacente avant l'augmentation de la demande, et 2) en les arrêtant lorsque la demande diminue.

Le schéma suivant illustre ce concept. Dans Kubernetes, vos charges de travail sont des applications en conteneurs qui s'exécutent dans des pods. L'infrastructure sous-jacente, composée d'un ensemble de nœuds, doit disposer d'une capacité de calcul suffisante pour exécuter les charges de travail.

L'autoscaling permet de réduire les coûts 1) en faisant démarrer les charges de travail et leur infrastructure sous-jacente avant l'augmentation de la demande, et 2) en les arrêtant lorsque la demande diminue.

Comme l'illustre le schéma suivant, cet environnement présente quatre dimensions d'évolutivité. La charge de travail et l'infrastructure peuvent évoluer horizontalement, en ajoutant et en supprimant des pods ou des nœuds. Elles peuvent également évoluer verticalement, en augmentant et en diminuant la taille des pods ou des nœuds.

Les quatre dimensions d'évolutivité d'un environnement à coût maîtrisé.

GKE gère ces scénarios d'autoscaling à l'aide de fonctionnalités telles que :

Le schéma suivant illustre ces scénarios.

Mise en œuvre de scénarios impliquant les autoscalers horizontal et vertical de pods, l'autoscaler de cluster et le provisionnement automatique de nœuds.

Le reste de cette section décrit plus en détail ces fonctionnalités d'autoscaling de GKE et aborde les autres configurations utiles et à coût maîtrisé concernant les charges de travail de diffusion et de traitement par lot.

Autoscaler horizontal de pods

L'autoscaler horizontal de pods est conçu pour le scaling des applications qui s'exécutent dans des pods, qui va dépendre des métriques exprimant la charge. Vous pouvez configurer l'utilisation du processeur ou d'autres métriques personnalisées (par exemple, le nombre de requêtes par seconde). En résumé, l'autoscaler horizontal de pods ajoute et supprime des instances dupliquées de pods et convient mieux aux nœuds de calcul sans état, qui sont capables de démarrer rapidement pour réagir aux pics d'utilisation et de s'arrêter progressivement pour éviter l'instabilité des charges de travail.

Le seuil d'utilisation cible de l'autoscaler horizontal de pods vous permet de personnaliser le moment auquel le scaling s'active automatiquement.

Comme l'illustre l'image précédente, l'autoscaler horizontal de pods nécessite un seuil d'utilisation cible, exprimé en pourcentage, qui permet de personnaliser le moment auquel le scaling s'active automatiquement. Dans cet exemple, le seuil d'utilisation cible du processeur est de 70 %. Votre charge de travail dispose donc d'un tampon de ressources processeur de 30 % pour le traitement des requêtes, tandis que de nouvelles instances dupliquées démarrent. Un tampon de taille réduite évite les scalings à la hausse trop précoces, mais peut surcharger votre application pendant les pics d'activité. Cependant, un tampon plus étendu est synonyme de gaspillage de ressources, et donc d'augmentation des coûts. Le seuil cible idéal n'existe pas : il dépend de votre application. Vous devez donc dimensionner le tampon de façon à pouvoir traiter les requêtes durant deux ou trois minutes lors d'un pic d'utilisation. Même si vous vous assurez que votre application peut démarrer en quelques secondes, ce délai supplémentaire est nécessaire lorsque l'autoscaler de cluster ajoute des nœuds à votre cluster ou lorsque des pods sont limités en raison d'un manque de ressources.

Voici quelques bonnes pratiques d'activation de l'autoscaler horizontal de pods dans votre application :

Pour en savoir plus, consultez la page Configurer un autoscaler horizontal de pods.

Autoscaler vertical de pods

Contrairement à l'autoscaler horizontal de pods, qui ajoute et supprime des instances dupliquées de pods pour réagir rapidement aux pics d'utilisation, l'autoscaler vertical de pods surveille les pods en continu et détermine de manière progressive la quantité de ressources processeur et mémoire nécessaires aux pods. Sur le plan de la stabilité et de la rentabilité, il est important de définir des ressources adaptées. Si les ressources de vos pods sont insuffisantes, votre application peut être limitée ou échouer en raison d'erreurs de mémoire saturée. Si vos ressources sont trop importantes, vous encourez un gaspillage, et donc des factures plus élevées. L'autoscaler vertical de pods est destiné aux charges de travail sans état et avec état qui ne sont pas prises en charges par l'autoscaler horizontal de pods, ou aux situations où vous ne connaissez pas les demandes de ressources des pods.

L'autoscaler vertical de pods détecte lorsqu'un pod s'exécute constamment à la limite de ses capacités et recrée celui-ci, en le dotant de ressources plus importantes.

Comme l'illustre l'image précédente, l'autoscaler vertical de pods détecte lorsque le pod s'exécute constamment à la limite de ses capacités et recrée celui-ci, en le dotant de ressources plus importantes. Il en va de même lorsque le pod est systématiquement sous-exploité : un scaling à la baisse est déclenché.

L'autoscaler vertical de pods peut être associé à trois modes de fonctionnement :

  • Désactivé : dans ce mode, également appelé mode recommandation, l'autoscaler vertical de pods n'applique aucune modification à votre pod. Les recommandations sont calculées et peuvent être inspectées dans l'objet autoscaler vertical de pods.
  • Initial : l'autoscaler vertical de pods n'attribue des demandes de ressources que lors de la création du pod et ne les modifie jamais ultérieurement.
  • Auto : l'autoscaler vertical de pods met à jour les demandes de ressources mémoire et processeur pendant toute la durée de vie d'un pod. Cela signifie qu'un pod est supprimé, les ressources mémoire et processeur sont ajustées, puis un nouveau pod démarre.

Si vous prévoyez d'utiliser l'autoscaler vertical de pods, il est recommandé de commencer par le mode Désactivé afin d'exploiter les recommandations de l'autoscaler vertical de pods. Assurez-vous que celui-ci fonctionne pendant au moins 24 heures, et idéalement une semaine ou plus, avant d'exploiter ses recommandations. Ensuite, lorsque vous avez pris vos repères, passez en mode Initial ou Auto.

Suivez les bonnes pratiques d'activation de l'autoscaler vertical de pods en mode Initial ou Auto dans votre application :

Si vous envisagez d'utiliser le mode Auto, suivez les pratiques suivantes :

  • Assurez-vous que votre application peut être redémarrée tout en recevant du trafic.
  • Ajoutez un budget d'interruption de pod pour contrôler le nombre de pods pouvant être retirés simultanément.

Pour en savoir plus, consultez la page Configurer l'autoscaling vertical de pods.

Combiner les autoscalers horizontal et vertical de pods

La recommandation officielle conseille de ne pas combiner les autoscalers vertical et horizontal de pods sur les ressources processeur ou mémoire. Vous pouvez toutefois les mélanger en toute sécurité lorsque vous utilisez le mode recommandation dans l'autoscaler vertical de pods, ou avec des métriques personnalisées dans l'autoscaler horizontal de pods (par exemple, un nombre de requêtes par seconde). Lorsque vous combinez les autoscalers vertical et horizontal de pods, assurez-vous que vos déploiements reçoivent suffisamment de trafic, c'est-à-dire qu'ils s'exécutent toujours avec un nombre d'instances dupliquées supérieur au nombre minimal de l'autoscaler horizontal de pods. Cela permet à l'autoscaler vertical de pods de connaître les besoins en ressources de votre pod.

Pour en savoir plus sur les limitations de l'autoscaler vertical de pods, consultez la section Limites de l'autoscaling vertical de pods.

Autoscaler de cluster

L'autoscaler de cluster redimensionne automatiquement l'infrastructure informatique sous-jacente. L'autoscaler de cluster fournit des nœuds aux pods qui n'ont pas d'emplacement d'exécution dans le cluster et supprime les nœuds sous-utilisés. L'autoscaler de cluster cible une optimisation basée sur le coût de l'infrastructure. En d'autres termes, si le cluster compte au moins deux types de nœuds, l'autoscaler de cluster choisit celui qui sera le moins coûteux, tout en étant approprié à la demande concernée.

Contrairement aux autoscalers horizontal et vertical de pods, l'autoscaler de cluster ne dépend pas des métriques concernant les charges de travail. Il se base sur la simulation de planification et les demandes de pods déclarées. Il est recommandé d'activer l'autoscaler de cluster chaque fois que vous utilisez les autoscalers horizontal ou vertical de pods. Si vos autoscalers de pods déterminent que vous avez besoin de plus de capacité, cette pratique garantit le développement en conséquence de votre infrastructure sous-jacente.

L'autoscaler de cluster ajoute et supprime automatiquement de la capacité de calcul pour gérer les pics de trafic.

Comme l'illustrent ces schémas, l'autoscaler de cluster ajoute et supprime automatiquement de la capacité de calcul pour gérer les pics de trafic, tout en vous faisant réaliser des économies lorsque vos clients sont inactifs. Il est recommandé de définir un budget d'interruption de pod pour toutes vos applications. Cela est particulièrement important lors de la phase de scaling à la baisse de l'autoscaler de cluster, pendant laquelle le budget d'interruption de pod contrôle le nombre d'instances dupliquées pouvant être supprimées simultanément.

Certains pods ne peuvent pas être redémarrés par un autoscaler lorsqu'ils provoquent une interruption temporaire. Le nœud sur lequel ils s'exécutent ne peut donc pas être supprimé. Par exemple, les pods système (tels que metrics-server et kube-dns) et les pods utilisant le stockage local ne sont pas redémarrés. Vous pouvez toutefois modifier ce comportement en définissant des budgets d'interruption de pod pour ces pods système, et en définissant l'annotation "cluster-autoscaler.kubernetes.io/safe-to-evict": "true" pour les pods utilisant le stockage local et pouvant être redémarrés en toute sécurité par l'autoscaler. Pensez en outre à exécuter les pods de longue durée qui ne peuvent pas être redémarrés sur un pool de nœuds indépendant, afin qu'ils ne bloquent pas le scaling à la baisse des autres nœuds. Enfin, découvrez comment analyser les événements de l'autoscaler de cluster dans les journaux pour comprendre pourquoi une activité de scaling spécifique ne s'est pas déroulée comme prévu.

Si vos charges de travail sont résilientes aux nœuds qui redémarrent par inadvertance et aux pertes de capacité, vous pouvez réaliser des économies supplémentaires en créant un cluster ou un pool de nœuds dotés de machines virtuelles préemptives. Pour que l'autoscaler de cluster fonctionne comme prévu, les demandes de ressources du pod doivent être suffisamment volumineuses pour que celui-ci fonctionne normalement. Si les demandes de ressources sont trop modestes, les nœuds risquent de manquer de ressources et vos pods risquent de planter ou de rencontrer des problèmes lors de l'exécution.

Voici un récapitulatif des bonnes pratiques concernant l'activation de l'autoscaler de cluster dans votre cluster :

  • Utilisez les autoscalers horizontal et vertical pour procéder à l'autoscaling de vos charges de travail.
  • Assurez-vous d'observer les bonnes pratiques concernant l'autoscaler de pod choisi.
  • Dimensionnez correctement votre application en définissant des demandes et des limites de ressources adaptées, ou utilisez l'autoscaler vertical de pods.
  • Définissez un budget d'interruption de pod pour vos applications.
  • Définissez le budget d'interruption des pods système susceptibles de bloquer votre scaling à la baisse (par exemple, kube-dns). Pour éviter toute interruption temporaire dans votre cluster, ne définissez pas de budget d'interruption pour les pods système dotés d'une seule instance dupliquée (par exemple, metrics-server).
  • Exécutez des pods de courte durée et des pods pouvant être redémarrés dans des pools de nœuds distincts, afin que les pods de longue durée ne bloquent pas le scaling à la baisse.
  • Évitez le surprovisionnement en configurant des nœuds inactifs dans votre cluster. Pour cela, vous devez connaître votre capacité minimale (en période nocturne pour la plupart des entreprises), et définir le nombre minimal de nœuds de vos pools de nœuds pour gérer cette capacité.
  • Si vous avez besoin de plus de capacité pour traiter les requêtes durant les pics d'utilisation, utilisez des pods de pause, présentés à la rubrique Autoscaler et surprovisionnement.

Pour en savoir plus, consultez la page Procéder à l'autoscaling d'un cluster.

Provisionnement automatique des nœuds

Le provisionnement automatique de nœuds est un mécanisme de l'autoscaler de cluster qui ajoute automatiquement de nouveaux pools de nœuds et gère leur taille pour le compte de l'utilisateur. Sans provisionnement automatique de nœuds, GKE n'envisage de démarrer de nouveaux nœuds qu'à partir de l'ensemble des pools de nœuds créés par l'utilisateur. Le provisionnement automatique de nœuds permet à GKE de créer et de supprimer automatiquement des pools de nœuds.

Le provisionnement automatique de nœuds a tendance à réduire le gaspillage de ressources en créant dynamiquement des pools de nœuds, qui vont être idéalement adaptés aux charges de travail planifiées. Toutefois, la latence de l'autoscaling peut être légèrement plus importante lors de la création de pools de nœuds. Si vos charges de travail sont résilientes aux nœuds qui redémarrent par inadvertance et aux pertes de capacité, vous pouvez réduire davantage les coûts en configurant la tolérance d'une VM préemptive dans votre pod.

Voici les bonnes pratiques à suivre pour activer le provisionnement automatique des nœuds :

  • Suivez toutes les bonnes pratiques concernant l'autoscaler de cluster.
  • Définissez les tailles minimale et maximale des ressources pour éviter que le provisionnement automatique de nœuds n'effectue des modifications importantes dans votre cluster lorsque votre application ne reçoit pas de trafic.
  • Si vous utilisez l'autoscaler horizontal de pods pour les charges de travail de diffusion, pensez à conserver un tampon d'utilisation cible légèrement plus important, car le provisionnement automatique de nœuds peut accroître la latence de l'autoscaling dans certains cas.

Pour en savoir plus, consultez la page Utiliser le provisionnement automatique des nœuds et la section Fonctions non compatibles.

Autoscaler et surprovisionnement

Afin de contrôler vos coûts, nous vous recommandons vivement d'activer l'autoscaler conformément aux sections précédentes. Il n'existe aucune configuration qui réponde à tous les scénarios possibles. Vous devez donc ajuster les paramètres en fonction de votre charge de travail pour vous assurer que les autoscalers répondent correctement à l'augmentation du trafic.

Toutefois, comme indiqué dans la section Autoscaler horizontal de pods, le scaling à la hausse peut prendre un certain temps en raison du provisionnement de l'infrastructure. Pour visualiser cette différence de délai et les scénarios potentiels de scaling à la hausse, examinez le schéma suivant.

Illustration de la différence de délai et des scénarios potentiels de scaling à la hausse.

Lorsque votre cluster dispose de suffisamment d'espace pour déployer de nouveaux pods, l'un des scénarios de scaling à la hausse de la charge de travail se déclenche. Ainsi, si un nœud existant n'a jamais déployé votre application, il doit télécharger ses images de conteneur avant de démarrer le pod (scénario 1). Toutefois, si le même nœud doit démarrer une nouvelle instance dupliquée de pod de votre application, le délai total de scaling à la hausse diminue, car aucun téléchargement d'image n'est requis (scénario 2).

Lorsque votre cluster ne dispose pas de l'espace suffisant pour déployer de nouveaux pods, l'un des scénarios de scaling à la hausse de l'infrastructure et de la charge de travail se déclenche. Cela signifie que l'autoscaler de cluster doit provisionner de nouveaux nœuds et démarrer le logiciel requis avant de passer à votre application (scénario 1). Si vous utilisez le provisionnement automatique de nœuds, de nouveaux pools de nœuds peuvent être nécessaires selon la charge de travail planifiée. Dans ce cas, le délai total de scaling à la hausse augmente, car l'autoscaler de cluster doit provisionner des nœuds et des pools de nœuds (scénario 2).

Pour les scénarios dans lesquels une nouvelle infrastructure est requise, ne limitez pas trop votre cluster : surprovisionnez-le, mais seulement de façon à disposer du tampon nécessaire à la gestion des pics de requêtes attendus lors du scaling à la hausse.

Il existe deux stratégies principales concernant ce type de surprovisionnement :

  • Ajuster le seuil d'utilisation cible de l'autoscaler horizontal de pods. L'équation suivante est un moyen simple et sécurisé de déterminer un seuil d'utilisation cible adapté pour le processeur :

    (1 - buff)/(1 + perc)

    • buff est un tampon de sécurité que vous pouvez définir pour éviter d'atteindre une utilisation de 100 % du processeur. Cette variable est utile, car le fait d'atteindre une utilisation de 100 % du processeur signifie que la latence de traitement des requêtes est beaucoup plus élevée que d'habitude.
    • perc est le pourcentage de croissance de trafic attendu dans deux ou trois minutes.

    Par exemple, si vous prévoyez une croissance de 30 % de vos requêtes, pour éviter d'atteindre une utilisation de 100 % du processeur en définissant un tampon de sécurité de 10 %, votre formule doit ressembler à ce qui suit :

    (1 - 0,1)/(1 + 0,3) = 0,69

  • Configurez des pods de pause. Il n'existe aucun moyen de configurer l'autoscaler de cluster pour faire démarrer des nœuds à l'avance. Au lieu de cela, vous pouvez définir un seuil d'utilisation cible de l'autoscaler horizontal de pods, afin de disposer d'un tampon permettant de gérer les pics de charge. Toutefois, si vous prévoyez une utilisation particulièrement intensive, la définition d'un faible seuil d'utilisation cible de l'autoscaler horizontal de pods peut s'avérer insuffisante ou devenir trop coûteuse.

    Une solution à ce problème consiste à utiliser des pods de pause. Les pods de pause sont des déploiements de faible priorité qui n'ont aucune utilité à proprement parler, si ce n'est réserver de l'espace dans votre cluster. Chaque fois qu'un pod à priorité élevée est planifié, les pods de pause sont supprimés et le pod à priorité élevée les remplace immédiatement. Les pods de pause supprimés sont ensuite replanifiés. Si aucun espace n'est disponible dans le cluster, l'autoscaler de cluster démarre de nouveaux nœuds pour les intégrer. Il est recommandé de n'avoir qu'un seul pod de pause par nœud. Par exemple, si vous utilisez quatre nœuds de processeur, paramétrez la demande de processeurs du pod de pause à environ 3 200 m.

Choisir le type de machine approprié

En plus de l'autoscaling, d'autres configurations peuvent vous permettre d'exécuter des applications Kubernetes à coût maîtrisé sur GKE. Cette section explique comment choisir le type de machine approprié.

VM préemptives

Les VM préemptives sont des instances de VM Compute Engine qui durent au maximum 24 heures et n'offrent aucune garantie de disponibilité. Les VM préemptives sont jusqu'à 80 % moins chères que les VM Compute Engine standards, mais nous vous recommandons de les utiliser avec précaution sur les clusters GKE. Sur GKE, les VM préemptives sont plus adaptées à l'exécution de tâches par lot ou tolérantes aux pannes, qui sont moins sensibles au caractère éphémère et non garanti des VM préemptives. Les charges de travail de diffusion avec état ne doivent pas faire appel à des VM préemptives, sauf si vous concevez votre système et votre architecture de façon à gérer les contraintes des VM préemptives.

Quel que soit le type de charge de travail, vous devez être attentif aux contraintes suivantes :

  • Il est possible que le budget d'interruption de pod ne soit pas respecté, car les nœuds préemptifs peuvent s'arrêter par inadvertance.
  • Rien ne garantit que vos pods s'arrêteront normalement une fois que la préemption des nœuds aura ignoré le délai de grâce du pod.
  • GKE peut mettre plusieurs minutes à détecter que le nœud a été préempté et que les pods ne fonctionnent plus, ce qui retarde leur replanification vers un nouveau nœud.

Afin d'atténuer ces contraintes, vous pouvez déployer dans votre cluster un projet communautaire de gestionnaire d'événements d'arrêt de nœuds (attention : il ne s'agit pas d'un projet Google officiel). Celui-ci fournit un adaptateur destiné à traduire les événements d'arrêt de nœuds Compute Engine en arrêts concertés de pods dans Kubernetes. Ce projet communautaire ne résout pas de manière fiable toutes les contraintes des VM préemptives, vu que les budgets d'interruption des pods peuvent toujours être outrepassés. Par conséquent, la replanification des pods peut nécessiter un délai légèrement plus long.

Enfin, les VM préemptives ne bénéficient d'aucune garantie de disponibilité et peuvent donc être facilement indisponibles dans certaines régions. Pour contourner cette limitation, nous vous recommandons de configurer un pool de nœuds de secours sans VM préemptives. L'autoscaler de cluster favorise les VM préemptives, car il cible une optimisation basée sur le coût de l'infrastructure.

Pour en savoir plus, consultez les pages Exécuter des VM préemptives sur GKE et Exécuter des applications Web sur GKE à l'aide de VM Spot économiques.

Types de machines E2

Les types de machines E2 (VM E2) sont des VM à coût maîtrisé permettant de réaliser 31 % d'économies par rapport aux types de machines N1. Les VM E2 conviennent à un grand nombre de charges de travail, y compris les serveurs Web, les microservices, les applications stratégiques, les bases de données de petite à moyenne taille et les environnements de développement.

Pour en savoir plus sur les VM E2 et les comparer à d'autres types de machines Google Cloud, consultez les pages Gestion des ressources dynamiques basées sur les performances dans les VM E2 et Types de machines.

Sélectionner la région appropriée

Lorsque le coût est un critère qui rentre en ligne de compte, l'emplacement où vous exécutez vos clusters GKE est important. Le coût varie en fonction des régions de calcul, et ce en raison de nombreux facteurs. Assurez-vous donc d'exécuter votre charge de travail avec l'option la moins coûteuse, sans pour autant occasionner de la latence à votre client. Si votre charge de travail suppose de copier des données d'une région à une autre (par exemple, pour exécuter une tâche par lot), vous devez également prendre en compte le coût de déplacement de ces données.

Pour savoir comment sélectionner la bonne région, consultez la page Bonnes pratiques pour la sélection des régions Compute Engine.

S'inscrire pour bénéficier de remises sur engagement d'utilisation

Si vous avez l'intention d'utiliser Google Cloud pendant plusieurs années, nous vous recommandons vivement de souscrire à des remises sur engagement d'utilisation pour bénéficier de remises conséquentes sur l'utilisation des VM. Lorsque vous signez un contrat d'engagement d'utilisation, vous acquérez des ressources de calcul à prix réduit (jusqu'à 70 % de remise) en vous engageant pour une durée d'utilisation d'un an ou de trois ans. Si vous n'êtes pas sûr de la quantité de ressources à solliciter, examinez votre utilisation minimale de nos ressources de calcul (par exemple, pendant la nuit) et engagez-vous à hauteur de cette quantité.

Pour en savoir plus sur les tarifs avec engagement d'utilisation pour différents types de machines, consultez la page Tarifs des instances de VM.

Examiner les petits clusters de développement

Pour les clusters de développement de petite taille où vous devez réduire les coûts, envisagez d'utiliser des clusters Autopilot. Avec les clusters dans ce mode de fonctionnement, les pods système, les coûts du système d'exploitation ou les charges de travail non planifiées ne vous sont pas facturés.

Examiner vos stratégies de journalisation et de surveillance

Si vous utilisez Cloud Logging et Cloud Monitoring pour assurer l'observabilité de vos applications et infrastructures, vous ne payez que ce que vous utilisez. Cependant, plus votre infrastructure et vos applications consignent des informations dans les journaux, et plus vous conservez longtemps ces journaux, plus ceux-ci vous coûtent cher. De même, plus vous vous appuyez sur des métriques externes et personnalisées, plus vos coûts augmentent. Analysez vos stratégies de journalisation et de surveillance en fonction de l'optimisation des coûts liés à Cloud Logging, à Cloud Monitoring et à la gestion des performances des applications.

Examiner le trafic de sortie interrégional dans les clusters régionaux et multizones

Les types de clusters GKE disponibles sont les suivants : clusters à zone unique, clusters multizones et clusters régionaux. En raison de la haute disponibilité des nœuds entre les zones, les clusters régionaux et multizones sont parfaitement adaptés aux environnements de production. Cependant, le trafic de sortie entre les zones vous est facturé. En environnement de production, nous vous recommandons de surveiller la charge de trafic entre les zones et de réduire celle-ci au minimum en optimisant vos API. Pensez également à appliquer des configurations d'affinité et d'anti-affinité entre les pods pour regrouper les pods dépendants de différents services au sein des mêmes nœuds ou de la même zone de disponibilité, afin de réduire les coûts et la latence du réseau entre eux. Pour surveiller ce trafic, il est conseillé d'activer la mesure de l'utilisation de GKE et son agent de sortie réseau, qui est désactivé par défaut.

Dans les environnements hors production, la bonne pratique de réduction des coûts consiste à déployer des clusters à zone unique.

Préparer votre environnement à votre type de charge de travail

En termes de coûts et de disponibilité, chaque entreprise à ses propres exigences. Les charges de travail peuvent être divisées en charges de travail de diffusion, capables de répondre rapidement à une utilisation intensive ou à des pics d'utilisation, et en charges de travail par lot, chargées des tâches à effectuer. Les charges de travail de diffusion nécessitent une faible latence de scaling à la hausse ; les charges de travail par lot tolèrent mieux la latence. La variété des attentes associées à ces types de charge de travail facilite le choix de différentes méthodes de réduction des coûts.

Charges de travail par lot

Les charges de travail par lot sont liées aux tâches à effectuer et permettent de réduire les coûts générés par GKE, car elles tolèrent généralement un certain temps de latence au moment où les tâches sont lancées. Cette tolérance accorde à l'autoscaler de cluster l'espace nécessaire pour ne démarrer de nouveaux nœuds que lorsque des tâches sont planifiées, ainsi que pour supprimer des nœuds lorsque les tâches sont terminées.

La première pratique recommandée consiste à répartir les charges de travail par lot dans différents pools de nœuds à l'aide de libellés et sélecteurs, ainsi que de rejets et tolérances. Le principe est le suivant :

  • L'autoscaler de cluster peut supprimer les nœuds vides plus rapidement s'il n'a pas besoin de redémarrer les pods. À la fin des tâches par lot, le cluster accélère le processus de scaling à la baisse si la charge de travail s'exécute sur des nœuds dédiés qui sont désormais vides. Pour améliorer encore la vitesse du scaling à la baisse, configurez le profil d'optimisation de l'autoscaler de cluster.
  • Certains pods ne peuvent pas être redémarrés, et bloquent ainsi de manière permanente le scaling à la baisse des nœuds auxquels ils appartiennent. Ces pods, qui incluent les pods système, doivent s'exécuter sur différents pools de nœuds pour ne pas affecter le scaling à la baisse.

La seconde pratique recommandée consiste à utiliser le provisionnement automatique des nœuds pour créer automatiquement des pools de nœuds dédiés, pour les tâches comportant un rejet ou une tolérance associés. Vous pouvez ainsi séparer de nombreuses charges de travail différentes sans devoir configurer autant de groupes de nœuds différents.

Nous vous recommandons de n'utiliser des VM préemptives que si vous exécutez des tâches avec une tolérance aux pannes qui sont moins sensibles au caractère éphémère et à la disponibilité non garantie des VM préemptives.

Pour en savoir plus sur la mise en place d'un environnement conforme à ces pratiques, consultez le tutoriel Optimiser l'utilisation des ressources dans un cluster GKE mutualisé à l'aide du provisionnement automatique des nœuds.

Charges de travail de diffusion

Contrairement aux charges de travail par lot, les charges de travail de diffusion doivent répondre aussi rapidement que possible à une utilisation intensive ou aux pics de trafic. Ces augmentations soudaines du trafic peuvent résulter de nombreux facteurs, par exemple, les publicités télévisées, les événements de grande envergure comme le Black Friday, ou les alertes info. Votre application doit être en mesure de les gérer.

Les problèmes de gestion de ces pics sont généralement liés à une ou plusieurs des raisons suivantes :

  • Des applications non opérationnelles sur Kubernetes, qui comportent par exemple des images de grande taille, dont le démarrage est lent ou dont la configuration n'est pas optimisée pour Kubernetes.
  • Les applications qui dépendent d'une infrastructure dont le provisionnement prend un certain temps, comme les GPU.
  • Les autoscalers et le surprovisionnement ne sont pas paramétrés de manière appropriée.

Préparer votre application Kubernetes basée sur le cloud

Certaines des bonnes pratiques décrites dans cette section peuvent vous permettre de réaliser des économies même en dehors du contexte des applications Kubernetes à coût maîtrisé. Cependant, comme la plupart de ces pratiques sont destinées à assurer la compatibilité de votre application avec les autoscalers, nous vous recommandons vivement de les mettre en œuvre.

Connaître les capacités de votre application

Lorsque vous planifiez la capacité de vos applications, vous devez déterminer le nombre de requêtes simultanées que votre application peut traiter, la quantité de ressources processeur et mémoire dont elle a besoin, ainsi que sa capacité de réponse en cas de forte charge. La plupart des équipes ignorent ces capacités, aussi nous vous recommandons de tester le comportement de votre application en situation de surcharge. Isolez l'instance dupliquée d'un pod d'une application et désactivez l'autoscaling, puis effectuez les tests en simulant une charge d'utilisation réelle. Cela vous permet de mesurer la capacité pour un pod. Nous vous recommandons ensuite de configurer votre autoscaler de cluster, les demandes et les limites de ressources, et soit l'autoscaler horizontal de pods, soit l'autoscaler vertical de pods. Relancez ensuite un test plus poussé pour simuler une utilisation intensive ou des pics de trafic soudains.

Dans l'idéal, afin d'éliminer les problèmes de latence, ces tests doivent être effectués dans la même région ou zone que celle où l'application s'exécute sur Google Cloud. Vous pouvez utiliser l'outil de votre choix pour réaliser ces tests, à l'aide d'un script personnalisé ou d'un outil de mesure des performances plus avancé, comme Apache Benchmark, JMeter ou Locust.

Pour obtenir un exemple de procédure de test, consultez la section Tests de charge distribués à l'aide de Google Kubernetes Engine.

S'assurer que votre application peut se développer verticalement et horizontalement

Faites en sorte que votre application s'adapte à la demande. Vous pouvez ainsi choisir de gérer les augmentations de trafic, soit en augmentant les ressources processeur et mémoire, soit en ajoutant des instances dupliquées de pods. Vous avez ainsi la possibilité de déterminer ce qui convient le mieux à votre application, par exemple une configuration d'autoscaler ou une taille de nœud différentes. Certaines applications s'exécutent malheureusement sur un seul thread ou sont limitées à un nombre fixe de nœuds de calcul ou de sous-processus, ce qui ne permet pas de mener cette expérience sans une refactorisation complète de leur architecture.

Définir des demandes et des limites de ressources adaptées

Lorsque vous connaissez la capacité de vos applications, vous pouvez configurer les ressources de votre conteneur en conséquence. Dans Kubernetes, les ressources sont principalement constituées du processeur et de la mémoire (RAM). Vous configurez le processeur ou la mémoire en fonction de la puissance requise pour exécuter votre application via la demande spec.containers[].resources.requests.<cpu|memory>, ainsi que la limite associée via la demande spec.containers[].resources.limits.<cpu|memory>.

Lorsque vous avez correctement paramétré les demandes de ressources, le programmeur Kubernetes peut les utiliser pour décider du nœud sur lequel placer votre pod. Cela garantit que les pods sont placés dans des nœuds capables de les faire fonctionner normalement, de façon à améliorer la stabilité et à réduire les gaspillages de ressources. Paramétrer des limites de ressources permet en outre de garantir que ces applications n'utilisent jamais la totalité de l'infrastructure sous-jacente disponible fournie par les nœuds de calcul.

Pour paramétrer les ressources de votre conteneur, une bonne pratique consiste à utiliser la même quantité de mémoire pour les demandes et les limites de ressources, ainsi qu'à fixer une limite d'utilisation du processeur plus importante ou indéterminée. Prenons l'exemple du déploiement suivant :

apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress
spec:
  replicas: 1
  selector:
    matchLabels:
      app: wp
  template:
    metadata:
      labels:
        app: wp
    spec:
      containers:
  - name: wp
    image: wordpress
    resources:
      requests:
        memory: "128Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"

Le principe du modèle précédent se fonde sur la prise en charge du manque de ressources par Kubernetes. Pour résumer, une fois les ressources de calcul épuisées, les nœuds deviennent instables. Pour éviter cette situation, kubelet surveille et empêche la pénurie totale des ressources en hiérarchisant les pods dont la consommation est la plus élevée. Lorsque le processeur est en cause, ces pods peuvent être limités aux demandes de ressources processeur. En revanche, la mémoire étant une ressource incompressible, le pod doit être supprimé une fois celle-ci épuisée. Afin d'éviter la suppression des pods (ainsi qu'un environnement instable), la mémoire demandée doit correspondre à la limite de mémoire.

Vous pouvez également utiliser l'autoscaler vertical de pods en mode recommandation pour paramétrer l'utilisation du processeur et de la mémoire d'une application donnée. L'autoscaler vertical de pods propose de telles recommandations en fonction de l'utilisation de votre application. Nous vous recommandons donc de l'activer dans un environnement de production pour répondre au trafic réel. L'autoscaler vertical de pods génère alors un rapport indiquant les demandes et les limites de ressources suggérées, que vous pouvez spécifier de manière statique dans votre fichier manifeste de déploiement. Si votre application inclut déjà l'autoscaler horizontal de pods, consultez la section Combiner les autoscalers horizontal et vertical de pods.

S'assurer que votre conteneur est le plus léger possible

Lorsque vos applications s'exécutent dans des conteneurs, il convient d'observer certaines pratiques lors de leur création. Lorsque vous exploitez ces conteneurs sur Kubernetes, certaines de ces pratiques sont d'autant plus importantes que votre application peut démarrer et s'arrêter à tout moment. Cette section porte principalement sur les deux pratiques suivantes :

  • Utilisez la plus petite image possible. Il est préférable d'exploiter des images de taille réduite, car chaque fois que l'autoscaler de cluster provisionne un nouveau nœud dans votre cluster, ce nœud doit télécharger les images qui y seront exécutées. Plus l'image est de taille réduite, plus le nœud peut la télécharger rapidement.

  • Démarrez l'application le plus rapidement possible. Le démarrage de certaines applications peut nécessiter quelques minutes en raison du chargement des classes, de la mise en cache, etc. Lorsqu'un pod nécessite un long démarrage, les demandes de vos clients peuvent échouer pendant que votre application se lance.

Prenez en compte ces deux pratiques lors de la conception de votre système, surtout si vous prévoyez une utilisation intensive ou des pics de trafic. Une image de taille réduite et un démarrage rapide permettent de réduire la latence des scalings à la hausse. Vous pouvez ainsi mieux gérer les augmentations de trafic sans vous soucier outre mesure de l'instabilité. Ces pratiques se combinent idéalement avec les bonnes pratiques d'autoscaling présentées dans la section sur l'autoscaling GKE.

Pour en savoir plus sur la création de conteneurs, consultez la section Bonnes pratiques pour la création de conteneurs.

Ajouter un budget d'interruption de pod à votre application

Le budget d'interruption de pod limite le nombre de pods pouvant être supprimés simultanément dans le cadre d'une interruption volontaire. Le budget d'interruption défini est donc respecté lors des déploiements, des mises à niveau des nœuds et de toute activité d'autoscaling. Cependant, ce budget ne peut être garanti lorsque des imprévus surviennent, comme une panne de matériel, une panique du noyau ou la suppression accidentelle d'une VM par une personne.

Lorsque le budget d'interruption de pod est respecté pendant la phase de compactage de l'autoscaler de cluster, il est recommandé de définir un budget d'interruption de pod pour chaque application. Vous pouvez ainsi contrôler le nombre minimal d'instances dupliquées nécessaires pour supporter votre charge à tout moment, y compris lorsque l'autoscaler de cluster effectue un scaling à la baisse de votre cluster.

Pour en savoir plus, consultez la section Spécifier un budget d'interruption pour votre application.

Définir des vérifications d'aptitude et d'activité pertinentes pour votre application

La mise en place de vérifications pertinentes garantit que votre application ne reçoit du trafic que lorsqu'elle est opérationnelle et apte à le faire. GKE a recours à des vérifications d'aptitude pour décider quand ajouter ou supprimer des pods des équilibreurs de charge. GKE a recours à des vérifications d'activité pour décider quand redémarrer vos pods.

La vérification d'activité permet d'indiquer à Kubernetes qu'un pod est incapable de poursuivre son activité, par exemple lorsqu'un interblocage est détecté. La vérification d'aptitude permet d'indiquer à Kubernetes que votre application n'est pas apte à recevoir du trafic, par exemple, lors du chargement d'un grand nombre de données en cache au démarrage.

Pour garantir un cycle de vie correct à votre application au cours des activités de scaling à la hausse, vous devez procéder comme suit :

  • Paramétrez la vérification d'aptitude de l'ensemble de vos conteneurs.
  • Si votre application dépend d'un cache qui doit être chargé au démarrage, la vérification d'aptitude ne doit indiquer que l'application est prête que lorsque le cache est entièrement chargé.
  • Si votre application peut commencer immédiatement à diffuser des requêtes, l'implémentation d'une vérification par défaut peut être très simple, par exemple, un point de terminaison HTTP renvoyant un code d'état 200.
  • Si vous mettez en œuvre une vérification plus avancée, pour savoir par exemple si le pool de connexion dispose de ressources disponibles, assurez-vous que votre taux d'erreur n'augmente pas comparé à une mise en œuvre plus simple.
  • Ne permettez jamais à une logique de vérification d'accéder à d'autres services. Si ces services ne répondent pas rapidement, cela peut compromettre le cycle de vie de votre pod.

Pour plus d'informations, consultez la section Configurer des vérifications d'activité, d'aptitude et de démarrage.

S'assurer que vos applications s'arrêtent conformément aux attentes de Kubernetes

Les autoscalers vous permettent de répondre aux pics de trafic en démarrant de nouveaux pods et nœuds, et en les supprimant à l'issue des pics de trafic. Pour éviter les erreurs au cours du fonctionnement de vos pods, vous devez donc vous préparer à un démarrage rapide ou à un arrêt progressif.

Étant donné que Kubernetes met à jour de manière asynchrone les points de terminaison et les équilibreurs de charge, observez scrupuleusement ces bonnes pratiques afin de garantir des arrêts sans perturbation :

  • Continuez à accepter des nouvelles requêtes juste après le signal SIGTERM. Votre application ne doit pas s'arrêter immédiatement mais achever de traiter toutes les demandes en cours, tout en continuant à écouter les connexions entrantes qui se présentent après le début de l'arrêt du pod. Kubernetes mettra peut-être un certain temps à mettre à jour l'ensemble des kube-proxys et des équilibreurs de charge. Si votre application s'arrête avant cette mise à jour, certaines requêtes peuvent entraîner des erreurs côté client.
  • Si votre application n'observe pas la pratique précédente, utilisez le hook preStop. La plupart des programmes n'arrêtent pas immédiatement d'accepter des requêtes. Cependant, si vous faites appel à un code tiers ou si vous gérez un système sur lequel vous n'avez pas de contrôle, comme nginx, le hook preStop constitue un excellent moyen de déclencher un arrêt progressif sans modifier l'application. Une stratégie courante consiste à exécuter une veille de quelques secondes dans le hook preStop pour retarder le signal SIGTERM. Ainsi, Kubernetes dispose d'un délai supplémentaire pour achever le processus de suppression du pod, réduisant ainsi les erreurs de connexion côté client.
  • Utilisez le signal SIGTERM pour gérer les nettoyages. Si votre application nécessite un nettoyage ou présente un état en mémoire qui doit être maintenu avant la fin du traitement, l'émission du signal SIGTERM constitue le moment propice. Chaque langage de programmation capte ce signal de manière différente. Vous devez donc connaître celle qui correspond au langage que vous utilisez.
  • Configurez terminationGracePeriodSeconds en fonction des besoins de votre application. Certaines applications nécessitent par défaut plus de 30 secondes pour s'arrêter. Dans ce cas, vous devez spécifier terminationGracePeriodSeconds. Une valeur élevée peut par exemple augmenter le temps de mise à niveau ou de déploiement des nœuds. Si cette valeur est faible, Kubernetes n'aura peut-être pas le temps d'achever le processus d'arrêt du pod. Quoi qu'il en soit, nous vous recommandons de fixer le délai d'arrêt de votre application à moins de 10 minutes, car l'autoscaler de cluster n'y consacre que 10 minutes.
  • Si votre application fait appel à l'équilibrage de charge natif du conteneur, passez d'abord outre la vérification d'aptitude lorsque vous recevez un signal SIGTERM. Cette action ordonne directement aux équilibreurs de charge d'arrêter de transmettre de nouvelles requêtes au pod de backend. En fonction de la concurrence entre la configuration des vérifications d'état et la programmation des points de terminaison, il est possible que le pod de backend soit retiré du trafic plus tôt.

Pour en savoir plus, consultez les bonnes pratiques Kubernetes : arrêt progressif.

Configurer NodeLocal DNSCache

Le DNS géré par GKE est mis en œuvre par kube-dns, un module complémentaire déployé dans tous les clusters GKE. Lorsque vous exécutez des applications faisant massivement appel au DNS, il se peut que la configuration par défaut kube-dns-autoscaler, qui ajuste le nombre d'instances dupliquées de kube-dns en fonction du nombre de nœuds et de cœurs du cluster, ne soit pas suffisante. Dans ce scénario, les requêtes DNS peuvent être ralenties ou dépasser leur délai d'expiration. Pour atténuer ce problème, les entreprises ajustent généralement le fichier ConfigMap kube-dns-autoscaler pour augmenter le nombre d'instances dupliquées de kube-dns dans leurs clusters. Bien que cette stratégie puisse fonctionner comme prévu, elle augmente l'utilisation des ressources et le coût total de GKE.

Une autre solution à coût maîtrisé et plus évolutive consiste à configurer NodeLocal DNSCache dans votre cluster. NodeLocal DNSCache est un module complémentaire optionnel de GKE qui améliore la latence de la résolution DNS, harmonise les délais des résolutions DNS et réduit le nombre de requêtes DNS adressées à kube-dns en exploitant un cache DNS sur chaque nœud du cluster.

Pour en savoir plus, consultez la page Configurer NodeLocal DNSCache.

Utiliser l'équilibrage de charge natif en conteneurs via Ingress

L'équilibrage de charge natif en conteneurs permet aux équilibreurs de charge de cibler directement les pods Kubernetes et de répartir uniformément le trafic entre ceux-ci au moyen d'un modèle de données appelé groupes de points de terminaison du réseau. Cette approche améliore les performances du réseau, augmente la visibilité, active des fonctions avancées d'équilibrage de charge et permet l'utilisation de Traffic Director, le plan de contrôle du trafic entièrement géré de Google Cloud pour le maillage de services.

Compte tenu de ces avantages, l'équilibrage de charge natif en conteneurs est la solution recommandée pour l'équilibrage de charge via Ingress. Lorsque des groupes de points de terminaison du réseau sont utilisés avec GKE Ingress, le contrôleur d'entrée facilite la création de tous les aspects de l'équilibreur de charge L7. Cela inclut la création de l'adresse IP virtuelle, des règles de transfert, des vérifications d'état, des règles de pare-feu, etc.

L'équilibrage de charge natif en conteneurs prend encore plus d'importance en cas de recours à l'autoscaler de cluster. Dans le cas des équilibreurs de charge sans groupes de points de terminaison du réseau, durant les scalings à la baisse, il est possible que la programmation de l'équilibrage de charge et le drainage de connexion ne soient pas entièrement achevés avant que l'autoscaler de cluster n'arrête les instances de nœud. Une telle situation peut perturber les connexions en cours qui passent par le nœud, même si les pods de backend ne sont pas situés sur le nœud.

L'équilibrage de charge natif en conteneurs est activé par défaut pour les services lorsque l'ensemble des conditions suivantes sont remplies :

  • Les services ont été créés dans des clusters GKE 1.17.6-gke.7 et versions ultérieures.
  • Vous utilisez des clusters de VPC natif.
  • Vous n'utilisez pas de VPC partagé.
  • Vous n'utilisez pas de règle de réseau GKE.

Pour en savoir plus, consultez la documentation sur GKE Ingress et la page Utiliser l'équilibrage de charge natif en conteneurs.

Envisager d'utiliser un intervalle exponentiel entre les tentatives

Dans les architectures de microservices s'exécutant sur Kubernetes, des défaillances temporaires peuvent survenir pour diverses raisons, par exemple :

Ces problèmes temporaires peuvent être atténués en rappelant le service passé un certain délai. Cependant, pour éviter de submerger de requêtes le service de destination, vous devez impérativement passer ces appels en respectant un intervalle exponentiel entre les tentatives.

Pour faciliter ce genre de nouvelles tentatives, de nombreuses bibliothèques existantes appliquent une logique de relance exponentielle. Vous pouvez utiliser la bibliothèque de votre choix ou écrire votre propre code. Si vous utilisez Istio ou Anthos Service Mesh (ASM), vous pouvez opter pour un mécanisme de relance au niveau du proxy, qui effectue de manière transparente les nouvelles tentatives en votre nom.

Votre application doit impérativement permettre la relance des appels de service, pour éviter, par exemple, d'insérer des informations déjà saisies. Notez qu'une succession de nouvelles tentatives mal planifiée peut affecter le temps de latence de votre utilisateur final, avec dépassement potentiel du délai d'expiration.

Surveiller votre environnement et appliquer des configurations et des pratiques à coût maîtrisé

Dans de nombreuses moyennes et grandes entreprises, une plate-forme centralisée et une équipe d'infrastructure sont souvent responsables de la création, de la maintenance et de la surveillance des clusters Kubernetes pour l'ensemble de l'entreprise. Il est donc impératif de veiller à l'utilisation rationnelle des ressources et de s'assurer que toutes les équipes appliquent les règles de l'entreprise. Cette section présente les options de surveillance et d'application des pratiques à coût maîtrisé.

Observer vos clusters GKE et surveiller les recommandations

Vous pouvez contrôler l'utilisation des ressources dans un cluster Kubernetes en inspectant les conteneurs, les pods et les services, ainsi que les caractéristiques de l'ensemble du cluster. Il existe de nombreuses façons de mener à bien cette tâche, mais nous vous recommandons de commencer par observer vos clusters GKE à l'aide du tableau de bord Monitoring. Vous obtiendrez ainsi des données de séries temporelles sur l'utilisation de votre cluster, qui vous permettront d'agréger et de couvrir l'infrastructure, les charges de travail et les services.

Il s'agit d'un bon point de départ, mais Google Cloud offre également les options suivantes :

  • Dans la console Google Cloud, sur la page Clusters GKE, consultez la colonne Notifications. Si l'un de vos clusters génère un important gaspillage de ressources, l'interface utilisateur vous donne un aperçu de l'ensemble des ressources allouées, comparées aux informations demandées.

    Accéder à la liste des clusters GKE

  • Dans la console Google Cloud, sur la page Recommandations, recherchez les fiches de recommandations Économies.

    Accéder au centre de recommandations

Pour en savoir plus, consultez les pages Observer vos clusters GKE et Premiers pas avec le centre de recommandations.

Activer la mesure de l'utilisation de GKE

Pour adopter une approche plus souple vous permettant de voir la répartition approximative des coûts, optez pour la mesure de l'utilisation de GKE. La mesure de l'utilisation de GKE vous permet de consulter les profils d'utilisation de vos clusters GKE, ventilés par espaces de noms et par libellés. Celle-ci recueille des informations sur les demandes de ressources et la consommation de ces ressources découlant des charges de travail de votre cluster, comme le processeur, le GPU, le TPU, la mémoire, le stockage et, éventuellement, la sortie réseau.

La mesure de l'utilisation de GKE vous permet d'appréhender la structure globale des coûts de vos clusters GKE, de savoir quelle équipe ou application est la plus coûteuse, quel environnement ou composant a provoqué un pic d'utilisation ou de coûts, et quelle équipe génère le plus de gaspillage. En comparant les demandes de ressources à l'utilisation réelle, vous découvrirez quelles charges de travail sont sous- ou surprovisionnées.

Vous pouvez vous servir des modèles par défaut de Looker Studio ou aller plus loin et personnaliser les tableaux de bord en fonction des besoins de votre entreprise. Pour en savoir plus sur la mesure de l'utilisation de GKE et ses prérequis, consultez la section Comprendre l'utilisation des ressources de cluster.

Comprendre le fonctionnement du module complémentaire Metrics-server et le surveiller

Metrics-server constitue la source des métriques relatives aux ressources des conteneurs pour les pipelines d'autoscaling intégrés à GKE. Metrics-server extrait les métriques des kubelets et les expose via l'API Metrics de Kubernetes. Les autoscalers horizontal et vertical de pods exploitent ensuite ces métriques pour savoir à quel moment déclencher l'autoscaling.

Pour assurer le bon fonctionnement de l'autoscaling GKE, vous devez disposer d'un module complémentaire Metrics-server opérationnel. Le déploiement de metrics-server dans GKE implique l'installation d'un système de supervision du redimensionnement permettant de faire évoluer verticalement le conteneur Metrics-server, en ajoutant ou en supprimant des processeurs et de la mémoire, en fonction du nombre de nœuds du cluster. La mise à jour sur place des pods n'est pas encore compatible avec Kubernetes. Le système de supervision doit donc redémarrer le pod metrics-server afin de mettre en œuvre les nouvelles ressources nécessaires.

Bien que le redémarrage soit rapide, le délai de latence total nécessaire aux autoscalers pour entrer en action peut augmenter légèrement après un redimensionnement de metrics-server. Pour éviter les redémarrages fréquents du module complémentaire Metrics-server dans les clusters qui évoluent rapidement, le système de supervision autorise des délais de redimensionnement à partir de GKE 1.15.11-gke.9.

Suivez ces bonnes pratiques lorsque vous utilisez le module complémentaire Metrics-server :

  • Choisissez une version de GKE qui accepte les délais de redimensionnement de metrics-server. Vous pouvez vous en assurer en vérifiant si le fichier YAML de déploiement de metrics-server contient la configuration scale-down-delay dans le conteneur metrics-server-nanny.
  • Surveillez le déploiement de metrics-server. S'il est indisponible, l'autoscaling ne fonctionne pas. L'idéal est que ce soit vos services de surveillance prioritaires qui surveillent ce déploiement.
  • Suivez les bonnes pratiques décrites dans la section Autoscaling GKE.

Utiliser les quotas de ressources Kubernetes

Dans les clusters mutualisés, les différentes équipes sont généralement responsables d'applications déployées dans différents espaces de noms. Dans le cas d'une plate-forme centralisée et d'un groupe d'infrastructures, il y a lieu de craindre qu'une équipe utilise plus de ressources que nécessaire. Épuiser les ressources de calcul du cluster ou déclencher trop de scalings à la hausse peut accroître vos coûts.

Pour résoudre ce problème, vous devez mettre en place des quotas de ressources. Les quotas de ressources permettent de gérer la quantité de ressources utilisée par les objets dans un espace de noms. Vous pouvez définir des quotas en termes de ressources de calcul (processeur et mémoire) et de ressources de stockage, ou en termes de nombre d'objets. Les quotas de ressources vous permettent de vous assurer qu'aucun locataire n'utilise plus de ressources de cluster que la part qui lui est attribuée.

Pour en savoir plus, consultez la page Configurer les quotas de mémoire et de processeur d'un espace de noms.

Envisager d'utiliser GKE Enterprise Policy Controller

GKE Enterprise Policy Controller est un contrôleur d'admission dynamique Kubernetes qui vérifie, audite et assure la conformité de vos clusters non seulement avec les règles liées à la sécurité ou aux réglementations, mais aussi avec des règles métier arbitraires. Policy Controller applique des contraintes pour assurer la conformité de votre cluster. Vous pouvez par exemple mettre en place des contraintes dans votre cluster afin de faire observer la plupart des bonnes pratiques présentées dans la section Préparer votre application Kubernetes basée sur le cloud. Ainsi, les déploiements sont refusés s'ils ne sont pas strictement conformes à vos pratiques Kubernetes. Appliquer ces règles permet d'éviter les pics de coûts inattendus et réduit le risque d'instabilité de la charge de travail lors de l'autoscaling.

Pour en savoir plus sur les modalités d'application et de rédaction de vos propres règles, consultez les sections Créer des contraintes et Écrire un modèle de contrainte. Si vous n'êtes pas client GKE Enterprise, vous pouvez envisager d'utiliser Gatekeeper, le logiciel Open Source sur lequel APC s'appuie.

Concevoir votre pipeline CI/CD de façon à instaurer une logique d'économie

GKE Enterprise Policy Controller vous permet d'éviter le déploiement de logiciels non conformes dans votre cluster GKE. Nous vous recommandons toutefois d'appliquer ces contraintes liées aux règles dès le début de votre cycle de développement, lors des contrôles préalables à un commit, des contrôles des demandes d'extraction, des flux de diffusion ou de toute autre étape pertinente compte tenu de votre environnement. Cette pratique vous permet de détecter et de corriger rapidement les erreurs de configuration et vous indique à quels éléments vous devez prêter attention lorsque vous créez des garde-fous.

Pensez également à faire appel aux fonctions kpt dans votre pipeline CI/CD pour confirmer que vos fichiers de configuration Kubernetes respectent les contraintes imposées par GKE Enterprise Policy Controller, ainsi que pour estimer l'utilisation des ressources ou le coût du déploiement. Vous pouvez ainsi arrêter le pipeline lorsqu'un problème lié aux coûts est détecté. Vous pouvez également créer un processus d'approbation de déploiement différent pour les configurations qui, par exemple, augmentent le nombre d'instances dupliquées.

Pour en savoir plus, consultez la section Utiliser Policy Controller dans un pipeline CI. Pour étudier un exemple complet de plate-forme de livraison, consultez la page : CI/CD modernes avec GKE Enterprise.

Instaurer une culture de l'économie

De nombreuses entreprises mettent en place des abstractions et des plates-formes pour dissimuler la complexité de leur infrastructure. Il s'agit d'une pratique courante dans les entreprises qui migrent leurs services depuis des machines virtuelles vers Kubernetes. Parfois, ces entreprises autorisent les développeurs à configurer leurs propres applications en production. Toutefois, il n'est pas rare que les développeurs n'aient jamais touché à un cluster Kubernetes.

Les pratiques que nous recommandons dans cette section ne vous dispensent pas de recourir à des abstractions. Elles vous permettent en revanche de connaître vos dépenses liées à Google Cloud et de former vos développeurs et vos opérateurs sur votre infrastructure. Vous pouvez y parvenir en instaurant des mesures d'incitation à la formation et des programmes qui regroupent cours traditionnels ou en ligne, groupes de discussion, examens par les pairs, programmation en binôme, jeux en lien avec la CI/CD et la réalisation d'économies, etc. Dans l'univers Kubernetes, il est par exemple important de comprendre les répercussions d'une image d'application de 3 Go, d'une vérification d'aptitude défaillante ou d'une configuration erronée de l'autoscaler horizontal de pods.

Enfin, comme le montre l'étude de l'équipe DORA de Google, les capacités culturelles sont parmi les principaux facteurs qui permettent d'améliorer les performances organisationnelles, de réduire le travail de retraitement, l'épuisement professionnel, etc. Il en va de même pour la réduction des coûts. Donner à vos employés l'accès à leurs dépenses leur permet de s'aligner davantage sur les objectifs et les contraintes de l'entreprise.

Récapitulatif des bonnes pratiques

Le tableau suivant récapitule les bonnes pratiques recommandées dans ce document.

Sujet Tâche
Options et fonctionnalités d'optimisation des coûts de GKE
Préparer vos applications Kubernetes cloud natives
Surveiller votre environnement et appliquer des configurations et des pratiques à coût maîtrisé
Culture

Étapes suivantes