We are at re:Invent 2026Book my merch

Cloud Intelligence™

La fonctionnalité GKE que la plupart des clusters n'utilisent toujours pas : les ComputeClasses personnalisées

Cette page est également disponible en English, Deutsch, Español, Italiano, 日本語 et Português.

Nov 13, 202611 min read
Chimbu Chinnadurai

About Chimbu Chinnadurai

Senior Cloud Architect II

I've probably debugged a Kubernetes issue in more time zones than I care to count. Based in London, I help engineering teams across EMEA get their clusters to behave — and actually understand why they misbehaved in the first place.

I write, speak, and guest on podcasts about all things cloud-native. Away from the terminal: I enjoy cooking almost as much as simplifying overly complex systems.

My personal page

Je retrouve le même schéma dans presque chaque revue de cluster GKE que je mène : une longue liste de node pools statiques, chacun lié à un seul type de machine. Un pool n2-standard-8 pour les workloads génériques, un pool n2-highmem-16 pour les services gourmands en mémoire, un pool Spot créé l'an dernier lors d'une campagne de réduction des coûts, et peut-être un pool GPU. Les workloads sont placés sur les nœuds via nodeSelector, des taints, des tolerations et des règles de node affinity accumulées au fil des ans.

Ça tient tant que rien ne bouge — et quand ça bouge, c'est généralement l'un de ces trois scénarios.

  • Pénuries zonales : une zone vient à manquer de la série de machines choisie. Cluster Autoscaler ne peut faire évoluer que les pools que vous lui avez indiqués, laissant des pods bloqués en Pending alors même que des familles de machines voisines restent inutilisées dans la même zone.

  • Pièges de préemption Spot : de fortes préemptions Spot déversent les workloads sur des pools de fallback on-demand. Une fois la capacité revenue, rien ne rapatrie activement les workloads, et les économies prévues n'apparaissent jamais sur la facture.

  • Montées de génération : passer de N2 à N4 ou C4 devient un chantier opérationnel de plusieurs semaines : provisionner de nouveaux pools, mettre à jour les valeurs Helm dans des dizaines de dépôts, drainer les anciens nœuds, et espérer qu'aucun manifeste n'a codé en dur d'anciens labels.

GKE propose depuis un moment déjà une réponse à ces trois problèmes : les ComputeClasses personnalisées. Les clients avec qui j'échange soit n'en ont jamais entendu parler, soit pensent qu'elles sont réservées à Autopilot. Ce n'est pas le cas. Les ComputeClasses personnalisées sont disponibles en mode Autopilot comme en mode Standard à partir de GKE 1.30.3-gke.1451000, et elles sont activées par défaut sur tous les clusters éligibles.

Qu'est-ce qu'une ComputeClass personnalisée ?

Une ComputeClass est une ressource personnalisée Kubernetes (computeclasses.cloud.google.com) qui définit les profils de nœuds que les workloads privilégient, classés par priorité. Comme l'explique la documentation de Google, elle fournit à GKE un profil d'attributs de nœuds à utiliser lors des événements d'autoscaling.

  • Node pools traditionnels : vous déclarez d'abord l'infrastructure, puis vous y dirigez les workloads.

  • ComputeClasses : vous déclarez une intention cible (essayer d'abord N4 Spot ; si indisponible, essayer C4 Spot ; sinon, revenir à N4 on-demand) et l'autoscaler provisionne automatiquement les bons nœuds.

Les responsabilités restent ainsi bien séparées : les équipes plateforme définissent les profils matériels, et les développeurs applicatifs choisissent un profil par son nom.

Ce que ça résout concrètement

  • Les pénuries deviennent des fallbacks automatisés : si une règle de priorité élevée échoue pour cause de quota ou de disponibilité zonale, GKE tente immédiatement la règle suivante de la liste.
  • La capacité de fallback ne s'éternise pas : avec la migration active, GKE ramène les workloads vers les nœuds de priorité supérieure dès que la capacité préférée revient, récupérant automatiquement les économies.
  • Les montées de version restent côté plateforme : faire passer les workloads de N2 à N4, ou tester C4, revient à mettre à jour un seul manifeste ComputeClass. Les équipes applicatives ne touchent jamais à leurs sélecteurs.

D'autres points, plus mineurs, facilitent aussi la vie. Vous pouvez décider de façon centralisée quelles réservations Compute Engine sont consommées en premier, ajuster l'agressivité avec laquelle chaque classe consolide les nœuds sous-utilisés, et définir une classe par défaut pour un namespace ou tout le cluster, afin que les équipes obtiennent un matériel adapté sans écrire de sélecteur.

Les principaux réglages de configuration

Sous spec.priorities, chaque règle définit une cible matérielle principale : machineFamily (par exemple n4), machineType (par exemple n4-standard-32), gpu ou tpu. Pour les clusters Standard, une règle peut pointer vers des node pools existants avec nodepools. Les règles acceptent des options pour spot, minCores, minMemoryGb, les paramètres du disque de démarrage, les SSD locaux, les disques de démarrage secondaires, les réservations et les zones.

  • whenUnsatisfiable : contrôle le comportement si tous les niveaux de priorité échouent. ScaleUpAnyway crée un nœud avec la configuration par défaut du cluster, tandis que DoNotScaleUp laisse les Pods en attente jusqu'à ce qu'un nœud correspondant puisse être créé. DoNotScaleUp est la valeur par défaut depuis GKE 1.33 (auparavant, c'était ScaleUpAnyway) : définissez-la explicitement pour éviter les surprises quand des clusters sur des versions différentes partagent les mêmes manifestes.

  • autoscalingPolicy : configure la sensibilité du scale-down avec consolidationDelayMinutes, un consolidationThreshold CPU et mémoire, et un gpuConsolidationThreshold distinct.

  • activeMigration : la migration active comporte deux options.

    • optimizeRulePriority: true ramène activement les pods vers les nœuds de priorité supérieure dès que la capacité se libère.
    • ensureAllDaemonSetPodsRunning: true remplace les nœuds trop petits pour exécuter tous les Pods DaemonSet requis par des nœuds plus grands.
  • nodePoolAutoCreation.enabled: true : autorise GKE à créer et supprimer des node pools pour satisfaire vos priorités. À partir de GKE 1.33.3-gke.1136000, le node auto-provisioning au niveau du cluster n'est plus nécessaire pour cela.

Vos pools existants restent utilisables. Ajoutez le label cloud.google.com/compute-class et un taint NoSchedule correspondant à un pool créé manuellement : il rejoint la classe, ce qui permet une adoption progressive.

Vous pouvez aussi appliquer une ComputeClass par défaut à un namespace en le labellisant, ou à tout le cluster en déployant une classe nommée default et en activant la fonctionnalité sur le cluster. GKE fournit également des ComputeClasses intégrées, dont autopilot, qui permet aux clusters Standard d'exécuter certains Pods sur la plateforme de calcul optimisée pour les conteneurs d'Autopilot.

Deux patterns pour démarrer

Pattern 1 : remplacer les pools Spot statiques par une chaîne de fallback résiliente

Voici une classe de calcul généraliste qui privilégie N4 Spot, bascule sur C4 Spot, et utilise N4 on-demand en soupape de sécurité. Elle consolide les nœuds sous-utilisés après 5 minutes et fait remonter les pods dans la chaîne quand la capacité Spot revient :

apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: general-cost-optimized
spec:
nodePoolAutoCreation:
enabled: true
priorities:
- machineFamily: n4
spot: true
minCores: 4
- machineFamily: c4
spot: true
minCores: 4
- machineFamily: n4
spot: false
activeMigration:
optimizeRulePriority: true
autoscalingPolicy:
consolidationDelayMinutes: 5
consolidationThreshold: 70
whenUnsatisfiable: DoNotScaleUp

Avec optimizeRulePriority: true, GKE ramène les Pods vers la règle Spot préférée dès que la capacité revient, puis supprime le nœud de fallback.

Les workloads consomment cette classe via un simple node selector :

apiVersion: apps/v1
kind: Deployment
metadata:
name: checkout-api
spec:
replicas: 3
selector:
matchLabels:
app: checkout-api
template:
metadata:
labels:
app: checkout-api
spec:
nodeSelector:
cloud.google.com/compute-class: general-cost-optimized
containers:
- name: api
image: registry.k8s.io/pause
resources:
requests:
cpu: "1"
memory: "2Gi"

Pas de sélecteur cloud.google.com/gke-spot, pas de tolerations ni d'affinité de famille de machines — et c'est voulu. GKE rejette les Pods qui sélectionnent une ComputeClass tout en sélectionnant des labels système ayant un champ ComputeClass correspondant, comme cloud.google.com/gke-spot, cloud.google.com/machine-family ou node.kubernetes.io/instance-type. Ces choix appartiennent à la classe. Si vous migrez des workloads existants, commencez par rechercher ces labels dans vos manifestes et charts Helm.

Pattern 2 : superposer des classes à vos pools personnalisés existants

Si vos clusters Standard comportent des pools spécialisés, préchauffés ou adossés à des réservations, inutile de les supprimer. Configurez la classe pour utiliser d'abord les pools existants et n'en créer de nouveaux que lorsqu'ils ne peuvent plus évoluer :

apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: hybrid-fallback-class
spec:
nodePoolAutoCreation:
enabled: true
priorities:
- nodepools: [core-workload-pool]
- machineFamily: n4
- machineFamily: c4

Labellisez et taintez votre pool existant pour que la classe le reconnaisse :

gcloud container node-pools update core-workload-pool \
--cluster=example-cluster \
--node-labels="cloud.google.com/compute-class=hybrid-fallback-class"
gcloud container node-pools update core-workload-pool \
--cluster=example-cluster \
--node-taints="cloud.google.com/compute-class=hybrid-fallback-class:NoSchedule"

Notez que --node-labels et --node-taints remplacent tous les labels et taints du pool : incluez donc les valeurs existantes lorsque vous exécutez ces commandes.

Le guide des bonnes pratiques recommande le même ordre : les pools créés manuellement reçoivent la priorité la plus élevée et les pools auto-créés servent de fallback.

Cloud bill shouldn't be a mystery

One platform for AI and Cloud optimization.

Nouveautés récentes à connaître

La fonctionnalité a beaucoup évolué au fil des dernières versions mineures de GKE. Voici les changements que je signalerais à quiconque a regardé les ComputeClasses il y a un an avant de passer à autre chose.

Scores de priorité pondérés (1.35.2-gke.1842000+)

Au lieu de reposer uniquement sur l'ordre de la liste, les règles peuvent définir un priorityScore explicite de 1 à 1000. C'est tout ou rien : soit chaque règle de la classe a un score, soit aucune. Jusqu'à trois règles peuvent partager un même score, et GKE évalue ensemble les règles à égalité, en laissant Cluster Autoscaler choisir entre elles.

apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: priority-rule-score-class
spec:
nodePoolAutoCreation:
enabled: true
priorities:
- machineFamily: e2
spot: true
priorityScore: 30
- machineFamily: n2
spot: true
priorityScore: 20
- machineFamily: t2d
spot: true
priorityScore: 20
- machineFamily: n1
spot: true
priorityScore: 10
whenUnsatisfiable: ScaleUpAnyway

Ici, N2 et T2D Spot comptent comme des seconds choix équivalents. Les règles groupées peuvent ajouter de la latence d'autoscaling — davantage pour les règles machineFamily larges que pour les règles machineType plus ciblées — car GKE doit exécuter plus de simulations.

Sélection automatique du stockage (1.35.3-gke.1290000+)

Mélanger les générations de machines comportait auparavant un risque côté stockage, chaque série prenant en charge des types de disques spécifiques (par exemple, N4 prend en charge Hyperdisk, tandis que N2 repose sur les PD standard). Vous pouvez désormais utiliser une StorageClass avec sélection automatique du type de disque : GKE crée un type de disque compatible avec le type de machine sur lequel le Pod atterrit. Les chaînes de fallback multi-générations deviennent ainsi bien plus sûres pour les workloads utilisant le provisioning dynamique. Les disques préexistants requièrent toujours un type de disque pris en charge par toutes les séries de machines de la classe.

Formes de machines personnalisées (1.33.2-gke.1111000+)

Vous pouvez définir des formes personnalisées comme n4-custom-8-20480 directement dans machineType, pour les workloads dont le ratio CPU/mémoire ne correspond pas aux formes prédéfinies.

Paramètres de disque de démarrage sur les règles machineFamily (1.34.1-gke.1431000+)

Définissez storage.bootDiskType et storage.bootDiskSize sur les règles machineFamily flexibles, et plus seulement sur les règles machineType spécifiques :

priorities:
- machineFamily: n4
spot: true
minCores: 16
minMemoryGb: 64
storage:
bootDiskType: hyperdisk-balanced
bootDiskSize: 100

Labels et taints dans la classe (1.33.2 à 1.34.1)

Déclarez nodeLabels et taints par règle de priorité (labels à partir de 1.33.2-gke.1111000, taints à partir de 1.33.4-gke.1350000) ou globalement sous nodePoolConfig (à partir de 1.34.1-gke.3084002). Les valeurs au niveau des règles et les valeurs globales ne doivent pas se chevaucher. Labels et isolation restent ainsi dans le même objet que la décision matérielle.

Classes par défaut pour les workloads système (1.33.1-gke.1788000+)

Les namespaces peuvent recevoir une classe par défaut qui ne s'applique qu'aux Pods non-DaemonSet, via le label cloud.google.com/default-compute-class-non-daemonset. GKE s'en sert pour exécuter les Pods système des namespaces comme kube-system et gmp-system séparément de vos workloads, tandis que les Pods DaemonSet ne reçoivent pas le sélecteur de classe.

Calcul Autopilot en parallèle d'une classe par défaut personnalisée (1.34.1-gke.1829001+)

Si vous définissez une classe personnalisée comme classe par défaut dans un cluster Autopilot, les Pods cessent de s'exécuter par défaut sur la plateforme optimisée pour les conteneurs d'Autopilot. Vous pouvez désormais exécuter certains Pods sur la plateforme de calcul Autopilot en leur ajoutant le node selector cloud.google.com/compute-class: autopilot.

Quelques ajouts plus mineurs

priorityDefaults (1.32.1-gke.1729000) permet de définir des valeurs partagées une seule fois au lieu de les répéter dans chaque règle. nodeSystemConfig intègre le réglage du kubelet et des sysctl dans la classe. Le placement compact et les workload policies sont disponibles pour Autopilot à partir de 1.33.2-gke.1335000.

Précautions en production et cas limites

Les ComputeClasses ont des limites, et mieux vaut les découvrir en revue de conception qu'en production.

  • kube-scheduler ignore les règles de priorité : les ComputeClasses influencent l'autoscaling, mais kube-scheduler ne les prend pas en compte. Si des nœuds de fallback disposent déjà de capacité, de nouveaux Pods peuvent y atterrir avant les nœuds préférés. Activer activeMigration.optimizeRulePriority remplace ces nœuds de fallback au fil du temps, et un consolidationThreshold plus strict aide les nœuds de fallback sous-utilisés à se vider plus tôt.

  • Les modifications ne valent que pour l'avenir : modifier une ComputeClass ne change rien aux nœuds en cours d'exécution. Cordonnez et drainez les nœuds existants pendant une fenêtre de maintenance pour qu'ils soient remplacés selon les nouvelles règles.

  • Tenez les workloads stateful à l'écart de la migration active : la migration active évince les Pods et ne déplace pas les données. Le guide des bonnes pratiques recommande de la désactiver pour les classes utilisées par des workloads stateful. Placez ces workloads dans une classe dédiée, et utilisez la sélection automatique du type de disque ou limitez la classe aux séries de machines qui prennent toutes en charge votre type de disque.

  • Les classes par défaut de namespace ne migrent pas les Pods existants : GKE n'injecte le sélecteur de classe que dans les Pods créés après le labelling du namespace ; les Pods déjà en cours d'exécution restent intacts. Redémarrez les workloads du namespace après avoir défini une classe par défaut, pour que les Pods recréés récupèrent le sélecteur et la migration active. Une classe par défaut au niveau du cluster peut, elle, migrer directement les Pods existants.

  • Attention au churn élevé de Pods : dans les clusters où les créations et suppressions de Pods sont très fréquentes, Cluster Autoscaler peut ne pas évaluer les règles inférieures avant l'expiration du backoff des règles supérieures, et les Pods restent en Pending. Si vous rencontrez ce cas limite, réduisez la fréquence de consolidation ou désactivez la migration active.

  • Comportement de fallback des réservations : avec AnyBestEffort, si aucune réservation correspondante n'a de capacité, GKE tente un nœud on-demand pour cette même règle avant de passer à la suivante. Pour basculer directement sur la règle suivante quand la capacité réservée est pleine, utilisez affinity: Specific (pour les réservations nommées) ou affinity: AnyThenFail.

Contraintes plus mineures

Un workload ne peut sélectionner qu'une seule ComputeClass, et chaque node pool créé manuellement ne peut appartenir qu'à une seule classe. Sur Autopilot, bootDiskType ne prend en charge que pd-balanced. Les noms de classes ne peuvent pas commencer par gke ni autopilot. Beaucoup des fonctionnalités ci-dessus requièrent des versions de patch récentes : vérifiez votre canal de release avant de bâtir votre architecture dessus.

Conclusion

Si vos clusters tournent encore sur des node pools figés liés à des types de machines, commencez par un namespace stateless. Donnez-lui une chaîne de fallback privilégiant le Spot, puis observez à quelle fréquence les Pods atterrissent sur les règles de fallback et si la migration active les ramène.

Gardez à l'esprit qu'une ComputeClass décide du type de nœud à créer, mais que la taille des nœuds dépend des requests de ressources de vos Pods. Pour les règles machineFamily, Cluster Autoscaler choisit une taille de machine en fonction des requests agrégées des Pods en attente. Des requests surdimensionnées impliquent des machines plus grandes, un bin packing moins efficace et une empreinte de fallback plus importante.

C'est là que le right-sizing porte ses fruits. PerfectScale ajuste en continu les requests des workloads, afin que les nœuds créés par vos ComputeClasses correspondent à ce que vos Pods consomment réellement. Sa fonctionnalité Node Recommendations vous aide à choisir les familles de machines les plus rentables à placer dans vos règles de priorité. Si vous auditez les dépenses de vos clusters et souhaitez voir comment ces configurations de fallback se comportent en pratique, réservez une démo avec l'équipe.

Références