Provisionner une capacité de calcul supplémentaire pour un scaling rapide des pods


Cette page explique comment réserver une capacité de calcul supplémentaire dans vos clusters Google Kubernetes Engine (GKE) afin que vos charges de travail puissent rapidement évoluer à la hausse lors des pics de trafic sans attendre le démarrage de nouveaux nœuds. Vous pouvez suivre ces instructions pour réserver la surcharge de calcul de façon permanente ou en prévision d'événements spécifiques.

Intérêt du provisionnement d'une capacité de réserve

Les clusters GKE Autopilot et les clusters standards avec provisionnement automatique de nœuds créent de nouveaux nœuds lorsqu'aucun nœud existant n'a la capacité requise pour exécuter de nouveaux pods. Le démarrage de chaque nouveau nœud prend environ 80 à 120 secondes. GKE attend que le nœud ait démarré avant de placer des pods en attente dessus, après quoi ces pods peuvent démarrer. Dans les clusters standards, vous pouvez aussi créer manuellement un nouveau pool de nœuds ayant la capacité supplémentaire requise pour exécuter de nouveaux pods. Cette page s'applique aux clusters qui utilisent un mécanisme d'autoscaling de nœud, tel qu'Autopilot ou le provisionnement automatique des nœuds.

Dans certains cas, vous souhaiterez peut-être que vos pods démarrent plus rapidement lors d'événements de scaling à la hausse. Par exemple, si vous lancez une nouvelle extension pour votre jeu multijoueur en ligne populaire, réduire le temps de démarrage de vos pods de serveur de jeu peut limiter le temps passé en file d'attente pour les joueurs qui se connectent le jour du lancement. Autre exemple : si vous exécutez une plate-forme d'e-commerce et que vous programmez une vente flash pendant une durée limitée, vous prévoyez des pics de trafic pendant toute la durée de la vente.

Le provisionnement de capacités de secours est compatible avec l'utilisation intensive des pods. Cela permet aux pods d'utiliser temporairement des ressources demandées par d'autres pods du nœud, si cette capacité est disponible et inutilisée par d'autres pods. Pour utiliser l'utilisation intensive, définissez des limites de ressources supérieures à vos demandes de ressources ou ne définissez pas de limites de ressources. Pour en savoir plus, consultez la page Configurer l'utilisation intensive des pods dans GKE.

Fonctionnement du provisionnement d'une capacité de réserve dans GKE

Pour provisionner une capacité de réserve, vous pouvez utiliser les PriorityClasses de Kubernetes et les pods d'espace réservé. Une PriorityClass vous permet d'indiquer à GKE que certaines charges de travail sont moins prioritaires que d'autres. Vous pouvez déployer des pods d'espace réservé qui utilisent une PriorityClass de faible priorité et demandent la capacité de calcul que vous devez réserver. GKE ajoute de la capacité au cluster en créant des nœuds pour gérer les pods d'espace réservé.

Lorsque vos charges de travail de production évoluent à la hausse, GKE évince les pods d'espace réservé ayant une priorité inférieure et planifie à leur place les nouvelles instances dupliquées de vos pods de production (qui utilisent une PriorityClass de priorité plus élevée). Si vous avez plusieurs pods de faible priorité ayant des niveaux de priorité différents, GKE évince en premier les pods ayant la priorité la plus basse.

Méthodes de provisionnement de capacité

Selon votre cas d'utilisation, vous pouvez provisionner de la capacité supplémentaire dans vos clusters GKE de l'une des manières suivantes :

  • Provisionnement de capacité cohérent : utilisez un déploiement pour créer un nombre spécifique de pods d'espace réservé à faible priorité qui s'exécutent en permanence dans le cluster. Lorsque GKE évince ces pods pour exécuter vos charges de travail de production, le contrôleur de déploiement s'assure que GKE provisionne davantage de capacité pour recréer les pods à faible priorité évincés. Cette méthode fournit une surcharge de capacité cohérente dans le temps au fil des différents événements de scaling à la hausse et à la baisse, jusqu'à la suppression du déploiement.
  • Provisionnement de capacité à usage unique : utilisez un job pour exécuter un nombre spécifique de pods parallèles d'espace réservé de faible priorité pendant une période spécifique. Une fois que ce délai est écoulé ou que GKE a évincé toutes les instances dupliquées du job, la capacité réservée cesse d'être disponible. Cette méthode fournit une quantité spécifique de capacité disponible pour une période donnée.

Tarifs

Dans GKE Autopilot, les demandes de ressources de vos pods en cours d'exécution vous sont facturées, y compris les charges de travail de faible priorité que vous déployez. Pour en savoir plus, consultez la section Tarifs du mode Autopilot.

Dans GKE Standard, les VM Compute Engine sous-jacentes provisionnées par GKE vous sont facturées, indépendamment du fait que les pods utilisent ou non cette capacité. Pour en savoir plus, consultez la page Tarifs du mode standard.

Avant de commencer

Avant de commencer, effectuez les tâches suivantes :

  • Activez l'API Google Kubernetes Engine.
  • Activer l'API Google Kubernetes Engine
  • Si vous souhaitez utiliser Google Cloud CLI pour cette tâche, installez puis initialisez gcloud CLI. Si vous avez déjà installé gcloud CLI, assurez-vous de disposer de la dernière version en exécutant la commande gcloud components update.
  • Assurez-vous de disposer d'un cluster GKE Autopilot ou d'un cluster GKE standard avec le provisionnement automatique des nœuds activé.
  • Consultez la section Considérations pour le provisionnement de capacité afin de vous assurer de choisir des valeurs appropriées dans vos requêtes de capacité.

Créer une PriorityClass

Pour utiliser l'une des méthodes décrites dans la section Méthodes de provisionnement de capacité, vous devez d'abord créer les PriorityClass suivantes :

  • PriorityClass Default : PriorityClass par défaut globale attribuée à tout pod qui ne définit pas explicitement une autre classe PriorityClass dans sa spécification de pod. Les pods ayant cette PriorityClass par défaut peuvent évincer les pods qui utilisent une PriorityClass inférieure.
  • PriorityClass Low : une PriorityClass autre que celle par défaut, définie sur la priorité la plus basse possible dans GKE. Les pods ayant cette PriorityClass peuvent être évincés pour exécuter des pods ayant des PriorityClass plus élevées.
  1. Enregistrez le manifeste suivant sous le nom priorityclasses.yaml :

    apiVersion: scheduling.k8s.io/v1
    kind: PriorityClass
    metadata:
      name: low-priority
    value: -10
    preemptionPolicy: Never
    globalDefault: false
    description: "Low priority workloads"
    ---
    apiVersion: scheduling.k8s.io/v1
    kind: PriorityClass
    metadata:
      name: default-priority
    value: 0
    preemptionPolicy: PreemptLowerPriority
    globalDefault: true
    description: "The global default priority."
    

    Ce fichier manifeste comprend les champs suivants :

    • preemptionPolicy : indique si les pods utilisant une PriorityClass peuvent évincer les pods de priorité inférieure. La PriorityClass low-priority utilise Never, et la PriorityClass default utilise PreemptLowerPriority.
    • value : priorité des pods qui utilisent la PriorityClass. La PriorityClass default utilise 0. La PriorityClass low-priority utilise -1. Dans Autopilot, vous pouvez définir cette valeur sur toute valeur inférieure à la priorité de la PriorityClass default.

      En mode standard, si vous définissez cette valeur sur une valeur inférieure à -10, les pods qui utilisent cette PriorityClass ne déclencheront pas la création de nœuds et resteront en attente.

      Pour obtenir de l'aide sur le choix des valeurs appropriées, consultez la section Choisir une priorité.

    • globalDefault : indique si GKE attribue ou non la PriorityClass aux pods qui ne définissent pas explicitement une PriorityClass dans leur spécification de pod. La PriorityClass low-priority utilise false, et la PriorityClass default utilise true.

  2. Appliquez le fichier manifeste :

    kubectl apply -f priorityclasses.yaml
    

Provisionner une capacité de calcul supplémentaire

Les sections suivantes présentent un exemple dans lequel vous provisionnez de la capacité pour un événement unique ou de manière cohérente au fil du temps.

Utiliser un déploiement pour un provisionnement de capacité cohérent

  1. Enregistrez le manifeste suivant sous le nom capacity-res-deployment.yaml :

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: capacity-res-deploy
    spec:
      replicas: 10
      selector:
        matchLabels:
          app: reservation
      template:
        metadata:
          labels:
            app: reservation
        spec:
          priorityClassName: low-priority
          terminationGracePeriodSeconds: 0
          containers:
          - name: ubuntu
            image: ubuntu
            command: ["sleep"]
            args: ["infinity"]
            resources:
              requests:
                cpu: 500m
                memory: 500Mi
    

    Ce fichier manifeste comprend les champs suivants :

    • spec.replicas : modifiez cette valeur pour répondre à vos besoins.
    • spec.resources.requests : modifiez les demandes de ressources mémoire et de processeur en fonction de vos besoins. Suivez les instructions de la section Choisir le dimensionnement de la capacité pour vous aider à choisir les valeurs de demande appropriées.
    • spec.containers.command et spec.containers.args : indiquent aux pods de rester actifs jusqu'à leur éviction par GKE.
  2. Appliquez le fichier manifeste :

    kubectl apply -f capacity-res-deployment.yaml
    
  3. Obtenez l'état du pod :

    kubectl get pods -l app=reservation
    

    Attendez que toutes les instances dupliquées atteignent l'état Running.

Utiliser un job pour un provisionnement de capacité lié à un événement unique

  1. Enregistrez le manifeste suivant sous le nom capacity-res-job.yaml :

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: capacity-res-job
    spec:
      parallelism: 4
      backoffLimit: 0
      template:
        spec:
          priorityClassName: low-priority
          terminationGracePeriodSeconds: 0
          containers:
          - name: ubuntu-container
            image: ubuntu
            command: ["sleep"]
            args: ["36000"]
            resources:
              requests:
                cpu: "16"
          restartPolicy: Never
    

    Ce fichier manifeste comprend les champs suivants :

    • spec.parallelism : remplacez la valeur par le nombre de jobs que vous souhaitez exécuter en parallèle pour réserver de la capacité.
    • spec.backoffLimit: 0 : empêche le contrôleur de job de recréer des jobs évincés.
    • template.spec.resources.requests : modifiez les demandes de ressources mémoire et de processeur en fonction de vos besoins. Suivez les instructions de la section Considérations pour vous aider à choisir les valeurs de demandes appropriées.
    • template.spec.containers.command et template.spec.containers.args : indiquent aux jobs de rester actifs pendant la période, en secondes, durant laquelle vous avez besoin de la capacité supplémentaire.
  2. Appliquez le fichier manifeste :

    kubectl apply -f capacity-res-job.yaml
    
  3. Obtenez l'état du job :

    kubectl get jobs
    

    Attendez que tous les jobs atteignent l'état Running.

Tester le provisionnement de capacité et l'éviction

Pour vérifier que le provisionnement de capacité fonctionne comme prévu, procédez comme suit :

  1. Dans votre terminal, surveillez l'état des charges de travail de provisionnement de la capacité :

    1. Pour les déploiements, exécutez la commande suivante :

      kubectl get pods --label=app=reservation -w
      
    2. Pour les jobs, exécutez la commande suivante :

      kubectl get Jobs -w
      
  2. Ouvrez une nouvelle fenêtre de terminal et procédez comme suit :

    1. Enregistrez le manifeste suivant sous le nom test-deployment.yaml :

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: helloweb
        labels:
          app: hello
      spec:
        replicas: 5
        selector:
          matchLabels:
            app: hello
            tier: web
        template:
          metadata:
            labels:
              app: hello
              tier: web
          spec:
            containers:
            - name: hello-app
              image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0
              ports:
              - containerPort: 8080
              resources:
                requests:
                  cpu: 400m
                  memory: 400Mi
      
    2. Appliquez le fichier manifeste :

      kubectl apply -f test-deployment.yaml
      
  3. Dans la fenêtre de terminal d'origine, notez que GKE arrête certaines des charges de travail de provisionnement de capacité pour planifier vos nouvelles instances dupliquées, comme dans l'exemple suivant :

    NAME                                         READY   STATUS    RESTARTS   AGE
    capacity-res-deploy-6bd9b54ffc-5p6wc         1/1     Running   0          7m25s
    capacity-res-deploy-6bd9b54ffc-9tjbt         1/1     Running   0          7m26s
    capacity-res-deploy-6bd9b54ffc-kvqr8         1/1     Running   0          2m32s
    capacity-res-deploy-6bd9b54ffc-n7zn4         1/1     Running   0          2m33s
    capacity-res-deploy-6bd9b54ffc-pgw2n         1/1     Running   0          2m32s
    capacity-res-deploy-6bd9b54ffc-t5t57         1/1     Running   0          2m32s
    capacity-res-deploy-6bd9b54ffc-v4f5f         1/1     Running   0          7m24s
    helloweb-85df88c986-zmk4f                    0/1     Pending   0          0s
    helloweb-85df88c986-lllbd                    0/1     Pending   0          0s
    helloweb-85df88c986-bw7x4                    0/1     Pending   0          0s
    helloweb-85df88c986-gh8q8                    0/1     Pending   0          0s
    helloweb-85df88c986-74jrl                    0/1     Pending   0          0s
    capacity-res-deploy-6bd9b54ffc-v6dtk   1/1     Terminating   0          2m47s
    capacity-res-deploy-6bd9b54ffc-kvqr8   1/1     Terminating   0          2m47s
    capacity-res-deploy-6bd9b54ffc-pgw2n   1/1     Terminating   0          2m47s
    capacity-res-deploy-6bd9b54ffc-n7zn4   1/1     Terminating   0          2m48s
    capacity-res-deploy-6bd9b54ffc-2f8kx   1/1     Terminating   0          2m48s
    ...
    helloweb-85df88c986-lllbd              0/1     Pending       0          1s
    helloweb-85df88c986-gh8q8              0/1     Pending       0          1s
    helloweb-85df88c986-74jrl              0/1     Pending       0          1s
    helloweb-85df88c986-zmk4f              0/1     Pending       0          1s
    helloweb-85df88c986-bw7x4              0/1     Pending       0          1s
    helloweb-85df88c986-gh8q8              0/1     ContainerCreating   0          1s
    helloweb-85df88c986-zmk4f              0/1     ContainerCreating   0          1s
    helloweb-85df88c986-bw7x4              0/1     ContainerCreating   0          1s
    helloweb-85df88c986-lllbd              0/1     ContainerCreating   0          1s
    helloweb-85df88c986-74jrl              0/1     ContainerCreating   0          1s
    helloweb-85df88c986-zmk4f              1/1     Running             0          4s
    helloweb-85df88c986-lllbd              1/1     Running             0          4s
    helloweb-85df88c986-74jrl              1/1     Running             0          5s
    helloweb-85df88c986-gh8q8              1/1     Running             0          5s
    helloweb-85df88c986-bw7x4              1/1     Running             0          5s
    

    Ce résultat montre que votre nouveau déploiement a mis cinq secondes pour passer de l'état "En attente" à l'état "En cours d'exécution".

Considérations relatives au provisionnement de capacité

Provisionnement de capacité cohérent

  • Évaluez le nombre d'instances dupliquées de pods d'espace réservé dont vous avez besoin et la taille des requêtes dans chaque instance dupliquée. Les instances dupliquées à faible priorité doivent demander au moins la capacité correspondant à votre charge de travail de production la plus importante, afin que ces charges de travail puissent tenir dans la capacité réservée par votre charge de travail de faible priorité.
  • Si vous exploitez un grand nombre de charges de travail de production à grande échelle, envisagez de définir les demandes de ressources de vos pods d'espace réservé sur des valeurs qui provisionnent une capacité suffisante pour exécuter plusieurs charges de travail de production au lieu d'une seule.

Provisionnement de capacité à usage unique

  • Définissez la durée de conservation des jobs d'espace réservé sur la durée pendant laquelle vous avez besoin de capacité supplémentaire. Par exemple, si vous souhaitez augmenter la capacité pour les 24 heures du jour de lancement d'un jeu, définissez la durée sur 86 400 secondes. Cela garantit que la capacité provisionnée ne durera pas plus longtemps que nécessaire.
  • Définissez un intervalle de maintenance pour la période durant laquelle vous réservez la capacité. Cela empêche l'éviction des jobs de faible priorité lors de la mise à niveau des nœuds. La définition d'un intervalle de maintenance est également une bonne pratique recommandée lorsque vous prévoyez une demande élevée sur votre charge de travail.
  • Si vous exploitez un grand nombre de charges de travail de production à grande échelle, envisagez de définir les demandes de ressources de vos jobs d'espace réservé sur des valeurs qui provisionnent une capacité suffisante pour exécuter plusieurs charges de travail de production au lieu d'une seule.

La capacité n'est provisionnée que pour un seul événement de scaling. Si vous augmentez la capacité et que vous l'utilisez pendant un temps avant de la réduire, cette capacité n'est plus disponible pour un autre événement de scaling à la hausse. Si vous prévoyez plusieurs événements de scaling à la hausse et à la baisse, utilisez la méthode de réservation de capacité cohérente et ajustez la taille de la réservation si nécessaire. Par exemple, vous pouvez augmenter les requêtes des pods avant un événement, puis les réduire ou les ramener à zéro après l'événement.

Choisir une priorité

Définissez la priorité de vos PriorityClasses sur des valeurs inférieures à zéro.

Vous pouvez définir dans votre cluster plusieurs PriorityClasses à utiliser avec des charges de travail ayant des exigences différentes. Par exemple, vous pouvez créer une PriorityClass ayant une priorité de -10 pour le provisionnement de capacité à usage unique et une PriorityClass ayant une priorité de -9 pour un provisionnement de capacité cohérent. Vous pouvez alors provisionner une capacité cohérente utilisant la PriorityClass de priorité -9. Lorsque vous souhaitez augmenter la capacité pour un événement spécial, vous pouvez déployer de nouveaux jobs qui utilisent la PriorityClass de priorité -10. GKE évince en premier les charges de travail ayant la priorité la plus basse.

Vous pouvez également utiliser d'autres PriorityClasses pour exécuter des charges de travail hors production de faible priorité, qui effectuent des tâches réelles comme des charges de travail par lot tolérantes aux pannes, à une priorité inférieure à celle de vos charges de travail de production, mais supérieure à celle de vos pods d'espace réservé (par exemple, -5).

Choisir le dimensionnement de la capacité

Définissez un nombre d'instances dupliquées et les demandes de ressources de votre charge de travail d'espace réservé sur une capacité supérieure ou égale à la capacité dont vos charges de travail de production auront besoin lors du scaling à la hausse.

La capacité totale provisionnée est basée sur le nombre de pods d'espace réservé que vous déployez et sur les demandes de ressources de chaque instance dupliquée. Si votre scaling à la hausse nécessite davantage de capacité que GKE n'en a provisionné pour vos pods d'espace réservé, certaines de vos charges de travail de production restent à l'état Pending jusqu'à ce que GKE puisse provisionner plus de capacité.

Étapes suivantes