Pod

Cette page décrit l'objet pod de Kubernetes et son utilisation dans Google Kubernetes Engine.

Qu'est-ce qu'un pod ?

Les pods sont les objets déployables qui constituent les plus petits composants essentiels de Kubernetes. Un pod représente une instance unique d'un processus en cours d'exécution dans votre cluster.

Les pods contiennent un ou plusieurs conteneurs tels que des conteneurs Docker. Lorsqu'un pod exécute plusieurs conteneurs, ceux-ci sont gérés comme une seule entité et partagent les ressources du pod. En règle générale, l'exécution de plusieurs conteneurs au sein d'un même pod constitue un cas d'utilisation avancée.

Les pods contiennent également des ressources partagées de stockage et de réseau pour leurs conteneurs :

  • Réseau : les pods reçoivent automatiquement des adresses IP uniques. Les conteneurs d'un pod partagent le même espace de noms réseau, y compris l'adresse IP et les ports réseau. Les conteneurs d'un pod communiquent entre eux à l'intérieur du pod sur localhost.
  • Stockage : les pods peuvent spécifier un ensemble de volumes de stockage partagés pouvant être communs aux différents conteneurs.

Vous pouvez considérer un pod comme un "hôte logique" autonome et isolé, dépositaire des besoins systémiques de l'application qu'il gère.

Un pod est conçu pour exécuter une seule instance de votre application sur votre cluster. Toutefois, il n'est pas recommandé de créer directement des pods individuels. Au lieu de cela, vous créez généralement un ensemble de pods identiques, constituant des instances dupliquées, pour exécuter votre application. Un tel ensemble de pods répliqués est créé et géré par un contrôleur, par exemple un objet Déploiement. Les contrôleurs gèrent le cycle de vie de leurs pods constitutifs et peuvent également gérer le scaling horizontal en modifiant le nombre de pods suivant les besoins.

Même s'il est parfois possible d'interagir directement avec les pods pour les déboguer, les dépanner ou les inspecter, il est vivement recommandé d'utiliser un contrôleur pour gérer les pods.

Les pods s'exécutent sur des nœuds du cluster. Une fois créé, un pod reste sur son nœud jusqu'à la fin de son processus, la suppression du pod, l'éviction du pod par manque de ressources sur le nœud, ou une défaillance du nœud. Dans ce dernier cas, la suppression des pods du nœud défaillant est automatiquement programmée.

Cycle de vie d'un pod

Les pods sont éphémères. Ils ne sont pas conçus pour fonctionner à l'infini et, lorsqu'un pod est arrêté, il ne peut pas être restauré. En général, les pods ne disparaissent pas tant qu'ils ne sont pas supprimés par un utilisateur ou par un contrôleur.

Les pods ne peuvent pas se "corriger" ou se réparer. Ainsi, si un pod est planifié sur un nœud qui subit ultérieurement une défaillance, le pod est supprimé. De même, si un pod est évincé d'un nœud pour une raison quelconque, le pod ne peut pas se remplacer lui-même.

Chaque pod possède un objet d'API PodStatus, qui est représenté par le champ status. Les pods renseignent leur phase dans le champ status: phase. La phase d'un pod est une synthèse brève du pod dans son état actuel.

Lorsque vous utilisez la commande kubectl get pod pour inspecter un pod en cours d'exécution sur un cluster, ce pod peut se trouver dans l'une des phases suivantes :

  • En attente : le pod a été créé et accepté par le cluster, mais un ou plusieurs de ses conteneurs ne sont pas encore actifs. Cette phase comprend le temps passé à planifier le pod sur un nœud et à télécharger des images.
  • En cours d'exécution : le pod a été associé à un nœud et tous les conteneurs ont été créés. Au moins un conteneur est en cours d'exécution, de démarrage ou de redémarrage.
  • Réussite : tous les conteneurs du pod se sont correctement arrêtés. Les pods arrêtés ne redémarrent pas.
  • Échec : tous les conteneurs du pod se sont arrêtés, et au moins un conteneur s'est arrêté sur une défaillance. Un conteneur "échoue" s'il s'arrête dans un état différent de zéro.
  • Inconnu : l'état du pod ne peut pas être déterminé.

De plus, PodStatus contient un tableau appelé PodConditions, représenté dans le fichier manifeste du pod sous l'intitulé conditions. Ce champ est assorti de champs type et status. conditions indique plus précisément les conditions au sein du pod qui sont à l'origine de son état actuel.

Le champ type peut contenir les valeurs PodScheduled (planifié), Ready (prêt), Initialized (initialisé) et Unschedulable (planification impossible). Le champ status correspond au champ type et peut contenir les valeurs True (vrai), False (faux) ou Unknown (inconnu).

Créer des pods

Les pods étant éphémères, il n'est pas nécessaire de les créer directement. De même, puisque les pods ne peuvent ni se réparer ni se remplacer, il n'est pas recommandé de créer des pods directement.

À la place, vous pouvez utiliser un contrôleur tel qu'un objet Déploiement, qui crée et gère les pods pour vous. Les contrôleurs sont également utiles pour déployer des mises à jour, par exemple pour changer la version d'une application s'exécutant dans un conteneur, car le contrôleur gère l'intégralité du processus de mise à jour.

Requêtes des pod

Lorsqu'un pod démarre, il demande une quantité de processeurs et de mémoire. Cela permet à Kubernetes de planifier le pod sur un nœud approprié afin d'exécuter la charge de travail. Un pod ne sera pas programmé sur un nœud qui ne dispose pas des ressources nécessaires pour répondre à la requête du pod. Une requête correspond à la quantité minimale de processeurs ou de mémoire garantie par Kubernetes à un pod.

Vous pouvez configurer les requêtes de processeurs et de mémoire pour un pod, en fonction des ressources dont vos applications ont besoin. Vous pouvez également spécifier les requêtes pour les conteneurs individuels qui s'exécutent dans le pod. Tenez bien compte des éléments suivants :

  • La requête de processeurs par défaut est de 100 millions. Ce nombre est trop faible pour de nombreuses applications. En outre, il est probablement bien plus faible que la quantité de processeurs disponible sur le nœud.
  • Il n'existe pas de requête de mémoire par défaut. Un pod sans requête de mémoire par défaut peut être planifié sur un nœud ne disposant pas d'une quantité de mémoire suffisante pour exécuter les charges de travail du pod.
  • Si vous définissez une valeur trop faible pour les requêtes de processeurs ou de mémoire, un nombre trop élevé de pods ou une combinaison sous-optimale de pods sont planifiés sur un nœud donné, ce qui entraîne une baisse de performance.
  • Si vous définissez une valeur trop élevée pour les requêtes de processeurs ou de mémoire, le pod risque de devenir non planifiable et d'augmenter le coût des ressources du cluster.
  • En plus ou au lieu de définir les ressources d'un pod, vous pouvez spécifier des ressources pour les conteneurs individuels qui s'exécutent dans le pod. Si vous ne spécifiez que des ressources pour les conteneurs, les requêtes du pod correspondent à la somme des requêtes spécifiées pour les conteneurs. Si vous exécutez ces deux méthodes, la somme des requêtes pour tous les conteneurs ne doit pas dépasser les requêtes du pod.

Il est fortement recommandé de configurer des requêtes pour vos Pods, en fonction des exigences des charges de travail réelles. Pour en savoir plus, consultez l'article Bonnes pratiques Kubernetes : demandes de ressources et limites dans le blog Google Cloud.

Limites des pods

Par défaut, la limite d'un pod est inférieure à la quantité maximale de processeurs ou de mémoire qu'il peut utiliser sur un nœud. Vous pouvez définir des limites pour contrôler la quantité de processeurs ou de mémoire que votre Pod peut utiliser sur un nœud. Une limite correspond à la quantité maximale de processeurs ou de mémoire garantie par Kubernetes à un pod.

En plus ou au lieu de définir les limites d'un pod, vous pouvez spécifier des limites pour les conteneurs individuels qui s'exécutent dans le pod. Si vous ne spécifiez que des limites pour les conteneurs, les limites du pod correspondent à la somme des limites spécifiées pour les conteneurs. Toutefois, chaque conteneur est limité dans son accès aux ressources. Par conséquent, si vous décidez de ne spécifier des limites que sur les conteneurs, vous devez spécifier des limites pour chacun d'entre eux. Si vous spécifiez les deux, la somme des limites pour tous les conteneurs ne doit pas dépasser la limite du pod.

Les limites ne sont pas prises en compte lors de la planification des pods. Toutefois, elles peuvent empêcher les conflits de ressources entre les pods d'un même nœud. Elles peuvent également éviter qu'un pod ne provoque une instabilité du système sur le nœud en privant de ressources le système d'exploitation sous-jacent.

Il est fortement recommandé de configurer des limites pour vos Pods, en fonction des exigences des charges de travail réelles. Pour plus d'informations, reportez-vous à l'article Bonnes pratiques Kubernetes : requêtes et limites de ressources sur le blog Google Cloud.

Modèles de pod

Les objets contrôleurs tels que les Déploiements et les StatefulSets contiennent un champ de modèle de pod. Les modèles de pod contiennent une spécification de pod qui détermine le mode d'exécution de chaque pod, en particulier les conteneurs à exécuter dans les pods et les volumes que les pods doivent installer.

Les objets contrôleurs utilisent des modèles de pods pour créer des pods et gérer leur "état souhaité" dans votre cluster. Lorsqu'un modèle de pod est modifié, tous les pods ultérieurs reflètent le nouveau modèle, mais ce n'est pas le cas de tous les pods existants.

Pour en savoir plus sur le fonctionnement des modèles de pods, consultez la page Creating a Deployment (Créer un objet Déploiement) dans la documentation de Kubernetes.

Contrôler les nœuds sur lesquels un pod s'exécute

D'office, les pods s'exécutent sur des nœuds du pool de nœuds par défaut du cluster. Vous pouvez configurer explicitement ou implicitement le pool de nœuds sélectionné par un pod :

  • Il est possible de forcer explicitement un pod à se déployer sur un pool de nœuds spécifique en définissant un sélecteur de nœuds dans le fichier manifeste du pod. Cela oblige un pod à ne s'exécuter que sur les nœuds de ce pool de nœuds.

  • Vous pouvez spécifier des requêtes de ressources pour les conteneurs que vous exécutez. Le pod ne s'exécutera que sur des nœuds qui répondent aux requêtes de ressources. Par exemple, si la définition de pod inclut un conteneur qui nécessite quatre processeurs, le service ne sélectionnera pas les pods s'exécutant sur des nœuds avec deux processeurs.

Schémas d'utilisation des pods

Les pods peuvent être utilisés principalement de deux manières :

  • Les pods qui exécutent un seul conteneur. Le modèle de pod le plus simple et le plus courant est constitué d'un conteneur unique par pod, le conteneur unique représentant une application entière. Dans ce cas, vous pouvez considérer le pod comme un wrapper.
  • Les pods qui exécutent plusieurs conteneurs devant fonctionner conjointement. Les pods avec plusieurs conteneurs servent principalement pour des programmes en colocation et cogérés qui doivent partager des ressources. Ces conteneurs en colocation peuvent former une seule unité de service cohérente : un conteneur diffuse des fichiers à partir d'un volume partagé, tandis qu'un autre conteneur actualise ou met à jour ces fichiers. Le pod encapsule ces conteneurs et ressources de stockage en une seule entité de gestion.

Chaque pod est destiné à exécuter une instance unique d'une application donnée. Si vous souhaitez exécuter plusieurs instances, vous devez utiliser un pod pour chaque instance de l'application. Ceci est généralement désigné par le terme réplication. Les pods répliqués sont créés et gérés en tant que groupe par un contrôleur tel qu'un Déploiement.

Arrêter un pod

Les pods s'arrêtent normalement lorsque leurs processus sont terminés. Kubernetes impose par défaut un délai de grâce de 30 secondes. Lorsque vous supprimez un pod, vous pouvez remplacer ce délai de grâce en définissant l'option --grace-period sur le temps d'attente souhaité (exprimé en secondes) avant l'arrêt forcé du pod.

Étapes suivantes