Les bases de kubernetes : Pods, Nodes, Containers, Deployments et Clusters
Kubernetes a clairement remporté la guerre de l’orchestration de conteneurs. Initialement conçu pour exécuter des applications stateless, il est aujourd’hui largement utilisé dans de nombreux domaines, notamment le cloud computing, l’ingénierie des données et le machine learning.
En data science, Kubernetes est couramment utilisé pour créer des pipelines ETL (Extract, Transform, Load) permettant d’extraire, transformer et charger des données à l’aide de frameworks tels que Apache Spark, Apache Flink ou Apache Airflow. Il joue également un rôle clé dans l’entraînement et le déploiement de modèles de machine learning, grâce à des projets open source comme Kubeflow.
Que vous soyez développeur, ingénieur DevOps ou data scientist, il est désormais indispensable de maîtriser au moins les bases du fonctionnement de Kubernetes.
Dans cette vidéo, nous aborderons les concepts fondamentaux de Kubernetes, notamment les pods, les nœuds, les conteneurs, les déploiements et les clusters. Nous verrons également les notions d’ingress et de load balancer, essentielles pour exposer des applications et gérer le trafic dans une infrastructure cloud moderne.
Node Kubernetes
Commençons par le nœud (node), qui représente la plus petite unité de calcul dans un cluster Kubernetes. Un nœud correspond à une machine sur laquelle s’exécutent vos applications. Il peut s’agir d’un serveur physique hébergé dans un data center, ou d’une machine virtuelle déployée dans un cloud public comme AWS ou Microsoft Azure. Il est même possible de construire un cluster Kubernetes à partir de plusieurs Raspberry Pi.
Considérer une machine comme un nœud permet d’introduire un niveau d’abstraction. Vous n’avez alors plus besoin de vous soucier des caractéristiques spécifiques de chaque serveur, comme la quantité de CPU ou de mémoire RAM disponible. Kubernetes se charge de décider où déployer vos services en fonction des ressources et des spécifications que vous définissez. En cas de défaillance d’un nœud, celui-ci peut être facilement remplacé, et Kubernetes se charge automatiquement de redistribuer la charge de travail.
Même s’il peut parfois être utile de travailler avec des serveurs individuels, ce n’est pas l’approche recommandée avec Kubernetes. En règle générale, ni vous ni vos applications ne devriez avoir à vous préoccuper de l’endroit précis où elles s’exécutent.
Les nœuds sont généralement regroupés au sein de node pools (ou groupes de nœuds). Lors du déploiement d’une application, Kubernetes analyse chaque nœud disponible et en sélectionne un en fonction de critères tels que la capacité CPU et la mémoire disponible. Si ce nœud devient indisponible, Kubernetes s’assure que l’application est automatiquement déplacée et reste opérationnelle, garantissant ainsi une haute disponibilité.
Il est possible de définir plusieurs groupes de nœuds au sein d’un même cluster Kubernetes, parfois appelés instance groups ou node pools. Par exemple, vous pouvez disposer d’un groupe de nœuds avec une forte puissance de calcul mais peu de mémoire pour des charges de travail intensives en calcul, et d’un autre groupe offrant beaucoup de mémoire mais moins de CPU.
Dans le contexte du cloud computing, il est courant de distinguer deux types de node pools :
- les nœuds à la demande (on-demand), disponibles en permanence,
- les nœuds spot, moins coûteux mais susceptibles d’être interrompus à tout moment.
Étant donné que les applications exécutées dans Kubernetes ne sont pas garanties de fonctionner en permanence sur le même nœud, elles doivent être conçues pour être portables, résilientes et tolérantes aux pannes.
Volumes persistants Kubernetes (Persistent Volumes)
Dans Kubernetes, il n’est pas possible d’utiliser le disque local d’un nœud pour stocker des données de manière persistante. Si une application enregistre des données sur le disque local et qu’elle est ensuite déplacée vers un autre nœud du cluster, ces données ne seront plus disponibles. C’est pourquoi le stockage local ne doit être utilisé que pour des usages temporaires, comme le cache.
Pour assurer la persistance des données, Kubernetes s’appuie sur un mécanisme appelé Persistent Volumes (PV). Contrairement aux ressources CPU et mémoire, qui sont mutualisées et gérées directement par le cluster Kubernetes, le stockage persistant ne l’est pas automatiquement.
Les Persistent Volumes permettent d’attacher des espaces de stockage locaux ou des volumes cloud au cluster Kubernetes. Il peut s’agir, par exemple, de disques fournis par des services de stockage cloud comme AWS EBS, Azure Disk ou Google Persistent Disk, mais aussi de solutions on-premise. On peut les comparer à un disque dur externe connecté au cluster.
Un Persistent Volume fournit un système de fichiers qui peut être monté par les applications du cluster, sans être lié à un nœud spécifique. Cela permet aux applications de conserver leurs données même lorsqu’elles sont redéployées, déplacées ou redémarrées sur un autre nœud, garantissant ainsi la résilience et la continuité de service.
Pour exécuter une application sur un cluster Kubernetes, celle-ci doit être packagée sous forme de conteneur Linux, généralement à l’aide de technologies comme Docker.
Conteneurs Kubernetes
Un conteneur est une unité d’exécution légère qui permet de créer des environnements Linux isolés et autonomes. La conteneurisation permet d’embarquer une application ainsi que l’ensemble de ses dépendances dans une image unique, facilement distribuable et déployable.
Une image de conteneur peut être téléchargée et exécutée sur n’importe quelle infrastructure, qu’elle soit on-premise ou hébergée dans un cloud public comme AWS, Azure ou Google Cloud, avec un minimum de configuration. Cela garantit une portabilité et une cohérence des environnements entre le développement, les tests et la production.
La création d’images Docker fait généralement partie d’un pipeline CI/CD. Le processus classique consiste à cloner le dépôt de code, exécuter des tests unitaires, puis construire l’image du conteneur avant son déploiement automatisé sur un cluster Kubernetes.
Même s’il est techniquement possible d’exécuter plusieurs applications dans un seul conteneur, il est recommandé d’adopter le principe un processus par conteneur. Il est préférable de disposer de plusieurs petits conteneurs spécialisés plutôt qu’un seul conteneur volumineux.
Des conteneurs ayant un périmètre fonctionnel réduit facilitent les mises à jour, améliorent la maintenabilité et rendent les problèmes plus simples à diagnostiquer. Cette approche s’inscrit pleinement dans les bonnes pratiques des architectures cloud natives et des microservices.
Pods Kubernetes
Kubernetes n’exécute pas directement les conteneurs. À la place, il les regroupe au sein d’une structure de plus haut niveau appelée pod. Un pod peut contenir un ou plusieurs conteneurs, qui partagent les mêmes ressources système ainsi que le même réseau local.
Les conteneurs appartenant à un même pod peuvent communiquer entre eux comme s’ils s’exécutaient sur une seule et même machine, tout en conservant un certain niveau d’isolation vis-à-vis des autres pods du cluster.
Les pods constituent l’unité de réplication dans Kubernetes. Lorsqu’une application doit monter en charge, il suffit d’augmenter le nombre de pods. Kubernetes peut être configuré pour ajuster automatiquement cette mise à l’échelle grâce à des mécanismes d’auto-scaling, en se basant sur des métriques telles que l’utilisation du CPU, de la mémoire, ou encore des métriques personnalisées comme le nombre de requêtes traitées par l’application.
En pratique, plusieurs instances d’une même application sont généralement exécutées en parallèle afin de garantir une haute disponibilité et d’éviter toute interruption de service en cas de défaillance d’un nœud.
Un conteneur pouvant exécuter plusieurs processus, un pod peut donc héberger plusieurs conteneurs. Cependant, comme les pods sont scalés en tant qu’unité, tous les conteneurs qu’ils contiennent sont mis à l’échelle simultanément, quels que soient leurs besoins individuels. Cela peut entraîner une surconsommation de ressources et une augmentation des coûts d’infrastructure.
Pour éviter cela, il est recommandé de concevoir des pods aussi petits que possible. Dans la majorité des cas, un pod contient un processus principal, accompagné éventuellement de conteneurs auxiliaires étroitement liés, appelés sidecars (par exemple pour la journalisation, la sécurité ou la collecte de métriques).
Déploiements Kubernetes (Deployments)
Les pods constituent l’unité de base d’exécution dans Kubernetes, mais ils ne sont généralement pas créés directement dans le cluster. Kubernetes propose un niveau d’abstraction supplémentaire appelé Deployment, qui facilite la gestion et l’exploitation des applications.
Le rôle principal d’un Deployment Kubernetes est de définir le nombre de réplicas d’un pod devant être exécutés à un instant donné. Lorsqu’un deployment est créé dans le cluster, Kubernetes lance automatiquement le nombre de pods requis et en assure la surveillance continue.
Si un pod tombe en panne ou devient indisponible, le deployment se charge de le recréer automatiquement, garantissant ainsi la résilience et la disponibilité de l’application.
Grâce aux deployments, il n’est plus nécessaire de gérer les pods manuellement. Il suffit de déclarer l’état souhaité du système (par exemple le nombre de réplicas ou la version de l’application) et Kubernetes se charge d’appliquer et de maintenir cet état de manière automatisée.
Les deployments permettent également de réaliser des mises à jour progressives (rolling updates) et des retours en arrière (rollbacks), ce qui en fait un composant clé des pipelines CI/CD et des architectures cloud natives.
Load Balancer et Ingress Kubernetes
Jusqu’à présent, nous avons exploré les principaux composants de Kubernetes. Grâce aux deployments, nous savons désormais comment exécuter une application au sein d’un cluster Kubernetes. Mais une question essentielle se pose : comment exposer une application Kubernetes sur Internet ?
Par défaut, Kubernetes assure une isolation réseau entre les pods et le monde extérieur. Pour permettre la communication avec un service exécuté dans un pod, il est nécessaire d’ouvrir un canal de communication approprié. Kubernetes propose plusieurs mécanismes pour exposer des services.
Service de type Load Balancer
Si vous souhaitez exposer une application directement, vous pouvez utiliser un service de type Load Balancer. Dans ce cas, chaque application est associée à son propre load balancer, généralement fourni par le cloud provider (AWS, Azure, Google Cloud).
Ce type de service permet l’utilisation de nombreux protocoles, tels que TCP, UDP, gRPC ou WebSockets, ce qui le rend très flexible pour différents types d’applications.
Ingress et Ingress Controller
Une autre approche très répandue consiste à utiliser un Ingress Controller. Il existe de nombreuses implémentations d’ingress pour Kubernetes, chacune offrant des fonctionnalités spécifiques (gestion du trafic, sécurité, règles de routage, etc.).
Avec un ingress controller, un seul load balancer est partagé entre plusieurs services. Le routage du trafic s’effectue à l’aide de sous-domaines ou de chemins d’URL, permettant de diriger les requêtes vers l’application appropriée au sein du cluster.
Les Ingress prennent uniquement en charge les protocoles HTTP et HTTPS. Ils sont généralement plus complexes à configurer et à maintenir que les services de type Load Balancer, mais offrent une meilleure mutualisation des ressources et une plus grande flexibilité pour les architectures web.
Si vous souhaitez approfondir les différences entre NodePort, Load Balancer et Ingress, un article dédiée est disponible.
Si vous souhaitez mettre en place kubernetes pour vos projet. On peut vous aider à bien le mettre en place pour qu'une amélioration ne devienne pas une régression et ajoute de la friction dans le déploiement de vos projet.