Structure d'un cluster Kubernetes
Voici le schéma d'un cluster Kubernetes
Le Control Plane (Master Node) est le cerveau du cluster Kubernetes, il gère l'orchestration des tâches, la surveillance de l'état du système et la gestion des communications entre les nœuds.
Les worker nodes dans Kubernetes sont les machines (physiques ou virtuelles) qui exécutent les applications sous forme de containers.
Kubectl
kubectl est l'outil principal en ligne de commande utilisé pour interagir avec un cluster Kubernetes. Il permet aux utilisateurs de gérer les ressources du cluster, d'exécuter des commandes dans les containers, de déployer des applications et bien plus encore. Voici comment kubectl interagit avec un cluster Kubernetes :
Interprétation des commandes : Lorsque vous exécutez une commande
kubectl, l'outil interprète l'entrée et la transforme en une requête REST appropriée, envoyée au serveur d'API Kubernetes (kube-apiserver).Connexion au serveur d'API :
kubectlutilise le fichier de configurationkubeconfig, situé généralement dans~/.kube/config, pour se connecter au serveur d'API du cluster. Ce fichier contient les informations d'accès telles que l'URL du serveur API, les identifiants d'utilisateur et les certificats.Authentification et Autorisation : Le serveur d'API authentifie la requête à l'aide des informations fournies par
kubectl, puis vérifie si l'utilisateur a les droits nécessaires pour exécuter l'action demandée (via RBAC ou d'autres mécanismes).Traitement des Requêtes : Une fois la requête autorisée, le serveur d'API la traite et interagit avec le cluster. Par exemple, si l'utilisateur demande à créer un pod, l'API crée une ressource Pod dans etcd (la base de données clé-valeur du cluster).
Mise à jour du cluster : Si la commande implique la modification des ressources du cluster (ex: création, mise à jour, suppression), le serveur d'API met à jour l'état du cluster en conséquence. Les composants du plan de contrôle comme le scheduler ou les contrôleurs observent ces modifications et prennent les actions appropriées.
Réponse à
kubectl: Après avoir traité la requête, le serveur d'API renvoie une réponse àkubectl, qui l'affiche à l'utilisateur sous forme de messages texte ou JSON.
Scheduler
Le Scheduler (planificateur) est responsable de l'affectation des pods à des nœuds spécifiques dans le cluster Kubernetes. Lorsqu'un pod est créé sans nœud attribué, le Scheduler détermine le nœud le plus approprié pour héberger le pod, en tenant compte des contraintes de ressources, des préférences de déploiement et des règles définies.
Le processus fonctionne de cette façon :
- Récupération des pods non attribués : Le Scheduler observe les pods en attente d’attribution.
- Filtrage des nœuds disponibles : Il filtre les nœuds selon les exigences spécifiques du pod, telles que les ressources disponibles (CPU, mémoire) et les contraintes (affinités, anti-affinités).
- Notation des nœuds restants : Une fois les nœuds filtrés, le Scheduler les note en fonction de critères d'optimisation, comme l'équilibrage de charge.
- Sélection du nœud : Le nœud ayant la meilleure note est sélectionné pour héberger le pod.
- Assignation : Le Scheduler met à jour l'objet pod avec le nœud sélectionné et la planification se termine.
API Server
L'API Server est l'interface centrale qui reçoit toutes les requêtes venant des utilisateurs, des composants internes et des autres systèmes externes. Il agit comme le point d'entrée et contrôle toutes les opérations sur les objets Kubernetes (ex : création de Pods, Services, etc.). C'est également l'API que kubectl utilise pour interagir avec le cluster.
Il est essentiel pour :
- Servir les API REST aux utilisateurs et aux composants internes du cluster.
- Valider et configurer les données des objets Kubernetes.
- Exposer les informations du cluster à d’autres composants (Scheduler, Controller Manager, etc.).
- Contrôler l’accès aux ressources via des mécanismes d’authentification et d’autorisation (RBAC).
NOTE
- Service RESTful : L'API expose des endpoints REST que
kubectlet d'autres composants utilisent pour interagir avec les objets Kubernetes. - Sécurisation : Gère des processus comme TLS pour sécuriser la communication et autorise les actions via RBAC (Role-Based Access Control) ou ABAC (Attribute-Based Access Control).
- Validation et mutation des objets : Chaque objet envoyé est validé selon le schéma Kubernetes et peut être modifié par des webhooks de mutating admission controllers.
- Rôle de gestion des opérations : L'API Server ne stocke pas les informations à long terme. Il interagit avec etcd pour cela.
Etcd
etcd est une base de données distribuée clé-valeur qui stocke l’état global de Kubernetes. Il est conçu pour être fiable, performant et distribué, garantissant ainsi la haute disponibilité des données critiques du cluster. Tous les objets et configurations Kubernetes sont persistés dans etcd (par exemple, les informations sur les pods, services, configurations des nodes, secrets, etc.).
Le composant repose sur les principes suivants :
- Modèle clé-valeur : etcd stocke toutes les informations sous forme de paires clé-valeur. Les clés représentent les objets Kubernetes, et les valeurs contiennent leur état actuel.
- Transaction et Réplication : Chaque modification (écriture, mise à jour, suppression) est traitée comme une transaction distribuée et est répliquée sur tous les nœuds du cluster etcd pour assurer la cohérence.
- Watch : etcd permet aux composants de Kubernetes de s’abonner (via des watchers) aux changements d’état des objets. Par exemple, l’API Server peut « observer » les modifications d'un pod ou d'un nœud et déclencher des actions en conséquence.
Voici comment etcd fonctionne dans Kubernetes :
- Stockage de données : etcd conserve toutes les informations d'état du cluster. Chaque modification apportée par les composants du plan de contrôle (comme l'API Server) est écrite dans etcd.
- Répartition et tolérance aux pannes : etcd fonctionne de manière distribuée avec plusieurs nœuds, ce qui garantit une haute disponibilité et la tolérance aux pannes. Si un nœud etcd tombe en panne, d'autres nœuds prennent le relais.
- Consensus via Raft : etcd utilise l'algorithme de consensus Raft pour assurer la cohérence entre les différents nœuds du cluster etcd. Cela garantit que les données sont uniformément répliquées et fiables.
- Snapshotted et compacté : Pour éviter que le journal de transactions ne devienne trop grand, etcd compresse périodiquement les données (compaction) et effectue des instantanés réguliers.
- Interactions via API : Tous les composants Kubernetes (API Server, Controller Manager, Scheduler) interagissent avec etcd via des appels d'API pour lire ou écrire des données. L’API Server est le principal point de contact avec etcd.
Controller Manager
Le Controller Manager dans Kubernetes est un composant central qui exécute plusieurs "contrôleurs" pour assurer que l'état désiré du cluster soit maintenu. Chaque contrôleur est responsable de la gestion d'une ressource spécifique ou d'un ensemble de ressources (par exemple, les pods, les nœuds, les répliques). Il s'assure que l'état actuel du cluster correspond à l'état désiré, en observant les changements et en prenant des actions correctives lorsque nécessaire.
Les rôles principaux du Controller Manager incluent :
- Node Controller : Surveille les nœuds du cluster, détecte les pannes, et prend des mesures (comme marquer un nœud comme "Non Ready").
- Replication Controller : Garantit que le nombre souhaité de répliques de pods est en cours d'exécution. Si un pod meurt ou est supprimé, il en recrée un nouveau.
- Service Account & Token Controller : Gère les comptes de service et les tokens associés pour l'authentification au sein du cluster.
- Job Controller : Supervise les objets "Jobs" et s'assure qu'ils sont exécutés jusqu'à leur achèvement.
- Endpoint Controller : Gère les points de terminaison d'un service, garantissant qu'ils pointent vers les pods en cours d'exécution.
- DaemonSet Controller : Assure que tous les nœuds du cluster exécutent au moins une instance d'un certain pod.
Ces contrôleurs travaillent en coordination pour ajuster l'état du cluster à tout moment, en suivant un modèle de contrôle en boucle et effectuent les actions suivantes :
- Observation de l'état du cluster : Chaque contrôleur observe les objets Kubernetes à travers des événements déclenchés par l'API Server (qui récupère les données d'etcd).
- Prise de décision : Si un contrôleur détecte que l'état actuel diffère de l'état souhaité (par exemple, un pod supprimé ou un nœud défaillant), il prend une décision pour ajuster cet état.
- Actions correctives : En fonction de la décision prise, le contrôleur peut, par exemple, recréer un pod, marquer un nœud comme "Non Ready", ou modifier la configuration d'un service.
- Mise à jour de l'état : Le contrôleur met ensuite à jour l'état du cluster via l'API Server, qui persiste ces informations dans etcd.
Kubelet
Le Kubelet est l'agent qui fonctionne sur chaque nœud dans un cluster Kubernetes. Il est responsable de s'assurer que les containers des pods spécifiés par l'API Server sont en cours d'exécution et sont dans un état sain. Il interagit avec le système d'orchestration pour maintenir l'état désiré des pods sur le nœud.
Le Kubelet ne gère que les pods que Kubernetes lui a assignés et s'assure qu'ils sont bien démarrés, surveillés et exécutés sur le nœud.
Voici les fonctions du kubelet :
- Obtenir des instructions de l'API Server : Le Kubelet reçoit des instructions de l'API Server sous forme de manifestes de pods. Ces manifestes spécifient quels conteneurs doivent être exécutés sur le nœud.
- Interaction avec le Runtime de conteneurs : Le Kubelet interagit avec le container runtime (comme Docker, containerd, ou CRI-O) pour démarrer, arrêter, ou vérifier l'état des conteneurs. Il utilise l'interface CRI (Container Runtime Interface) pour cela.
- Surveillance des pods et des conteneurs : Le Kubelet surveille en continu l'état des pods et des conteneurs en cours d'exécution. Si un conteneur échoue ou cesse de fonctionner, il prend les mesures nécessaires pour le redémarrer.
- Health Checks (Liveness et Readiness Probes) : Le Kubelet vérifie la santé des conteneurs via des probes configurées (liveness, readiness). Si un conteneur ne répond pas aux probes de liveness, il est redémarré.
- Rapport à l'API Server : Le Kubelet renvoie régulièrement des rapports à l'API Server concernant l'état des pods en cours d'exécution sur le nœud.
- Gestion des volumes et secrets : Il est également responsable de la gestion des volumes montés pour les pods et de la distribution des secrets et configurations nécessaires au bon fonctionnement des conteneurs.
NOTE
- Manifeste de pod : Le Kubelet utilise les manifestes de pod pour savoir quels conteneurs doivent être exécutés et comment ils doivent être configurés (ressources, volumes, etc.).
- Communication avec l'API Server : Le Kubelet utilise l'API Server pour signaler l'état des pods et obtenir de nouvelles instructions.
- Contrôle en boucle : Le Kubelet fonctionne en continu pour s'assurer que l'état du nœud et des pods correspond à ce qui est attendu.
Kube Proxy
Kube-proxy est un composant réseau essentiel dans chaque nœud du cluster Kubernetes. Il est chargé de maintenir les règles réseau qui permettent la communication entre les services et les pods dans le cluster. Kube-proxy gère les règles de routage réseau en fonction des services Kubernetes et répartit le trafic vers les pods correspondants en se basant sur ces règles.
Il permet la découverte et la communication des services dans Kubernetes, en assurant la mise en œuvre du modèle de service virtuel.
Le composant fonctionne de la manière suivante :
Réception des configurations de services : Kube-proxy récupère les informations sur les services exposés dans le cluster à partir de l'API Server. Il comprend les services de type ClusterIP, NodePort et LoadBalancer.
Création des règles réseau : Kube-proxy configure les règles réseau sur chaque nœud en fonction de la configuration des services. Ces règles permettent de router le trafic destiné à un service vers les pods correspondants.
- Cela inclut des règles iptables ou IPVS (selon la configuration) pour router le trafic réseau vers les bonnes adresses IP des pods qui font partie du service.
Routage du trafic : Lorsqu'un service est exposé, Kube-proxy intercepte les requêtes destinées à ce service (par exemple, via une adresse ClusterIP) et répartit le trafic vers un des pods associés. Il agit comme un load balancer distribuant le trafic de manière équitable entre les pods.
Mise à jour dynamique : Kube-proxy surveille en continu les changements dans les services (par exemple, ajout ou suppression de pods, modification des règles réseau) et met à jour les règles de routage en conséquence.
Gestion du réseau : Kube-proxy peut utiliser plusieurs méthodes pour gérer les règles réseau, notamment iptables, IPVS, ou des proxys basés sur des sockets pour diriger le trafic.
- iptables : Crée des règles réseau basées sur les tables de routage d'iptables du système hôte.
- IPVS : Fournit des fonctionnalités plus avancées pour la gestion du trafic, offrant de meilleures performances pour de grands clusters.
NOTE
- Mode iptables : Kube-proxy utilise des règles iptables pour router le trafic en se basant sur les adresses IP et les ports des services. C'est le mode par défaut, simple mais moins performant à grande échelle.
- Mode IPVS : IP Virtual Server (IPVS) est un mode avancé qui offre des capacités de load balancing plus performantes que le mode iptables. Il est recommandé pour les clusters de grande taille.
- Mode nftables (K8s 1.29+) : Un nouveau mode basé sur nftables, le successeur moderne d'iptables. Il offre une syntaxe plus claire, de meilleures performances et une meilleure maintenabilité. Ce mode est encore en développement actif.
CoreDNS
CoreDNS est le serveur DNS par défaut dans Kubernetes (depuis la version 1.13). Il fournit la résolution de noms pour les services et les pods au sein du cluster, permettant aux applications de communiquer entre elles en utilisant des noms de services plutôt que des adresses IP.
CoreDNS remplace l'ancien kube-dns et offre une architecture plus modulaire et extensible grâce à son système de plugins.
Fonctionnement
Résolution des services : Lorsqu'un pod veut communiquer avec un service (par exemple
my-service.my-namespace.svc.cluster.local), CoreDNS résout ce nom en l'adresse IP du service (ClusterIP).Résolution des pods : CoreDNS peut également résoudre les noms des pods individuels, bien que cela soit moins courant.
Intégration avec l'API Server : CoreDNS surveille l'API Server pour détecter les changements dans les services et endpoints, et met à jour ses enregistrements DNS en conséquence.
Configuration via ConfigMap : La configuration de CoreDNS est stockée dans un ConfigMap (
corednsdans le namespacekube-system), ce qui permet de la personnaliser facilement.
Format des noms DNS
| Type | Format | Exemple |
|---|---|---|
| Service | <service>.<namespace>.svc.cluster.local | nginx.default.svc.cluster.local |
| Pod | <pod-ip>.<namespace>.pod.cluster.local | 10-244-0-5.default.pod.cluster.local |
| Service Headless | <pod-name>.<service>.<namespace>.svc.cluster.local | web-0.nginx.default.svc.cluster.local |
NOTE
- Plugins : CoreDNS utilise une architecture de plugins (kubernetes, forward, cache, errors, etc.) qui permet d'étendre ses fonctionnalités.
- Upstream DNS : CoreDNS peut transférer les requêtes DNS externes (non-cluster) vers des serveurs DNS upstream configurés.
- Cache : CoreDNS met en cache les réponses DNS pour améliorer les performances et réduire la charge sur l'API Server.
Container Runtime (CRI)
Le Container Runtime Interface (CRI) est l'interface utilisée par Kubernetes pour interagir avec le runtime des containers, tel que containerd, CRI-O, ou d'autres runtimes compatibles. Le Kubelet, qui est l'agent Kubernetes sur chaque nœud, utilise CRI pour gérer le cycle de vie des containers (créer, démarrer, arrêter, et détruire des containers). Le CRI permet à Kubernetes d'utiliser différentes implémentations de runtime containers de manière standardisée et agnostique.
WARNING
Fin du support Docker (dockershim) : Depuis Kubernetes 1.24 (mai 2022), le support natif de Docker via dockershim a été retiré. Docker n'est plus un runtime supporté directement par Kubernetes. Les clusters doivent utiliser containerd ou CRI-O comme runtime. Notez que les images Docker restent compatibles, car elles respectent le standard OCI (Open Container Initiative).
Runtimes compatibles CRI
| Runtime | Description | Cas d'usage |
|---|---|---|
| containerd | Runtime léger, extrait de Docker, maintenu par la CNCF. C'est le runtime par défaut sur la plupart des distributions Kubernetes. | Production, usage général |
| CRI-O | Runtime optimisé pour Kubernetes, développé par Red Hat. Minimaliste et focalisé uniquement sur K8s. | OpenShift, environnements Red Hat |
| gVisor (runsc) | Runtime avec isolation renforcée via un noyau utilisateur. | Workloads multi-tenants, sécurité accrue |
| Kata Containers | Runtime utilisant des micro-VMs pour une isolation forte. | Workloads sensibles, isolation maximale |
Fonctionnement
CRI gRPC API : Le CRI est une API standard basée sur gRPC qui permet à Kubernetes de communiquer avec différents runtimes de containers.
Deux principales fonctions du CRI :
- Container Manager : Créer, démarrer, arrêter et supprimer les containers.
- Image Manager : Télécharger, extraire, et gérer les images de containers.
Interaction avec Kubelet :
- Le Kubelet utilise l'API CRI pour piloter le runtime des containers sur le nœud.
- Il envoie des requêtes pour démarrer ou arrêter des containers, vérifier leur état, ou gérer les images des containers.
Standardisation et indépendance du runtime : Grâce au CRI, Kubernetes peut fonctionner avec n'importe quel runtime compatible (comme containerd ou CRI-O) sans nécessiter de modifications internes à Kubernetes.
NOTE
- Standardisation : CRI standardise l'interaction entre Kubernetes et les différents runtimes de containers. Cela permet d'utiliser différentes solutions (comme containerd ou CRI-O) avec Kubernetes sans avoir à adapter Kubernetes.
- Flexibilité : CRI permet à Kubernetes d'être agnostique vis-à-vis des runtimes, offrant ainsi une flexibilité et des performances optimisées pour différents environnements.
- Surveillance active : Le Kubelet utilise CRI pour vérifier en continu l'état des containers et s'assurer qu'ils sont en cours d'exécution comme prévu.
- Images OCI : Tous les runtimes compatibles CRI utilisent des images au format OCI, ce qui garantit la portabilité des images entre différents runtimes.
POD
Un Pod est l'unité de base de déploiement dans Kubernetes. Il représente un ou plusieurs conteneurs qui partagent le même contexte d'exécution, incluant les ressources réseau, les volumes de stockage, et les spécifications de configuration. Les pods sont créés, gérés, et supprimés par Kubernetes, et chaque pod contient généralement un seul conteneur, bien qu'il puisse en contenir plusieurs dans des cas où une forte co-dépendance entre les conteneurs est nécessaire.
Les pods sont éphémères et peuvent être recréés ou migrés entre différents nœuds en fonction des événements dans le cluster (comme les pannes de nœuds ou la mise à jour des ressources).
Le fonctionnement du POD est le suivant :
Création : Un Pod est créé lorsque le Kubelet reçoit une instruction via l'API Server pour exécuter un ou plusieurs conteneurs sur un nœud. Le Kubelet utilise le Container Runtime pour démarrer les containers dans le pod.
Compartiment réseau partagé : Les containers dans un Pod partagent le même réseau, ce qui signifie qu'ils utilisent la même adresse IP et peuvent communiquer entre eux via
localhost. Ils peuvent aussi partager des volumes de stockage.Liveness et Readiness Probes : Les pods utilisent des probes de liveness (pour vérifier si un conteneur doit être redémarré) et des probes de readiness (pour signaler que le conteneur est prêt à recevoir du trafic).
Répartition des ressources : Chaque pod peut avoir des limites et des demandes spécifiques en termes de CPU et de mémoire. Kubernetes utilise ces informations pour répartir les ressources sur les nœuds et planifier les pods.
Cycle de vie : Les pods sont temporaires par nature. Une fois qu'un pod est terminé (par exemple, une tâche de type batch), il ne sera pas redémarré, à moins qu'il ne fasse partie d'un contrôleur comme un Deployment ou un Job.
NOTE
Les statuts que peut prendre un POD sont :
- Pending : Le pod est créé mais pas encore planifié sur un nœud.
- Running : Le pod est planifié sur un nœud, et les containers à l'intérieur sont en cours d'exécution.
- Succeeded/Failed : Le pod a terminé avec succès ou échoué (par exemple, pour les pods de type Job).
- Unknown : L'état du pod est inconnu (généralement en raison d'une perte de communication entre le nœud et le Kubelet).
Cloud Controller Manager
Le Cloud Controller Manager est un composant optionnel mais crucial dans Kubernetes, qui permet d'intégrer un cluster avec un fournisseur de cloud spécifique (comme AWS, GCP, Azure, etc.). Il est responsable de la gestion des ressources et services liés au cloud dans le cluster Kubernetes. Cela inclut la gestion des nœuds, des volumes de stockage, des adresses IP externes, des load balancers, et bien plus encore.
Le Cloud Controller Manager est divisé en plusieurs contrôleurs spécialisés qui interagissent avec les API du fournisseur de cloud pour permettre une gestion fluide des ressources cloud. Ces contrôleurs gèrent des aspects spécifiques comme :
- Node Controller : Vérifie que les nœuds du cloud fonctionnent correctement et les marque comme non disponibles s'ils échouent.
- Route Controller : Configure les routes réseau dans le cloud pour permettre la communication entre les pods.
- Service Controller : Crée, met à jour, ou supprime les Load Balancers du cloud en fonction des services exposés dans Kubernetes.
- Volume Controller : Gère le provisionnement et la libération des volumes de stockage cloud pour les pods.
Ses principales fonctions sont les suivantes :
Découplage des opérations cloud : Le Cloud Controller Manager permet de séparer la logique spécifique au fournisseur de cloud du reste de Kubernetes, ce qui rend l'intégration cloud plus flexible.
Contrôleurs cloud spécifiques : Chaque contrôleur intégré au Cloud Controller Manager interagit avec les API du fournisseur de cloud pour gérer les ressources cloud, comme les instances, les disques, les réseaux et les load balancers.
Surveillance et mise à jour des ressources : Le Cloud Controller Manager surveille continuellement les ressources cloud (par exemple, les nœuds, les volumes) et effectue des ajustements si nécessaire, comme la création de Load Balancers ou le marquage des nœuds indisponibles.