Placer les pods GKE dans des zones spécifiques

Cette page explique comment indiquer à Google Kubernetes Engine (GKE) d'exécuter vos pods sur des nœuds situés dans des zones Google Cloud spécifiques à l'aide de la topologie zonale. Ce type d'emplacement est utile dans les situations suivantes :

  • Les pods doivent accéder aux données stockées sur un disque persistant Compute Engine zonal.
  • Les pods doivent s'exécuter avec d'autres ressources zonales telles que des instances Cloud SQL.

Vous pouvez également utiliser un emplacement zonal avec un routage du trafic basé sur la topologie pour réduire la latence entre les clients et les charges de travail. Pour plus d'informations sur le routage du trafic basé sur la topologie, consultez la page Routage basé sur la topologie.

L'utilisation de la topologie zonale pour contrôler l'emplacement des pods est un mécanisme Kubernetes avancé que vous ne devez utiliser que si votre situation nécessite l'exécution de pods dans des zones spécifiques. Dans la plupart des environnements de production, nous vous recommandons d'utiliser des ressources régionales, qui sont les valeurs par défaut de GKE, lorsque cela est possible.

Méthodes de placement zonal

La topologie zonale est intégrée à Kubernetes avec le libellé de nœud topology.kubernetes.io/zone: ZONE. Pour indiquer à GKE de placer un pod dans une zone spécifique, utilisez l'une des méthodes suivantes :

  • nodeAffinity : spécifiez une règle nodeAffinity dans la spécification de pod pour une ou plusieurs zones Google Cloud . Cette méthode est plus flexible qu'un nodeSelector, car elle vous permet de placer des pods dans plusieurs zones.
  • nodeSelector : spécifiez un nodeSelector ciblant une seule zone Google Cloud dans la spécification de pod.

  • Classes de calcul : configurez votre pod pour qu'il utilise une classe de calcul GKE. Cette approche vous permet de définir une liste hiérarchisée d'ensembles de zones Google Cloud . Il permet de déplacer dynamiquement la charge de travail vers l'ensemble de zones le plus approprié lorsque des nœuds sont disponibles dans ces zones. Pour en savoir plus, consultez À propos des classes de calcul personnalisées.

Remarques

Le placement de pod zonal basé sur la topologie zonale prend en compte les éléments suivants :

  • Le cluster doit se trouver dans la même région Google Cloud que les zones demandées.
  • Dans les clusters standards, vous devez utiliser le provisionnement automatique des nœuds ou créer des pools de nœuds avec des nœuds dans les zones demandées. Les clusters Autopilot gèrent automatiquement ce processus pour vous.
  • Les clusters standards doivent être des clusters régionaux.

Tarifs

La topologie zonale est une fonctionnalité de planification Kubernetes sans frais sans frais supplémentaires dans GKE.

Pour en savoir plus sur les tarifs, consultez la page Tarifs de GKE.

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 la Google Cloud CLI pour cette tâche, installez et initialisez la gcloud CLI. Si vous avez déjà installé la gcloud CLI, obtenez la dernière version en exécutant la commande gcloud components update. Il est possible que les versions antérieures de la gcloud CLI ne permettent pas d'exécuter les commandes de ce document.
  • Assurez-vous de disposer d'un cluster GKE existant dans la même régionGoogle Cloud que les zones dans lesquelles vous souhaitez placer vos pods. Pour créer un cluster, consultez la page Créer un cluster Autopilot.

Placer les pods dans plusieurs zones en utilisant nodeAffinity

Kubernetes nodeAffinity fournit un mécanisme de contrôle de planification flexible qui accepte plusieurs sélecteurs de libellés et opérateurs logiques. Utilisez nodeAffinity si vous souhaitez autoriser les pods à s'exécuter dans une zone faisant partie d'un ensemble de zones (par exemple, dans us-central1-a ou dans us-central1-f).

  1. Enregistrez le manifeste suivant sous le nom multi-zone-affinity.yaml :

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx-multi-zone
      template:
        metadata:
          labels:
            app: nginx-multi-zone
        spec:
          containers:
          - name: nginx
            image: nginx:latest
            ports:
            - containerPort: 80
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: topology.kubernetes.io/zone
                    operator: In
                    values:
                    - us-central1-a
                    - us-central1-f
    

    Ce fichier manifeste crée un déploiement avec trois instances dupliquées et place les pods dans us-central1-a ou us-central1-f en fonction de la disponibilité des nœuds.

    Assurez-vous que votre cluster se trouve dans la région us-central1. Si votre cluster se trouve dans une autre région, remplacez les zones du champ de valeurs du fichier manifeste par des zones valides pour la région de votre cluster.

    Facultatif : Si vous provisionnez des VM TPU, utilisez une zone d'IA, comme us-central1-ai1a. Les zones d'IA sont des emplacements spécialisés optimisés pour les charges de travail d'IA/de ML dans les régions Google Cloud .

  2. Créez le déploiement :

    kubectl create -f multi-zone-affinity.yaml
    

    GKE crée les pods dans des nœuds de l'une des zones spécifiées. Plusieurs pods peuvent s'exécuter sur le même nœud. Vous pouvez éventuellement utiliser l'anti-affinité de pod pour indiquer à GKE de placer chaque pod sur un nœud distinct.

Placer les pods dans une seule zone en utilisant nodeSelector

Pour placer des pods dans une seule zone, utilisez nodeSelector dans la spécification du pod. Un objet nodeSelector correspond à une règle nodeAffinity requiredDuringSchedulingIgnoredDuringExecution ne comportant qu'une seule zone.

  1. Enregistrez le manifeste suivant sous le nom single-zone-selector.yaml :

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-singlezone
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx-singlezone
      template:
        metadata:
          labels:
            app: nginx-singlezone
        spec:
          nodeSelector:
            topology.kubernetes.io/zone: "us-central1-a"
          containers:
          - name: nginx
            image: nginx:latest
            ports:
            - containerPort: 80
    

    Ce fichier manifeste indique à GKE de placer toutes les instances dupliquées dans le déploiement de la zone us-central1-a.

  2. Créez le déploiement :

    kubectl create -f single-zone-selector.yaml
    

Prioriser le placement des pods dans des zones sélectionnées à l'aide d'une classe de calcul

Les classes de calcul GKE fournissent un mécanisme de contrôle qui vous permet de définir une liste de priorités de configuration des nœuds. Les préférences zonales vous permettent de définir les zones dans lesquelles vous souhaitez que GKE place les pods.

Utiliser la priorité des zones géographiques

Pour définir des préférences zonales dans les classes de calcul à l'aide de la priorité des zones géographiques, vous devez utiliser la version 1.33.1-gke.1545000 ou ultérieure de GKE.

L'exemple suivant crée une classe de calcul qui spécifie une liste de zones préférées pour les pods.

Ces étapes supposent que votre cluster se trouve dans la région us-central1. Si votre cluster se trouve dans une autre région, remplacez les valeurs des zones dans le fichier manifeste par des zones valides pour la région de votre cluster.

  1. Enregistrez le manifeste suivant sous le nom zones-custom-compute-class.yaml :

    apiVersion: cloud.google.com/v1
    kind: ComputeClass
    metadata:
      name: zones-custom-compute-class
    spec:
      priorities:
      - location:
        zones: [us-central1-a, us-central1-b]
      - location:
        zones: [us-central1-c]
      activeMigration:
        optimizeRulePriority: true
      nodePoolAutoCreation:
        enabled: true
      whenUnsatisfiable: ScaleUpAnyway
    

    Le fichier manifeste de cette classe de calcul modifie le comportement de scaling comme suit :

    1. GKE tente de placer les pods dans us-central1-a ou dans us-central1-b.
    2. Si us-central1-a et us-central1-b ne disposent pas de capacité disponible, GKE tente de placer les pods dans us-central1-c.
    3. Si us-central1-c ne dispose pas de capacité disponible, le champ whenUnsatisfiable: ScaleUpAnyway permet à GKE de placer les pods dans n'importe quelle zone disponible de la région.
    4. Si une zone ayant une priorité plus élevée dans la classe de calcul devient disponible ultérieurement, le champ activeMigration.optimizeRulePriority: true permet à GKE de déplacer les pods vers cette zone à partir de zones de priorité inférieure. Cette migration utilise le budget d'interruption de pod pour garantir la disponibilité du service.
  2. Créez la classe de calcul personnalisée :

    kubectl create -f zones-custom-compute-class.yaml
    

    GKE crée une classe de calcul personnalisée à laquelle vos charges de travail peuvent faire référence.

  3. Enregistrez le manifeste suivant sous le nom custom-compute-class-deployment.yaml :

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-zonal-preferences
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx-zonal-preferences
      template:
        metadata:
          labels:
            app: nginx-zonal-preferences
        spec:
          nodeSelector:
            cloud.google.com/compute-class: "zones-custom-compute-class"
          containers:
          - name: nginx
            image: nginx:latest
            ports:
            - containerPort: 80
    
  4. Créez le déploiement :

    kubectl create -f custom-compute-class-deployment.yaml
    

Utiliser la priorité des zoneTypes de localisation

Pour définir des préférences zonales dans les classes de calcul à l'aide de la priorité des types de zones de localisation, vous devez utiliser GKE version 1.35.2-gke.1842000 ou ultérieure. Si vous sélectionnez un type de zone pour vos pods, un pool de nœuds couvrant toutes les zones d'un type donné sera utilisé ou créé, selon vos paramètres.

Vous pouvez spécifier les types de zones suivants dans votre classe de calcul :

  • STANDARD : zones à usage général Google Cloud dans une région. Recommandée pour les charges de travail autres que le ML.
  • AI : zones spécialisées optimisées pour la capacité d'IA/d'accélérateur. Recommandé pour les charges de travail d'IA/de ML.
  • CLUSTER_DEFAULT : zones spécifiées dans autoprovisioning-locations du cluster (ou les emplacements du cluster si ce champ est vide).

Pour en savoir plus sur les zones standards et d'IA, consultez À propos des zones d'IA.

Restrictions concernant la combinaison de champs

Vous ne pouvez pas combiner le champ zoneTypes avec les champs location.zones ou reservations.specific dans la même entrée de priorité. Vous pouvez utiliser les champs zoneTypes et location.zones dans la même classe de calcul à condition de les placer dans des entrées de priorité distinctes.

De plus, le champ priorityDefaults s'applique à chaque priorité de la classe de calcul. Cette règle implique que la définition du champ zoneTypes dans le champ priorityDefaults vous empêche d'utiliser le champ location.zones ou le champ reservations.specific dans n'importe quelle priorité.

Exemple valide : priorités distinctes

L'exemple suivant est valide, car zones et zoneTypes sont spécifiés dans des entrées de priorité distinctes :

apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
  name: valid-zonal-preferences
spec:
  priorities:
  - location:
      zones: [us-central1-a]
  - location:
      zoneTypes: [AI]

Exemple non valide : même priorité

L'exemple suivant n'est pas valide, car zones et zoneTypes sont spécifiés dans la même entrée de priorité :

apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
  name: invalid-same-priority
spec:
  priorities:
  - location:
      zones: [us-central1-a]
      zoneTypes: [AI] # Error: mutually exclusive

Exemple non valide : conflit avec les valeurs par défaut

L'exemple suivant n'est pas valide, car la définition du champ zoneTypes dans la section priorityDefaults est en conflit avec le champ zones dans l'entrée de priorité :

apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
  name: invalid-defaults-conflict
spec:
  priorityDefaults:
    location:
      zoneTypes: [AI]
  priorities:
  - location:
      zones: [us-central1-a] # Error: merges with defaults

Exemple d'utilisation

L'exemple suivant crée une classe de calcul qui spécifie une liste de types de zones préférés pour les pods.

  1. Enregistrez le manifeste suivant sous le nom zone-types-custom-compute-class.yaml :

    apiVersion: cloud.google.com/v1
    kind: ComputeClass
    metadata:
      name: zone-types-custom-compute-class
    spec:
      priorities:
      - location:
        zones: [us-central1-c]
      - location:
        zoneTypes:
        - AI
      - location:
        zoneTypes:
        - CLUSTER_DEFAULT
      activeMigration:
        optimizeRulePriority: true
      nodePoolAutoCreation:
        enabled: true
      whenUnsatisfiable: ScaleUpAnyway
    

    Le fichier manifeste de cette classe de calcul modifie le comportement de scaling comme suit :

    1. GKE tente de placer les pods dans la zone us-central1-c.
    2. Si us-central1-c ne dispose pas de capacité disponible, GKE tente de placer les pods dans n'importe quelle zone AI de la région.
    3. Si aucune des zones AI ne dispose de capacité disponible, GKE tente de placer les pods dans l'une des zones CLUSTER_DEFAULT.
    4. Si aucune des zones CLUSTER_DEFAULT ne dispose de capacité disponible, le champ whenUnsatisfiable: ScaleUpAnyway permet à GKE de placer les pods dans n'importe quelle zone disponible de la région.
    5. Si une zone ayant une priorité plus élevée dans la classe de calcul devient disponible ultérieurement, le champ activeMigration.optimizeRulePriority: true permet à GKE de déplacer les pods vers cette zone à partir de zones de priorité inférieure. Cette migration utilise le budget d'interruption de pod pour garantir la disponibilité du service.
  2. Créez la classe de calcul personnalisée :

    kubectl create -f zone-types-custom-compute-class.yaml
    

    GKE crée une classe de calcul personnalisée à laquelle vos charges de travail peuvent faire référence.

  3. Enregistrez le manifeste suivant sous le nom custom-compute-class-deployment.yaml :

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-zonal-preferences
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx-zonal-preferences
      template:
        metadata:
          labels:
            app: nginx-zonal-preferences
        spec:
          nodeSelector: cloud.google.com/compute-class: "zone-types-custom-compute-class"
          containers:
          - name: nginx
            image: nginx:latest
            ports:
            - containerPort: 80
    
  4. Créez le déploiement :

    kubectl create -f custom-compute-class-deployment.yaml
    

Comment la NAP évalue-t-elle zoneTypes ?

Lorsque le provisionnement automatique des nœuds (NAP) détermine s'il faut réutiliser un pool de nœuds existant ou en créer un, il exige généralement une correspondance exacte entre les zones existantes du pool de nœuds et votre zoneTypes demandé. Si vous modifiez une priorité pour inclure des types de zones plus larges (par exemple, en passant de [AI] à [AI, STANDARD]), NAP provisionnera un nouveau pool de nœuds correspondant à la nouvelle forme exacte.

Rognage adapté au type de machine

Si un type de machine (comme h3-standard-88) n'est disponible que dans un sous-ensemble des zones définies par un type (par exemple, uniquement dans us-central1-a), GKE réduit automatiquement la liste des emplacements de pool de nœuds pour n'inclure que les zones où ce matériel est physiquement présent.

Cibler les zones d'IA

Les zones d'IA sont des zones spécialisées utilisées pour les charges de travail d'entraînement et d'inférence d'IA/de ML. Ces zones offrent une capacité d'accélérateur de ML importante. Pour en savoir plus, consultez la documentation sur les zones d'IA.

Avant d'utiliser une zone d'IA dans GKE, tenez compte des caractéristiques suivantes :

  • Les zones d'IA sont physiquement séparées des zones standards pour fournir davantage d'espace de stockage et de puissance. Cette séparation peut entraîner une latence plus élevée, ce qui est généralement tolérable pour les charges de travail d'IA/de ML.
  • Les zones d'IA ont un suffixe avec la notation ai. Par exemple, une zone d'IA dans la région us-central1 est nommée us-central1-ai1a.
  • Actuellement, seules les VM TPU sont acceptées.
  • Le plan de contrôle du cluster s'exécute dans une ou plusieurs zones standards de la même région que la zone d'IA.
  • Vous ne pouvez exécuter des VM sans TPU associés dans une zone d'IA que si vous remplissez les conditions suivantes :

    • Vous exécutez déjà d'autres charges de travail qui utilisent des VM TPU dans la même zone.
    • Les VM non-TPU sont soit des VM Spot, soit liées à une réservation, soit font partie d'un pool de nœuds avec un ratio spécifique entre VM à usage général et VM avec accélérateur.
  • Les zones d'IA partagent des composants, tels que les connexions réseau et les déploiements de logiciels, avec les zones standards qui ont le même suffixe dans la même région. Pour les charges de travail à haute disponibilité, nous vous recommandons d'utiliser différentes zones. Par exemple, évitez d'utiliser à la fois us-central1-ai1a et us-central1-a pour la haute disponibilité.

Par défaut, GKE ne déploie pas vos charges de travail dans les zones d'IA. Pour utiliser une zone d'IA, vous devez configurer l'une des options suivantes :

  • (Recommandé) ComputeClasses : définissez votre priorité la plus élevée pour demander des TPU à la demande dans une zone d'IA. Les ComputeClasses vous aident à définir une liste priorisée de configurations matérielles pour vos charges de travail. Pour obtenir un exemple, consultez À propos de ComputeClasses.
  • Provisionnement automatique des nœuds : utilisez un nodeSelector ou un nodeAffinity dans la spécification de votre pod pour demander au provisionnement automatique des nœuds de créer un pool de nœuds dans la zone d'IA. Si votre charge de travail ne cible pas explicitement une zone d'IA, le provisionnement automatique de nœuds ne tient compte que des zones standards ou des zones de --autoprovisioning-locations lors de la création de pools de nœuds. Cette configuration permet de s'assurer que les charges de travail qui n'exécutent pas de modèles d'IA/ML restent dans les zones standards, sauf si vous configurez explicitement le contraire. Pour obtenir un exemple de fichier manifeste qui utilise un nodeSelector, consultez Définir les zones par défaut pour les nœuds créés automatiquement.
  • GKE Standard : si vous gérez directement vos pools de nœuds, utilisez une zone d'IA dans l'option --node-locations lorsque vous créez un pool de nœuds. Pour obtenir un exemple, consultez Déployer des charges de travail TPU dans GKE Standard.

Vérifier le placement des pods

Pour vérifier le placement des pods, répertoriez les pods et vérifiez les libellés de nœuds. Plusieurs pods peuvent s'exécuter dans un même nœud. Par conséquent, vous ne verrez peut-être pas de pods répartis sur plusieurs zones si vous avez utilisé nodeAffinity.

  1. Affichez la liste des pods :

    kubectl get pods -o wide
    

    Le résultat affiche la liste des pods en cours d'exécution et le nœud GKE correspondant.

  2. Décrivez les nœuds :

    kubectl describe node NODE_NAME | grep "topology.kubernetes.io/zone"
    

    Remplacez NODE_NAME par le nom du nœud.

    Le résultat ressemble à ce qui suit :

    topology.kubernetes.io/zone: us-central1-a
    

Si vous souhaitez que GKE répartisse équitablement vos pods sur plusieurs zones pour améliorer le basculement sur plusieurs domaines de défaillance, utilisez topologySpreadConstraints.

Étapes suivantes