Introduction à Kubernetes
Mise à jour :
Bienvenue dans ce guide détaillé sur Kubernetes. Kubernetes, souvent abrégé en K8s, est un système open-source de gestion de conteneurs qui a révolutionné le monde de l’orchestration des conteneurs. En tant qu’administrateur système ou professionnel du DevOps, comprendre les fondamentaux de Kubernetes est essentiel pour gérer efficacement les applications conteneurisées à grande échelle.
Ce guide est conçu pour vous offrir une compréhension claire et complète des principaux concepts de Kubernetes, de son historique à son architecture en passant par ses fonctionnalités. Nous explorerons comment Kubernetes permet de déployer, gérer et scaler des applications conteneurisées de manière automatisée et résiliente.
Cette première section permet de définir tous les concepts et objets principaux utilisés sur un cluster Kubernetes.
Prérequis
Vous devez posséder au préalable des connaissances sur les conteneurs avant de vous attaquer à Kubernetes. Si certains mots ne sont pas clairs pour vous, vous pouvez aller faire un tour sur mon lexique Devops.
Introduction
Kubernetes, k8s, est un système Open Source qui exécute et coordonne des applications conteneurisées dans des clusters. Kubernetes gère le cycle complet de vie des applications et des services permettant ainsi de limiter le nombre de processus nécessaire au déploiement et à la mise à l’échelle des applications conteneurisées.
Historique de Kubernetes
Avant de plonger dans l’histoire de Kubernetes, il est important de comprendre l’évolution de la conteneurisation. Les conteneurs, en tant que technologie, permettent d’exécuter des applications de manière isolée sur un même système d’exploitation, offrant ainsi une meilleure utilisation des ressources et une portabilité accrue. La popularité des conteneurs a considérablement augmenté avec l’arrivée de Docker en 2013, qui a simplifié la création, le déploiement et l’exécution des conteneurs.
Kubernetes a été développé initialement par Google, basé sur leur vaste expérience en gestion de conteneurs à grande échelle à travers leur système interne appelé Borg. Google utilisait Borg pour déployer et gérer des milliers d’applications dans leurs data centers, assurant ainsi une haute disponibilité et une gestion efficace des ressources.
En 2014, Google a décidé de partager cette technologie sous la forme d’un projet open-source : Kubernetes. Ce projet a été annoncé lors de la conférence DockerCon de cette même année, marquant le début d’une nouvelle ère pour l’orchestration des conteneurs.
En 2015, Kubernetes a été transféré sous l’égide de la Cloud Native Computing Foundation (CNCF), une fondation dédiée à la promotion de technologies cloud-native. La CNCF a fourni un cadre de gouvernance et un soutien communautaire qui ont permis à Kubernetes de croître rapidement et d’adopter une adoption massive par l’industrie.
Depuis son lancement, Kubernetes a évolué rapidement grâce à une communauté active et une forte adoption par des entreprises de toutes tailles. Les contributions de divers acteurs de l’industrie, y compris des géants de la technologie comme IBM, Microsoft, Red Hat et d’autres, ont enrichi le projet en ajoutant des fonctionnalités avancées et en améliorant sa stabilité et sa performance.
Kubernetes est devenu le standard de facto pour l’orchestration des conteneurs, en partie grâce à ses fonctionnalités robustes comme le déploiement automatique, la mise à l’échelle automatique et la gestion de la résilience. Les entreprises l’utilisent pour gérer des applications critiques en production, profiter de la portabilité entre les environnements cloud et on-premise et améliorer l’efficacité opérationnelle.
L’impact de Kubernetes sur l’industrie de l’informatique est indéniable. Il a non seulement standardisé la gestion des conteneurs, mais a aussi facilité l’adoption de pratiques DevOps et de méthodologies cloud-native. Kubernetes a également inspiré le développement de nombreux projets complémentaires, comme Helm (gestionnaire de packages pour Kubernetes), Istio (maillage de services) et bien d’autres.
Voici le texte avec les mots-clés liés :
Fonctionnalités de Kubernetes
Kubernetes propose un large éventail de fonctionnalités pour gérer, déployer et faire évoluer les applications conteneurisées. Ces capacités sont pensées pour répondre aux besoins des environnements de production avec flexibilité et résilience.
-
Orchestration automatique : Kubernetes orchestre les conteneurs en gérant leur cycle de vie et en redémarrant automatiquement les applications en cas de défaillance.
-
Scalabilité dynamique : Kubernetes ajuste dynamiquement le nombre de réplicas des Pods selon la demande et les métriques de performance.
-
Gestion des défaillances : En surveillant constamment l’état des nœuds et des Pods, Kubernetes redémarre les conteneurs défaillants, rééquilibre les charges de travail et relocalise les Pods sur des nœuds fonctionnels.
-
Déploiements continus : Les déploiements progressifs avec Rolling Updates et les rollbacks automatiques permettent des mises à jour sans interruption de service. Voici un exemple de déploiement avec mise à jour continue :
-
Découverte et équilibrage de charge : Kubernetes gère la découverte des services et l’équilibrage de charge en attribuant des adresses IP stables et des noms DNS aux Pods, facilitant la communication entre les composants d’une application.
-
Gestion des configurations et secrets : Avec ConfigMaps ↗ et Secrets, Kubernetes permet de gérer séparément les informations de configuration et les données sensibles sans les intégrer au code de l’application.
-
Surveillance et journalisation : Kubernetes propose des outils intégrés pour surveiller les applications et enregistrer les logs. Des solutions comme Prometheus pour les métriques et Elasticsearch pour les journaux offrent des capacités avancées pour optimiser les performances et diagnostiquer les problèmes.
-
Réseau et sécurité : La gestion du réseau et de la sécurité se fait via les Network Policies, qui contrôlent les règles de communication entre les Pods, et via le Role-Based Access Control (RBAC), qui gère les permissions et l’accès aux ressources du cluster.
-
Extensions et opérateurs : Grâce aux Custom Resource Definitions (CRDs) et aux opérateurs, Kubernetes est hautement extensible. Les CRDs permettent d’ajouter de nouveaux types d’objets, tandis que les opérateurs automatisent la gestion des applications complexes.
-
Langage déclaratif : Kubernetes utilise un langage déclaratif basé sur YAML, permettant de décrire l’état souhaité des objets. Ce modèle simplifie la gestion et l’automatisation des configurations.
Architecture de Kubernetes
L’architecture de Kubernetes est conçue pour offrir une gestion efficace et flexible des conteneurs déployés dans un cluster. Elle repose sur une approche modulaire qui sépare les responsabilités entre plusieurs composants qui sont les noeuds maîtres (masters) et les nœuds de travail (workers). Voici une vue d’ensemble des principaux composants de l’architecture Kubernetes, en mettant l’accent sur les rôles des nœuds maîtres et des nœuds de travail.
Le Control Plane
Dans le graphique ci-dessus, nous voyons que le Control Plane Kubernetes est composé de plusieurs éléments. Chacun de ces éléments sont essentiels à la bonne santé d’un cluster Kubernetes. Si un de ces composants vient à dysfonctionner le cluster devient instable voir irrécupérable (etcd par exemple).
ETCD
ETCD est une base de données distribuée de type clé-valeur, qui a été développée en “Go”, le langage de programmation de Google. Dans un cluster Kubernetes, ETCD est chargé de stocker la configuration et les informations nécessaires au fonctionnement du cluster, c’est-à-dire de tous ses composants : les nœuds, les pods, les configs, les secrets, les rôles, les comptes etc.
L’API-Server
L’API Server est le composant central du cluster qui expose l’API REST
de Kubernetes. C’est donc l’élément “frontal” du Control Plane de
Kubernetes et c’est lui qui reçoit tous les appels et demandes, externes ou
internes. C’est ce composant qui gère entre autre les appels via les commandes
kubectl
. Il est donc chargé :
- De gérer les authentifications,
- De valider les demandes reçues,
- De gérer les données stockées dans la base de données ETCD,
- De fournir les informations aux autres composants du cluster : kubelet, scheduller, …
Le Scheduler
Le scheduler est chargé de la répartition des pods entre les différents workers nodes. Cette répartition se fait en fonction des ressources disponibles et des contraintes qui lui sont indiquées. Ces contraintes peuvent être des prérequis de type CPU et mémoire, des contraintes hardware, des affinités et anti-affinités.
Les nœuds sont filtrés en supprimant ceux qui ne répondent pas aux exigences du pod. Ensuite, les nœuds retenus sont classés par score, celui ayant obtenu le score le plus élevé est sélectionné.
Le scheduler indique au service kubelet du worker node sélectionné qu’il doit démarrer le pod.
Le Controller-Manager
Dans Kubernetes, le Controller Manager contient plusieurs controllers. Un controller est une boucle de contrôle qui surveille en permanence l’état d’un groupe d’objet qui lui est attribué. Il fera des demandes de modifications au serveur d’API, ou en direct si nécessaire, pour que l’état actuel de ses objets soit celui de l’état souhaité.
Parmi ces contrôleurs, on retrouve :
- Deployment controller
- StatefulSet controller
- Node controller
- Service controller
- Endpoints controller
- Namespace controller
- PersistentVolume controller
- …
La description de ces objets est faite plus bas dans ce billet.
Cloud-Controller-Manager (optionnel)
Kubernetes peut fonctionner sur des clouds publics, privés et hybrides. Le Cloud-Controller-Manager permet de lier votre cluster à l’API de votre fournisseur de cloud. Il permet donc aux fournisseurs de cloud de publier des fonctionnalités à un rythme différent de celui du projet Kubernetes.
Composants des nœuds (workers)
kubelet
Kubelet est un agent qui tourne sur tous les worker nodes du cluster Kubernetes. Kubelet examine les spécifications qui lui sont transmises par le scheduller et fait en sorte que les conteneurs définis avec ces spécifications tournent et soient en bonne santé.
kube-proxy
kube-proxy est un proxy réseau qui s’exécute sur chaque worker node du cluster et gère les règles réseau. Ces règles réseau permettent une communication réseau vers les Pods depuis des sessions réseau à l’intérieur ou à l’extérieur du cluster. kube-proxy utilise la couche de filtrage de paquets du système d’exploitation hôte s’il y en a une de disponible. Sinon, kube-proxy transmet le trafic lui-même.
Container Runtime
L’environnement d’exécution de conteneurs (Container Runtime) est le logiciel responsable de l’exécution des conteneurs. Le CRI est une interface de plug-in qui permet à kubelet d’utiliser différents environnements d’exécution de conteneurs, sans à avoir besoin de recompiler les composants du cluster. Kubernetes est compatible avec : Docker, ContainerD, cri-o, rktlet entre autre.
Rôle des nœuds maîtres et des nœuds de travail
Rôle des nœuds maîtres (masters)
Les nœuds maîtres sont le cœur de la gestion du cluster Kubernetes. Ils orchestrent les différentes opérations nécessaires pour maintenir l’état désiré du cluster. Les composants maîtres travaillent ensemble pour :
- Coordonner les activités du cluster : Le maître reçoit les commandes des utilisateurs via l’API Server et les distribue aux nœuds de travail.
- Maintenir l’état du cluster : Grâce à etcd, le maître conserve une vue cohérente et actuelle de l’état du cluster.
- Planifier les charges de travail : Le Scheduler assigne les Pods aux nœuds de travail en fonction de la disponibilité des ressources et des contraintes de déploiement.
- Gérer les contrôleurs : Le Controller Manager s’assure que l’état réel des objets Kubernetes correspond à l’état désiré défini par l’utilisateur.
Rôle des nœuds de travail (workers)
Les nœuds de travail, ou workers, sont responsables de l’exécution des conteneurs applicatifs. Les principales responsabilités des nœuds de travail incluent :
- Exécuter les conteneurs : Le Kubelet sur chaque nœud s’assure que les conteneurs sont exécutés comme spécifié dans les configurations des Pods.
- Gérer le réseau : Kube-proxy configure les règles réseau pour permettre une communication stable et sécurisée entre les services et les Pods.
- Rapporter l’état : Les nœuds de travail envoient des mises à jour régulières sur l’état des Pods au maître pour assurer une gestion précise et réactive du cluster.
Les ressources Kubernetes
Ressources de base
NameSpaces
Dans Kubernetes, les namespaces ou espaces de noms fournissent un mécanisme pour isoler des groupes de ressources au sein d’un seul cluster. Les noms de ressources doivent être uniques au sein d’un même namespace, mais pas entre namespaces. La portée basée sur un namespace s’applique uniquement aux objets avec namespace (par exemple, déploiements, services etc.) et non aux objets à l’échelle du cluster (par exemple, StorageClass, Nodes, PersistentVolumes etc.)
Il n’est pas nécessaire d’utiliser plusieurs namespaces pour séparer des ressources légèrement différentes, telles que des versions différentes de la même application : utilisez plutôt les labels (étiquettes) pour distinguer les ressources au sein du même namespace.
Pods
Les pods sont les plus petites unités déployables que vous pouvez créer et gérer dans Kubernetes. Un Pod est un groupe d’un ou plusieurs conteneurs partageant des ressources réseau, de stockage et d’un ensemble d’espaces de noms qui s’exécutent sur les workers.
Un pod peut aussi contenir des conteneurs d’initialisation qui s’exécutent lors du démarrage de celui-ci.
Vous créerez rarement des pods directement dans Kubernetes! Vous les instancierez à l’aide de ressources de charge de travail telles que les déployments, les daemonsets ou les statefulets.
Services
Comme les pods sont des objets non permanents comment y accéder si leur IP changent ? C’est à ce niveau qu’interviennent les Services. Un service est une couche d’abstraction qui définit des règles permettant d’accéder à un ensemble logique de pods. Un Service permet donc aux pods de recevoir du trafic.
Pour cibler des pods un service va utiliser ce qu’on appelle un selector, qui va rechercher dans le cluster des objets possédant des paires clé/valeurs correspondantes à celles attendues.
Il existe différentes manières d’exposer un service :
- ClusterIP (par défaut) : expose le Service sur une adresse IP interne au cluster
- NodePort : expose le Service sur un port statique du node
- Loadbalancer : expose le Service à l’extérieur en utilisant l’équilibreur de charge d’un fournisseur de cloud computing
- ExternalName : Mappe le service à un nom externe (exemple : artefacts.robert.local)
Volumes
Par défaut les fichiers d’un pod sont éphémères, lorsqu’un conteneur plante, kubelet va le redémarrer, mais les fichiers du pod précédent sont perdus.
Pour ajouter de la persistance de données dans kubernetes, il est possible d’utiliser des volumes. Kubernetes prend en charge plusieurs types de stockage dont les principaux sont : hostPath, emptyDir, configMap, nfs, secret, local, PersistentVolumeClaim, … La liste complète se trouve ici ↗
Les volumes permettent également de partager des fichiers entre conteneurs.
Les Workloads
Un workload (charge de travail) est une application fonctionnant sur Kubernetes faisant appel à un ou à une série de pods. Un workload Kubernetes permet d’automatiser le processus de publication d’une application et de la rendre ainsi reproductible. Tout est géré par le back-end de Kubernetes sans intervention de votre part, sauf bien sûr sa déclaration.
Nous ne verrons ici les ressources standards de Kubernetes, mais il est possible d’en ajouter de nouveaux via ce qu’on appelle un CustomResourceDefinition (CRD).
Déployments
Un déploiement permet de décrire le cycle de vie d’une application sans état, en spécifiant en autre les images à utiliser, la façon dont les pods doivent être mis à jour ou mis à l’échelle (scaling)
StatefulSet
Contrairement à un déployment, un StatefulSet conserve une identité persistante
pour chacun de ses pods. Les pods d’un StatefulSet sont créés
à partir de la même spécification, mais ne sont pas interchangeables : chacun a
un identifiant persistant qu’il conserve lors de toute reconstruction.
Par exemple si vous souhaitez utiliser des volumes de stockage pour assurer la persistance de vos données, un StatefulSet peut être la solution surtout si les volumes sont spécifiques à chaque pod.
DaemonSet
Le DaemonSet est utilisé pour le déploiement, comme son nom l’indique d’un daemon. Il va lancer une instance unique de pod sur chacun des workers nodes du cluster Kubernetes. En cas d’ajout d’un worker node, le controle plane de Kubernetes va programmer l’ajout d’un Pod pour ce DaemonSet sur ce nouveau noeud.
On l’utilise le plus souvent pour gérer du stockage, du monitoring ou de la journalisation de log.
Jobs et CronJobs
Les Jobs permettent d’exécuter des tâches ponctuelles voir des batchs plus complets. CronJob, en analogie avec les crons linux, permet de planifier à quels moments (minute, heure, jour du mois, mois et jour de la semaine) ces tâches doivent s’exécuter.
Extensions de Kubernetes
Kubernetes est hautement configurable et extensible via des plugins sur une grande partie des composants du cluster. Il est donc possible d’étendre au niveau de l’infrastructure du cluster :
- Les ressources de type réseau ↗
- Les ressources de type volume ↗
- D’intégrer de nouveaux devices ↗
- D’intégrer, voir de remplacer le scheduller par un autre.
Un autre moyen d’étendre les fonctionnalités d’un cluster Kubernetes est d’ajouter des points d’entrée à l’API. Cela permet d’intégrer des nouvelles méthodes d’authentification, d’autorisations et de contrôle d’admission.
Déployer un cluster Kubernetes
Maintenant que nous avons mis en place tous ces concepts passons à
l’installation d’un cluster Kubernetes. Je vous propose de suivre ce
tutoriel montrant comment l’installer avec kubeadm
sur des VM provisionnées
avec vagrant. Ou si vous
êtes à court de ressources matérielles avec
kind.
Plus d’informations
Comme dit en au début du billet, ce billet fait partie d’une série. Je vous invite donc à revenir de temps en temps, car je risque de le compléter comme je l’ai déjà fait avec Ansible. Parmi les sujets prévus : la création d’applications, les bonnes pratiques, une aide à la résolution d’incident, une sélection d’outils etc.
Voici la liste des billets existants (certains sont en cours de réécriture, Eh oui, je progresse et les outils évoluent également) :
- Kubernetes - Ecrire ses premiers manifests Kubernetes
- Kubernetes - Progresser dans l’écriture des manifests avec Kube-Score
- Kubernetes - Le contrôle d’accès basé sur les rôles (RBAC) - Partie 1
- Kubernetes - Administrer des clusters ETCD
- Kubernetes - Les sidecars
- Kubernetes - Utiliser des références d’images immutables
- Helm le gestionnaire d’applications pour cluster Kubernetes
- Kubernetes - Ecrire son premier chart Helm
- Ytt une alternative à Helm
- Kapp le gestionnaire d’applications
- Kapp-controller - les packages kapp versionnés
- Kubernetes - Superviser l’utilisation des ressources d’un Cluster avec Metrics Server
- Kubernetes - vendir un outil bien pratique pour constituer des packages
- Kubernetes - Installation d’un cluster sur Windows
- Pourquoi K3S plutôt que K8S
- Deployer automatiquement sur k3s avec skaffold
- Regula l’outil d’Analyse Statique pour l’Infra As Code
- Kubevious le tableau de bord de vos clusters Kubernetes
- GitOps, mais comment en est-on arrivé là ?
Vous pouvez également regarder du côté de mon Home Lab Devops ou j’utilise k3s pour :
- Faire tourner mes runners gitlab
- Création des ingress
- Monitorer le cluster avec Prometheus/Grafana
- Centraliser les logs avec Loki
Plus d’infos
Livres Gratuits
Livres
- Kubernetes - Maîtrisez l’orchestrateur des infrastructures du futur: Maîtrisez l’orchestrateur des infrastructures du futur ↗ de Kelsey Hightower
- Understanding Kubernetes in a visual way ↗ - Aurélie Vache
- Kubernetes: Gérez la plateforme de déploiement de vos applications conteneurisées ↗ - Yannig Perré