Les concepts architecturaux derrière Kubernetes.
Un cluster Kubernetes est composé d'un plan de contrôle et d'un ensemble de machines de travail, appelées nœuds, qui exécutent des applications conteneurisées. Chaque cluster a besoin d'au moins un nœud de travail pour exécuter des Pods.
Les nœuds de travail hébergent les Pods qui sont les composants de la charge de travail de l'application. Le plan de contrôle gère les nœuds de travail et les Pods du cluster. Dans les environnements de production, le plan de contrôle s'exécute généralement sur plusieurs ordinateurs et un cluster exécute généralement plusieurs nœuds, offrant une tolérance aux pannes et une haute disponibilité.
Ce document décrit les différents composants nécessaires pour avoir un cluster Kubernetes complet et fonctionnel.
Remarque : Ce diagramme présente une architecture de référence d'exemple pour un cluster Kubernetes. La répartition réelle des composants peut varier en fonction des configurations et des exigences spécifiques du cluster.
Les composants du plan de contrôle prennent des décisions globales sur le cluster (par exemple, la planification),
ainsi que la détection et la réponse aux événements du cluster (par exemple, démarrer un nouveau
pod lorsque le champ replicas d'un déploiement
n'est pas satisfait).
Les composants du plan de contrôle peuvent s'exécuter sur n'importe quelle machine du cluster. Cependant, pour simplifier, les scripts d'installation démarrent généralement tous les composants du plan de contrôle sur la même machine et n'exécutent pas de conteneurs utilisateur sur cette machine. Consultez Création de clusters hautement disponibles avec kubeadm pour un exemple de configuration du plan de contrôle s'exécutant sur plusieurs machines.
Composant sur le master qui expose l'API Kubernetes. Il s'agit du front-end pour le plan de contrôle Kubernetes.
Il est conçu pour une mise à l'échelle horizontale, ce qui veut dire qu'il met à l'échelle en déployant des instances supplémentaires. Voir Construire des Clusters en Haute Disponibilité.
Base de données clé-valeur consistante et hautement disponible utilisée comme mémoire de sauvegarde pour toutes les données du cluster.
Si votre cluster Kubernetes utilise etcd comme mémoire de sauvegarde, assurez-vous d'avoir un plan de back up pour ces données.
Vous pouvez trouver plus d'informations à propos d'etcd dans la documentation officielle.
Composant sur le master qui surveille les pods nouvellement créés qui ne sont pas assignés à un nœud et sélectionne un nœud sur lequel ils vont s'exécuter.
Les facteurs pris en compte pour les décisions de planification (scheduling) comprennent les exigences individuelles et collectives en ressources, les contraintes matérielles/logicielles/politiques, les spécifications d'affinité et d'anti-affinité, la localité des données, les interférences entre charges de travail et les dates limites.
Composant du master qui exécute les contrôleurs.
Logiquement, chaque contrôleur est un processus à part mais, pour réduire la complexité, les contrôleurs sont tous compilés dans un seul binaire et s'exécutent dans un seul processus.
Il existe de nombreux types de contrôleurs différents. Voici quelques exemples :
Ce qui précède n'est pas une liste exhaustive.
Le cloud-controller-manager exécute uniquement des contrôleurs spécifiques à votre fournisseur de cloud. Si vous exécutez Kubernetes sur vos propres serveurs ou dans un environnement d'apprentissage sur votre propre PC, le cluster n'a pas de cloud-controller-manager.
Comme pour kube-controller-manager, cloud-controller-manager combine plusieurs boucles de contrôle logiquement indépendantes en un seul binaire que vous exécutez en tant que processus unique. Vous pouvez mettre à l'échelle horizontalement (exécuter plusieurs copies) pour améliorer les performances ou pour aider à tolérer les pannes.
Les contrôleurs suivants peuvent avoir des dépendances vis-à-vis du fournisseur de cloud :
Les composants du nœud s'exécutent sur chaque nœud, maintenant les Pods en cours d'exécution et fournissant l'environnement d'exécution Kubernetes.
Un agent qui s'exécute sur chaque nœud du cluster. Il s'assure que les conteneurs fonctionnent dans un pod.
Le kubelet prend un ensemble de PodSpecs fournis par divers mécanismes et s'assure du fonctionnement et de la santé des conteneurs décrits dans ces PodSpecs. Le kubelet ne gère que les conteneurs créés par Kubernetes.
kube-proxy est un proxy réseau qui s'exécute sur chaque nœud du cluster et implémente une partie du concept Kubernetes de Service.
kube-proxy maintient les règles réseau sur les nœuds. 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 s'il y en a une et qu'elle est disponible. Sinon, kube-proxy transmet le trafic lui-même.
Si vous utilisez un plugin réseau qui implémente le transfert de paquets pour les Services par lui-même, et fournissant un comportement équivalent à kube-proxy, alors vous n'avez pas besoin d'exécuter kube-proxy sur les nœuds de votre cluster.L'environnement d'exécution de conteneurs est le logiciel responsable de l'exécution des conteneurs.
Kubernetes est compatible avec plusieurs environnements d'exécution de conteneur: Docker, containerd, cri-o, rktlet ainsi que toute implémentation de Kubernetes CRI (Container Runtime Interface).
Les add-ons utilisent des ressources Kubernetes (DaemonSet,
Déploiement, etc.) pour implémenter des fonctionnalités de cluster.
Étant donné qu'ils fournissent des fonctionnalités au niveau du cluster, les ressources des add-ons
appartiennent au namespace kube-system.
Certains add-ons sélectionnés sont décrits ci-dessous ; pour une liste étendue d'add-ons disponibles, veuillez consulter Add-ons.
Bien que les autres add-ons ne soient pas strictement nécessaires, tous les clusters Kubernetes devraient avoir DNS du cluster, car de nombreux exemples en dépendent.
Le DNS du cluster est un serveur DNS, en plus des autres serveur(s) DNS de votre environnement, qui fournit des enregistrements DNS pour les services Kubernetes.
Les conteneurs démarrés par Kubernetes incluent automatiquement ce serveur DNS dans leurs recherches DNS.
Dashboard est une interface utilisateur basée sur le web, générale, pour les clusters Kubernetes. Il permet aux utilisateurs de gérer et de résoudre les problèmes des applications en cours d'exécution dans le cluster, ainsi que du cluster lui-même.
Surveillance des ressources des conteneurs enregistre des métriques génériques de séries chronologiques sur les conteneurs dans une base de données centrale et fournit une interface utilisateur pour parcourir ces données.
Un mécanisme de journalisation au niveau du cluster est responsable de l'enregistrement des journaux des conteneurs dans un magasin de journaux central avec une interface de recherche/parcours.
Les plugins réseau sont des composants logiciels qui implémentent la spécification de l'interface réseau de conteneur (CNI). Ils sont responsables de l'allocation des adresses IP aux pods et de leur permettre de communiquer entre eux au sein du cluster.
Bien que les composants principaux de Kubernetes restent cohérents, la manière dont ils sont déployés et gérés peut varier. Comprendre ces variations est crucial pour concevoir et maintenir des clusters Kubernetes répondant à des besoins opérationnels spécifiques.
Les composants du plan de contrôle peuvent être déployés de plusieurs manières :
Le placement des charges de travail, y compris les composants du plan de contrôle, peut varier en fonction de la taille du cluster, des exigences de performance et des politiques opérationnelles :
Des outils tels que kubeadm, kops et Kubespray offrent différentes approches pour le déploiement et la gestion des clusters, chacun avec sa propre méthode de disposition et de gestion des composants.
La flexibilité de l'architecture de Kubernetes permet aux organisations d'adapter leurs clusters à des besoins spécifiques, en équilibrant des facteurs tels que la complexité opérationnelle, les performances et la charge de gestion.
L'architecture de Kubernetes permet une personnalisation significative :
La flexibilité de l'architecture de Kubernetes permet aux organisations d'adapter leurs clusters à des besoins spécifiques, en équilibrant des facteurs tels que la complexité opérationnelle, les performances et la charge de gestion.
En savoir plus sur les sujets suivants :
Kubernetes exécute votre charge de travail en plaçant des conteneurs dans des Pods pour s'exécuter sur des nœuds. Un nœud peut être une machine virtuelle ou physique, selon le cluster. Chaque nœud est géré par le plan de contrôle et contient les services nécessaires pour exécuter Pods.
Typiquement, vous avez plusieurs nœuds dans un cluster ; dans un environnement d'apprentissage ou limité en ressources, vous pourriez n'avoir qu'un seul nœud.
Les composants sur un nœud incluent le kubelet, un runtime de conteneur, et le kube-proxy.
Il existe deux principales façons d'ajouter des nœuds au serveur API :
Après avoir créé un objet Nœud, ou lorsque le kubelet sur un nœud s'enregistre automatiquement, le plan de contrôle vérifie si le nouvel objet Nœud est valide. Par exemple, si vous essayez de créer un Nœud à partir du manifeste JSON suivant :
{
"kind": "Node",
"apiVersion": "v1",
"metadata": {
"name": "10.240.79.157",
"labels": {
"name": "my-first-k8s-node"
}
}
}
Kubernetes crée un objet Nœud en interne (la représentation). Kubernetes vérifie
qu'un kubelet s'est enregistré auprès du serveur API correspondant au champ metadata.name
du Nœud. Si le nœud est en bonne santé (c'est-à-dire que tous les services nécessaires sont en cours d'exécution),
alors il est éligible pour exécuter un Pod. Sinon, ce nœud est ignoré pour toute activité du cluster
jusqu'à ce qu'il redevienne en bonne santé.
Kubernetes conserve l'objet pour le Nœud invalide et continue de vérifier s'il devient en bonne santé.
Vous, ou un contrôleur, devez explicitement supprimer l'objet Nœud pour arrêter cette vérification de santé.
Le nom d'un objet Nœud doit être un nom de sous-domaine DNS valide.
Le nom identifie un Nœud. Deux Nœuds ne peuvent pas avoir le même nom en même temps. Kubernetes suppose également qu'une ressource avec le même nom est le même objet. Dans le cas d'un Nœud, on suppose implicitement qu'une instance utilisant le même nom aura le même état (par exemple, les paramètres réseau, le contenu du disque racine) et les mêmes attributs tels que les étiquettes du nœud. Cela peut entraîner des incohérences si une instance a été modifiée sans changer son nom. Si le Nœud doit être remplacé ou mis à jour de manière significative, l'objet Nœud existant doit être supprimé du serveur API en premier lieu, puis ré-ajouté après la mise à jour.
Lorsque le drapeau kubelet --register-node est vrai (par défaut), le kubelet tente de
s'enregistrer auprès du serveur API. C'est le modèle préféré, utilisé par la plupart des distributions.
Pour l'auto-enregistrement, le kubelet est démarré avec les options suivantes :
--kubeconfig - Chemin vers les informations d'identification pour s'authentifier auprès du serveur API.
--cloud-provider - Comment communiquer avec un fournisseur de cloud
pour lire les métadonnées à son sujet.
--register-node - S'enregistrer automatiquement auprès du serveur API.
--register-with-taints - Enregistrer le nœud avec la liste donnée de
taints (séparées par des virgules <clé>=<valeur>:<effet>).
Ne fait rien si register-node est faux.
--node-ip - Liste facultative de adresses IP séparées par des virgules pour le nœud.
Vous ne pouvez spécifier qu'une seule adresse pour chaque famille d'adresses.
Par exemple, dans un cluster IPv4 à pile unique, vous définissez cette valeur comme l'adresse IPv4 que le
kubelet doit utiliser pour le nœud.
Consultez configurer une pile double IPv4/IPv6
pour plus de détails sur l'exécution d'un cluster à double pile.
Si vous ne fournissez pas cet argument, le kubelet utilise l'adresse IPv4 par défaut du nœud, le cas échéant ; si le nœud n'a pas d'adresses IPv4, alors le kubelet utilise l'adresse IPv6 par défaut du nœud.
--node-labels - Étiquettes à ajouter lors de l'enregistrement du nœud
dans le cluster (voir les restrictions d'étiquettes appliquées par le
plugin d'admission NodeRestriction).
--node-status-update-frequency - Spécifie à quelle fréquence le kubelet envoie son état de nœud au serveur API.
Lorsque le mode d'autorisation du nœud et le plugin d'admission NodeRestriction sont activés, les kubelets sont autorisés uniquement à créer/modifier leur propre ressource Nœud.
Comme mentionné dans la section Unicité du nom du nœud,
lorsque la configuration du nœud doit être mise à jour, il est recommandé de ré-enregistrer
le nœud auprès du serveur API. Par exemple, si le kubelet est redémarré avec
un nouvel ensemble de --node-labels, mais le même nom de Nœud est utilisé, le changement ne sera
pas pris en compte, car les étiquettes sont uniquement définies (ou modifiées) lors de l'enregistrement du Nœud auprès du serveur API.
Les Pods déjà planifiés sur le Nœud peuvent se comporter de manière incorrecte ou causer des problèmes si la configuration du Nœud est modifiée lors du redémarrage du kubelet. Par exemple, un Pod déjà en cours d'exécution peut être affecté par les nouvelles étiquettes attribuées au Nœud, tandis que d'autres Pods, incompatibles avec ce Pod, seront planifiés en fonction de cette nouvelle étiquette. La ré-enregistrement du Nœud garantit que tous les Pods seront évacués et correctement re-planifiés.
Vous pouvez créer et modifier des objets Nœud en utilisant kubectl.
Lorsque vous souhaitez créer manuellement des objets Nœud, définissez le drapeau kubelet --register-node=false.
Vous pouvez modifier des objets Nœud indépendamment du paramètre --register-node.
Par exemple, vous pouvez définir des étiquettes sur un Nœud existant ou le marquer comme non planifiable.
Vous pouvez utiliser des étiquettes sur les Nœuds en conjonction avec des sélecteurs de nœuds sur les Pods pour contrôler la planification. Par exemple, vous pouvez restreindre un Pod à s'exécuter uniquement sur un sous-ensemble des nœuds disponibles.
Le marquage d'un nœud comme non planifiable empêche le planificateur de placer de nouveaux pods sur ce Nœud, mais n'affecte pas les Pods existants sur le Nœud. Cela est utile comme étape préparatoire avant un redémarrage du nœud ou une autre opération de maintenance.
Pour marquer un Nœud comme non planifiable, exécutez :
kubectl cordon $NOM_DU_NŒUD
Consultez Évacuation sécurisée d'un nœud pour plus de détails.
L'état d'un Nœud contient les informations suivantes :
Vous pouvez utiliser kubectl pour afficher l'état d'un Nœud et d'autres détails :
kubectl describe node <insérez-le-nom-du-nœud-ici>
Consultez État du nœud pour plus de détails.
Les battements de cœur, envoyés par les nœuds Kubernetes, aident votre cluster à déterminer la disponibilité de chaque nœud et à prendre des mesures en cas de détection de défaillances.
Pour les nœuds, il existe deux formes de battements de cœur :
.status d'un Nœud.kube-node-lease.
Chaque Nœud a un objet Lease associé.Le contrôleur de nœud est un composant du plan de contrôle Kubernetes qui gère différents aspects des nœuds.
Le contrôleur de nœud a plusieurs rôles dans la vie d'un nœud. Le premier est d'attribuer un bloc CIDR au nœud lors de son enregistrement (si l'attribution CIDR est activée).
Le deuxième est de maintenir à jour la liste interne des nœuds du contrôleur de nœud avec la liste des machines disponibles du fournisseur de cloud. Lorsqu'il s'exécute dans un environnement cloud et chaque fois qu'un nœud est en mauvaise santé, le contrôleur de nœud demande au fournisseur de cloud si la VM pour ce nœud est toujours disponible. Si ce n'est pas le cas, le contrôleur de nœud supprime le nœud de sa liste de nœuds.
Le troisième est de surveiller la santé des nœuds. Le contrôleur de nœud est responsable de :
Ready
dans le champ .status du Nœud. Dans ce cas, le contrôleur de nœud définit la
condition Ready à Unknown.Unknown et la soumission
de la première demande d'éviction.Par défaut, le contrôleur de nœud vérifie l'état de chaque nœud toutes les 5 secondes.
Cette période peut être configurée à l'aide du drapeau --node-monitor-period sur le
composant kube-controller-manager.
Dans la plupart des cas, le contrôleur de nœud limite le taux d'éviction à
--node-eviction-rate (par défaut 0,1) par seconde, ce qui signifie qu'il n'évacuera pas les pods
de plus d'un nœud toutes les 10 secondes.
Le comportement d'éviction des nœuds change lorsqu'un nœud dans une zone de disponibilité donnée
devient en mauvaise santé. Le contrôleur de nœud vérifie quel pourcentage de nœuds dans la zone
sont en mauvaise santé (la condition Ready est Unknown ou False) en même temps :
--unhealthy-zone-threshold
(par défaut 0,55), alors le taux d'éviction est réduit.--large-cluster-size-threshold nœuds - par défaut 50), alors les évictions sont arrêtées.--secondary-node-eviction-rate
(par défaut 0,01) par seconde.La raison pour laquelle ces politiques sont mises en œuvre par zone de disponibilité est que une zone de disponibilité peut être isolée du plan de contrôle tandis que les autres restent connectées. Si votre cluster ne s'étend pas sur plusieurs zones de disponibilité du fournisseur de cloud, alors le mécanisme d'éviction ne prend pas en compte l'indisponibilité par zone.
Une raison clé de répartir vos nœuds sur plusieurs zones de disponibilité est de permettre
le déplacement de la charge de travail vers des zones saines lorsque toute une zone est hors service.
Par conséquent, si tous les nœuds d'une zone sont en mauvaise santé, alors le contrôleur de nœud évacue au
taux normal de --node-eviction-rate. Le cas particulier est lorsque toutes les zones sont
complètement en mauvaise santé (aucun des nœuds du cluster n'est en bonne santé). Dans un tel
cas, le contrôleur de nœud suppose qu'il y a un problème de connectivité
entre le plan de contrôle et les nœuds, et n'effectue aucune éviction.
(S'il y a eu une panne et que certains nœuds réapparaissent, le contrôleur de nœud évacue les pods
des nœuds restants qui sont en mauvaise santé ou injoignables).
Le contrôleur de nœud est également responsable de l'éviction des pods s'exécutant sur des nœuds avec
des taints NoExecute, sauf si ces pods tolèrent cette taint.
Le contrôleur de nœud ajoute également des taints
correspondant aux problèmes du nœud, tels que le nœud injoignable ou non prêt. Cela signifie
que le planificateur ne placera pas de Pods sur des nœuds en mauvaise santé.
Les objets Nœud suivent des informations sur la capacité des ressources du Nœud : par exemple, la quantité de mémoire disponible et le nombre de CPU. Les nœuds qui s'enregistrent automatiquement rapportent leur capacité lors de l'enregistrement. Si vous les ajoutez manuellement, alors vous devez définir les informations de capacité du nœud lors de son ajout. Les nœuds qui s'enregistrent automatiquement rapportent leur capacité lors de l'enregistrement. Si vous les ajoutez manuellement, alors vous devez définir les informations de capacité du nœud lors de son ajout.
Le planificateur Kubernetes s'assure qu'il y a suffisamment de ressources pour tous les Pods sur un Nœud. Le planificateur vérifie que la somme des demandes des conteneurs sur le nœud n'est pas supérieure à la capacité du nœud. Cette somme de demandes inclut tous les conteneurs gérés par le kubelet, mais exclut tout conteneur démarré directement par le runtime de conteneur, ainsi que tout processus s'exécutant en dehors du contrôle du kubelet.
Kubernetes v1.27 [stable](enabled by default)Si vous avez activé la fonctionnalité TopologyManager feature gate, alors le kubelet peut utiliser des indications de topologie lors de la prise de décision d'attribution des ressources. Consultez la section Contrôler les stratégies de gestion de la topologie sur un nœud pour plus d'informations.
Kubernetes v1.34 [stable](enabled by default)Pour activer la mémoire swap sur un nœud, la fonctionnalité NodeSwap doit être activée sur le kubelet (par défaut, elle est activée), et le drapeau de ligne de commande --fail-swap-on ou le paramètre de configuration failSwapOn setting doit être défini sur false. Pour permettre aux Pods d'utiliser la mémoire swap, swapBehavior ne doit pas être défini sur NoSwap (qui est le comportement par défaut) dans la configuration du kubelet.
Un utilisateur peut également configurer facultativement memorySwap.swapBehavior afin de spécifier comment un nœud utilisera la mémoire swap. Par exemple,
memorySwap:
swapBehavior: LimitedSwap
NoSwap (par défaut) : Les charges de travail Kubernetes n'utiliseront pas la mémoire swap.LimitedSwap : L'utilisation de la mémoire swap par les charges de travail Kubernetes est soumise à des limitations. Seuls les Pods de QoS Burstable sont autorisés à utiliser la mémoire swap.Si la configuration pour memorySwap n'est pas spécifiée et que la fonctionnalité est activée, par défaut, le kubelet appliquera le même comportement que le paramètre NoSwap.
Avec LimitedSwap, les Pods qui ne relèvent pas de la classification QoS Burstable (c'est-à-dire les Pods QoS BestEffort/Guaranteed) sont interdits d'utiliser la mémoire swap. Pour maintenir les garanties de sécurité et de santé du nœud mentionnées ci-dessus, ces Pods ne sont pas autorisés à utiliser la mémoire swap lorsque LimitedSwap est en vigueur.
Avant de détailler le calcul de la limite d'échange, il est nécessaire de définir les termes suivants :
nodeTotalMemory : La quantité totale de mémoire physique disponible sur le nœud.totalPodsSwapAvailable : La quantité totale de mémoire swap sur le nœud disponible pour une utilisation par les Pods (une partie de la mémoire swap peut être réservée à des fins système).containerMemoryRequest : La demande de mémoire du conteneur.La limitation d'échange est configurée comme suit :
(containerMemoryRequest / nodeTotalMemory) * totalPodsSwapAvailable.
Il est important de noter que, pour les conteneurs dans les Pods de QoS Burstable, il est possible de désactiver l'utilisation de l'échange en spécifiant des demandes de mémoire égales aux limites de mémoire. Les conteneurs configurés de cette manière n'auront pas accès à la mémoire swap.
L'échange est pris en charge uniquement avec cgroup v2, cgroup v1 n'est pas pris en charge.
Pour plus d'informations, et pour aider aux tests et fournir des commentaires, veuillez consulter l'article de blog sur Kubernetes 1.28 : NodeSwap passe en version Beta1, KEP-2400 et sa proposition de conception.
En savoir plus sur les éléments suivants :
Ce document répertorie les chemins de communication entre le serveur API et le cluster Kubernetes. L'objectif est de permettre aux utilisateurs de personnaliser leur installation pour renforcer la configuration réseau afin que le cluster puisse fonctionner sur un réseau non fiable (ou sur des adresses IP publiques complètement) fournies par un fournisseur de cloud.
Kubernetes utilise un modèle d'API de type "hub-et-spoke". Toutes les utilisations de l'API à partir des nœuds (ou des pods qu'ils exécutent) se terminent au niveau du serveur API. Aucun des autres composants du plan de contrôle n'est conçu pour exposer des services distants. Le serveur API est configuré pour écouter les connexions distantes sur un port HTTPS sécurisé (généralement le port 443) avec une ou plusieurs formes d'authentification client activées. Une ou plusieurs formes d'autorisation devraient être activées, en particulier si les requêtes anonymes ou les jetons de compte de service sont autorisés.
Les nœuds doivent être provisionnés avec le certificat racine public pour le cluster afin qu'ils puissent se connecter de manière sécurisée au serveur API avec des informations d'identification client valides. Une bonne approche consiste à ce que les informations d'identification client fournies au kubelet soient sous la forme d'un certificat client. Consultez l'amorçage TLS du kubelet pour la provision automatisée des certificats client du kubelet.
Les pods qui souhaitent se connecter au serveur API peuvent le faire de manière sécurisée en utilisant un compte de service de sorte
que Kubernetes injecte automatiquement le certificat racine public et un jeton d'accès valide
dans le pod lors de son instanciation.
Le service kubernetes (dans le namespace default) est configuré avec une adresse IP virtuelle qui est
redirigée (via kube-proxy) vers le point de terminaison HTTPS du serveur API.
Les composants du plan de contrôle communiquent également avec le serveur API via le port sécurisé.
Par conséquent, le mode de fonctionnement par défaut des connexions des nœuds et des pods exécutés sur les nœuds vers le plan de contrôle est sécurisé par défaut et peut fonctionner sur des réseaux non fiables et/ou publics.
Il existe deux chemins de communication principaux du plan de contrôle (le serveur API) vers les nœuds. Le premier est du serveur API au processus kubelet qui s'exécute sur chaque nœud du cluster. Le deuxième est du serveur API vers n'importe quel nœud, pod ou service via la fonctionnalité de proxy du serveur API.
Les connexions du serveur API au kubelet sont utilisées pour :
kubectl) aux pods en cours d'exécution.Ces connexions se terminent au niveau du point de terminaison HTTPS du kubelet. Par défaut, le serveur API ne vérifie pas le certificat de service du kubelet, ce qui rend la connexion vulnérable aux attaques de l'homme du milieu et non sécurisée pour une utilisation sur des réseaux non fiables et/ou publics.
Pour vérifier cette connexion, utilisez le paramètre --kubelet-certificate-authority
pour fournir au serveur API un ensemble de certificats racine à utiliser pour vérifier le certificat de service du kubelet.
Si cela n'est pas possible, utilisez le tunnel SSH entre le serveur API et le kubelet si nécessaire pour éviter de se connecter via un réseau non fiable ou public.
Enfin, l'authentification et/ou l'autorisation du kubelet devraient être activées pour sécuriser l'API du kubelet.
Les connexions du serveur API vers un nœud, un pod ou un service sont par défaut des connexions HTTP non sécurisées
et ne sont donc ni authentifiées ni chiffrées. Elles peuvent être exécutées via une connexion HTTPS sécurisée
en préfixant https: au nom du nœud, du pod ou du service dans l'URL de l'API, mais elles ne vérifieront pas
le certificat fourni par le point de terminaison HTTPS ni ne fourniront des informations d'identification client. Ainsi,
bien que la connexion soit chiffrée, elle ne garantira aucune intégrité. Ces
connexions ne sont actuellement pas sûres pour une utilisation sur des réseaux non fiables ou publics.
Kubernetes prend en charge les tunnels SSH pour protéger les chemins de communication du plan de contrôle vers les nœuds. Dans cette configuration, le serveur API initie un tunnel SSH vers chaque nœud du cluster (en se connectant à le serveur SSH qui écoute sur le port 22) et fait passer tout le trafic destiné à un kubelet, un nœud, un pod ou un service à travers le tunnel. Ce tunnel garantit que le trafic n'est pas exposé en dehors du réseau dans lequel les nœuds sont exécutés.
Kubernetes v1.18 [beta]
En remplacement des tunnels SSH, le service Konnectivity fournit un proxy de niveau TCP pour la communication entre le plan de contrôle et le cluster. Le service Konnectivity se compose de deux parties : le serveur Konnectivity dans le réseau du plan de contrôle et les agents Konnectivity dans le réseau des nœuds. Les agents Konnectivity initient des connexions vers le serveur Konnectivity et maintiennent les connexions réseau. Après avoir activé le service Konnectivity, tout le trafic du plan de contrôle vers les nœuds passe par ces connexions.
Suivez la tâche du service Konnectivity pour configurer le service Konnectivity dans votre cluster.
En robotique et automatisation, une boucle de contrôle est une boucle non terminante qui régule l'état d'un système.
Voici un exemple de boucle de contrôle : un thermostat dans une pièce.
Lorsque vous réglez la température, vous indiquez au thermostat votre état souhaité. La température réelle de la pièce est l' état actuel. Le thermostat agit pour rapprocher l'état actuel de l'état souhaité, en allumant ou éteignant l'équipement.
Boucle de contrôle surveillant l'état partagé du cluster à travers l'apiserver et effectuant des changements en essayant de déplacer l'état actuel vers l'état désiré.Un contrôleur suit au moins un type de ressource Kubernetes. Ces objets ont un champ spec qui représente l'état souhaité. Les contrôleurs de cette ressource sont responsables de rapprocher l'état actuel de cet état souhaité.
Le contrôleur peut effectuer lui-même l'action ; plus couramment, dans Kubernetes, un contrôleur enverra des messages au serveur API qui ont des effets secondaires utiles. Vous verrez des exemples de cela ci-dessous.
Le contrôleur de Job est un exemple de contrôleur intégré à Kubernetes. Les contrôleurs intégrés gèrent l'état en interagissant avec le serveur API du cluster.
Job est une ressource Kubernetes qui exécute un Pod, ou peut-être plusieurs Pods, pour effectuer une tâche, puis s'arrête.
(Une fois planifiés, les objets Pod font partie de l' état souhaité pour un kubelet).
Lorsque le contrôleur de Job voit une nouvelle tâche, il s'assure que, quelque part dans votre cluster, les kubelets sur un ensemble de nœuds exécutent le bon nombre de Pods pour effectuer le travail. Le contrôleur de Job n'exécute aucun Pod ou conteneur lui-même. Au lieu de cela, le contrôleur de Job demande au serveur API de créer ou supprimer des Pods. D'autres composants du plan de contrôle agissent sur les nouvelles informations (il y a de nouveaux Pods à planifier et à exécuter), et finalement le travail est terminé.
Après avoir créé un nouveau Job, l'état souhaité est que ce Job soit terminé. Le contrôleur de Job rapproche l'état actuel de ce Job de votre état souhaité : en créant des Pods qui effectuent le travail que vous avez demandé pour ce Job, de sorte que le Job soit plus proche de l'achèvement.
Les contrôleurs mettent également à jour les objets qui les configurent.
Par exemple : une fois le travail terminé pour un Job, le contrôleur de Job
met à jour cet objet Job pour le marquer comme Terminé.
(C'est un peu comme certains thermostats éteignent une lumière pour indiquer que votre pièce est maintenant à la température que vous avez réglée).
Contrairement à Job, certains contrôleurs doivent apporter des modifications à des éléments en dehors de votre cluster.
Par exemple, si vous utilisez une boucle de contrôle pour vous assurer qu'il y a suffisamment de nœuds dans votre cluster, alors ce contrôleur a besoin de quelque chose en dehors du cluster actuel pour configurer de nouveaux nœuds lorsque cela est nécessaire.
Les contrôleurs qui interagissent avec un état externe trouvent leur état souhaité à partir du serveur API, puis communiquent directement avec un système externe pour rapprocher l'état actuel en ligne.
(Il existe en fait un contrôleur qui met à l'échelle horizontalement les nœuds de votre cluster.)
Le point important ici est que le contrôleur apporte certaines modifications pour atteindre votre état souhaité, puis rapporte l'état actuel à votre serveur API de cluster. D'autres boucles de contrôle peuvent observer ces données rapportées et prendre leurs propres mesures.
Dans l'exemple du thermostat, si la pièce est très froide, un autre contrôleur pourrait également allumer un radiateur de protection contre le gel. Avec les clusters Kubernetes, le plan de contrôle fonctionne indirectement avec des outils de gestion des adresses IP, des services de stockage, des API de fournisseurs de cloud et d'autres services en étendant Kubernetes pour les implémenter.
Kubernetes adopte une vision nativement cloud des systèmes et est capable de gérer un changement constant.
Votre cluster peut changer à tout moment à mesure que le travail se déroule et que les boucles de contrôle corrigent automatiquement les défaillances. Cela signifie que, potentiellement, votre cluster n'atteint jamais un état stable.
Tant que les contrôleurs de votre cluster sont en cours d'exécution et capables de effectuer des modifications utiles, il n'importe pas si l'état global est stable ou non.
En tant que principe de sa conception, Kubernetes utilise de nombreux contrôleurs qui gèrent chacun un aspect particulier de l'état du cluster. Le plus souvent, une boucle de contrôle (contrôleur) utilise un type de ressource comme état souhaité et gère un autre type de ressource pour réaliser cet état souhaité. Par exemple, un contrôleur pour les Jobs suit les objets Job (pour découvrir un nouveau travail) et les objets Pod (pour exécuter les Jobs, puis voir quand le travail est terminé). Dans ce cas, quelque chose d'autre crée les Jobs, tandis que le contrôleur de Job crée les Pods.
Il est utile d'avoir des contrôleurs simples plutôt qu'un ensemble monolithique de boucles de contrôle interconnectées. Les contrôleurs peuvent échouer, c'est pourquoi Kubernetes est conçu pour le permettre.
Il peut y avoir plusieurs contrôleurs qui créent ou mettent à jour le même type d'objet. En coulisses, les contrôleurs Kubernetes s'assurent qu'ils ne prêtent attention qu'aux ressources liées à leur ressource de contrôle.
Par exemple, vous pouvez avoir des Déploiements et des Jobs ; ceux-ci créent tous deux des Pods. Le contrôleur de Job ne supprime pas les Pods créés par votre Déploiement, car il existe des informations (étiquettes) que les contrôleurs peuvent utiliser pour distinguer ces Pods.
Kubernetes est livré avec un ensemble de contrôleurs intégrés qui s'exécutent à l'intérieur du kube-controller-manager. Ces contrôleurs intégrés fournissent des comportements de base importants.
Le contrôleur de Déploiement et le contrôleur de Job sont des exemples de contrôleurs qui font partie de Kubernetes lui-même (contrôleurs "intégrés"). Kubernetes vous permet d'exécuter un plan de contrôle résilient, de sorte que si l'un des contrôleurs intégrés venait à échouer, une autre partie du plan de contrôle prendra en charge le travail.
Vous pouvez trouver des contrôleurs qui s'exécutent en dehors du plan de contrôle pour étendre Kubernetes. Ou, si vous le souhaitez, vous pouvez écrire vous-même un nouveau contrôleur. Vous pouvez exécuter votre propre contrôleur sous la forme d'un ensemble de Pods, ou en dehors de Kubernetes. Ce qui convient le mieux dépendra de ce que ce contrôleur particulier fait.
Les systèmes distribués ont souvent besoin de Lease, qui fournissent un mécanisme pour verrouiller les ressources partagées
et coordonner l'activité entre les membres d'un ensemble.
Dans Kubernetes, le concept de bail est représenté par les objets Lease
dans le groupe d'API coordination.k8s.io Groupe d'API,
qui sont utilisés pour des fonctionnalités critiques du système telles que les battements de cœur des nœuds et l'élection du leader au niveau des composants.
Kubernetes utilise l'API Lease pour communiquer les battements de cœur des nœuds kubelet au serveur API Kubernetes.
Pour chaque Node, il existe un objet Lease avec un nom correspondant dans le namespace kube-node-lease.
Sous le capot, chaque battement de cœur kubelet est une demande de mise à jour de cet objet Lease, mettant à jour
le champ spec.renewTime pour le bail. Le plan de contrôle Kubernetes utilise le horodatage de ce champ
pour déterminer la disponibilité de ce Node.
Consultez Objets de bail de nœud pour plus de détails.
Kubernetes utilise également des Lease pour s'assurer qu'une seule instance d'un composant est en cours d'exécution à tout moment.
Cela est utilisé par les composants du plan de contrôle tels que kube-controller-manager et kube-scheduler dans
les configurations HA, où une seule instance du composant doit être en cours d'exécution activement tandis que les autres
instances sont en attente.
Lisez élection coordonnée du leader pour en savoir plus sur la façon dont Kubernetes s'appuie sur l'API Lease pour sélectionner quelle instance de composant agit en tant que leader.
Kubernetes v1.26 [beta](enabled by default)À partir de Kubernetes v1.26, chaque kube-apiserver utilise l'API Lease pour publier son identité au reste du système.
Bien que cela ne soit pas particulièrement utile en soi, cela fournit un mécanisme pour les clients afin de
découvrir combien d'instances de kube-apiserver opèrent sur le plan de contrôle Kubernetes.
L'existence des Lease kube-apiserver permet des fonctionnalités futures qui peuvent nécessiter une coordination entre
chaque kube-apiserver.
Vous pouvez inspecter les Lease détenus par chaque kube-apiserver en vérifiant les objets de bail dans le namespace kube-system
avec le nom apiserver-<sha256-hash>. Alternativement, vous pouvez utiliser le sélecteur d'étiquettes apiserver.kubernetes.io/identity=kube-apiserver:
kubectl -n kube-system get lease -l apiserver.kubernetes.io/identity=kube-apiserver
NOM HOLDER ÂGE
apiserver-07a5ea9b9b072c4a5f3d1c3702 apiserver-07a5ea9b9b072c4a5f3d1c3702_0c8914f7-0f35-440e-8676-7844977d3a05 5m33s
apiserver-7be9e061c59d368b3ddaf1376e apiserver-7be9e061c59d368b3ddaf1376e_84f2a85d-37c1-4b14-b6b9-603e62e4896f 4m23s
apiserver-1dfef752bcb36637d2763d1868 apiserver-1dfef752bcb36637d2763d1868_c5ffa286-8a9a-45d4-91e7-61118ed58d2e 4m43s
Le hachage SHA256 utilisé dans le nom du bail est basé sur le nom d'hôte du système d'exploitation tel que vu par ce serveur API. Chaque kube-apiserver devrait être
configuré pour utiliser un nom d'hôte qui est unique dans le cluster. Les nouvelles instances de kube-apiserver qui utilisent le même nom d'hôte
prendront le contrôle des Lease existants en utilisant une nouvelle identité de détenteur, au lieu d'instancier de nouveaux objets de bail. Vous pouvez vérifier le
nom d'hôte utilisé par kube-apiserver en vérifiant la valeur de l'étiquette kubernetes.io/hostname:
kubectl -n kube-system get lease apiserver-07a5ea9b9b072c4a5f3d1c3702 -o yaml
apiVersion: coordination.k8s.io/v1
kind: Lease
metadata:
creationTimestamp: "2023-07-02T13:16:48Z"
labels:
apiserver.kubernetes.io/identity: kube-apiserver
kubernetes.io/hostname: master-1
name: apiserver-07a5ea9b9b072c4a5f3d1c3702
namespace: kube-system
resourceVersion: "334899"
uid: 90870ab5-1ba9-4523-b215-e4d4e662acb1
spec:
holderIdentity: apiserver-07a5ea9b9b072c4a5f3d1c3702_0c8914f7-0f35-440e-8676-7844977d3a05
leaseDurationSeconds: 3600
renewTime: "2023-07-04T21:58:48.065888Z"
Les Lease expirés des kube-apiservers qui n'existent plus sont collectés par les nouveaux kube-apiservers après 1 heure.
Vous pouvez désactiver les Lease d'identité du serveur API en désactivant la fonctionnalité APIServerIdentity
feature gate.
Votre propre charge de travail peut définir son propre usage des Lease. Par exemple, vous pouvez exécuter un
contrôleur personnalisé où un membre principal ou leader
effectue des opérations que ses pairs ne font pas. Vous définissez un bail afin que les réplicas du contrôleur puissent sélectionner
ou élire un leader, en utilisant l'API Kubernetes pour la coordination.
Si vous utilisez un bail, il est bon de pratiquer de définir un nom pour le bail qui est clairement lié au
produit ou au composant. Par exemple, si vous avez un composant nommé Example Foo, utilisez un bail nommé
example-foo.
Si un opérateur de cluster ou un autre utilisateur final peut déployer plusieurs instances d'un composant, sélectionnez un préfixe de nom et choisissez un mécanisme (comme le hachage du nom du déploiement) pour éviter les collisions de noms pour les Lease.
Vous pouvez utiliser une autre approche tant qu'elle atteint le même résultat : les différents produits logiciels ne entrent pas en conflit les uns avec les autres.
Kubernetes v1.11 [beta]
Les technologies d'infrastructure cloud vous permettent d'exécuter Kubernetes sur des clouds publics, privés et hybrides. Kubernetes croit en une infrastructure automatisée pilotée par API sans couplage étroit entre les composants.
Le gestionnaire du contrôleur de cloud est le Cloud Controller Manager est une fonctionnalité alpha de la version 1.8. Dans les prochaines versions, il deviendra le moyen privilégié pour l'intégration de Kubernetes à n'importe quel cloud.
Kubernetes v1.6 contient un nouveau binaire appelé cloud-controller-manager. Le cloud-controller-manager est un service qui intègre des boucles de contrôle propres au cloud. Ces boucles de contrôle spécifiques au cloud se trouvaient à l'origine dans le kube-controller-manager. Étant donné que les fournisseurs de cloud développent et mettent à jour leurs produits à un rythme différent de celui du projet Kubernetes, l'abstraction du code spécifique au fournisseur, au niveau du binaire cloud-controller-manager, permet aux fournisseurs de cloud d'évoluer indépendamment du code principal de Kubernetes.
Le gestionnaire du contrôleur de cloud est structuré à l'aide d'un mécanisme de plugin qui permet aux différents fournisseurs de cloud d'intégrer leurs plateformes à Kubernetes.
Le gestionnaire du contrôleur de cloud s'exécute dans le plan de contrôle en tant qu'ensemble répliqué de processus (généralement, ce sont des conteneurs dans des Pods). Chaque gestionnaire du contrôleur de cloud implémente plusieurs contrôleurs dans un seul processus.
Les contrôleurs à l'intérieur du gestionnaire du contrôleur de cloud comprennent :
Le contrôleur de nœud est responsable de la mise à jour des objets Nœud lorsque de nouveaux serveurs sont créés dans votre infrastructure cloud. Le contrôleur de nœud obtient des informations sur les hôtes en cours d'exécution dans votre tenancy avec le fournisseur de cloud. Le contrôleur de nœud effectue les fonctions suivantes :
Certaines implémentations de fournisseurs de cloud divisent cela en un contrôleur de nœud et un contrôleur de cycle de vie de nœud distinct.
Le contrôleur de route est responsable de la configuration des routes dans le cloud de manière appropriée afin que les conteneurs sur différents nœuds de votre cluster Kubernetes puissent communiquer entre eux.
Selon le fournisseur de cloud, le contrôleur de route peut également allouer des blocs d'adresses IP pour le réseau de Pod.
Les services s'intègrent aux composants d'infrastructure cloud tels que les équilibreurs de charge gérés, les adresses IP, le filtrage des paquets réseau et la vérification de l'état de la cible. Le contrôleur de service interagit avec les API de votre fournisseur de cloud pour configurer les équilibreurs de charge et autres composants d'infrastructure lorsque vous déclarez une ressource Service qui les nécessite.
Cette section détaille l'accès requis par le gestionnaire du contrôleur de cloud sur divers objets API pour effectuer ses opérations.
Le contrôleur de nœud ne fonctionne qu'avec les objets Nœud. Il nécessite un accès complet pour lire et modifier les objets Nœud.
v1/Node :
Le contrôleur de route écoute la création d'objets Nœud et configure les routes de manière appropriée. Il nécessite un accès Get aux objets Nœud.
v1/Node :
Le contrôleur de service surveille les événements de création, de mise à jour et de suppression des objets Service, puis configure les Endpoints pour ces Services de manière appropriée (pour les EndpointSlices, le kube-controller-manager les gère à la demande).
Pour accéder aux Services, il nécessite un accès list et watch. Pour mettre à jour les Services, il nécessite un accès patch et update.
Pour configurer les ressources Endpoints pour les Services, il nécessite un accès create, list, get, watch et update.
v1/Service :
La mise en œuvre du cœur du gestionnaire du contrôleur de cloud nécessite un accès pour créer des objets Event et pour assurer un fonctionnement sécurisé, il nécessite un accès pour créer des comptes de service.
v1/Event :
v1/ServiceAccount :
Le ClusterRole RBAC pour le gestionnaire du contrôleur de cloud ressemble à ceci :
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cloud-controller-manager
rules:
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- update
- apiGroups:
- ""
resources:
- nodes
verbs:
- '*'
- apiGroups:
- ""
resources:
- nodes/status
verbs:
- patch
- apiGroups:
- ""
resources:
- services
verbs:
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- create
- apiGroups:
- ""
resources:
- persistentvolumes
verbs:
- get
- list
- update
- watch
- apiGroups:
- ""
resources:
- endpoints
verbs:
- create
- get
- list
- watch
- update
Administration du gestionnaire du contrôleur de cloud contient des instructions sur l'exécution et la gestion du gestionnaire du contrôleur de cloud.
Pour mettre à niveau un plan de contrôle haute disponibilité pour utiliser le gestionnaire du contrôleur de cloud, consultez Migrer le plan de contrôle répliqué pour utiliser le gestionnaire du contrôleur de cloud.
Vous voulez savoir comment implémenter votre propre gestionnaire du contrôleur de cloud ou étendre un projet existant ?
CloudProvider définie dans
cloud.go
de kubernetes/cloud-provider pour permettre
l'intégration de toutes les implémentations de cloud.CloudProvider.Sur Linux, les groupes de contrôle limitent les ressources allouées aux processus.
Le kubelet et le runtime de conteneur sous-jacent doivent interagir avec les cgroups pour appliquer la gestion des ressources pour les pods et les conteneurs, ce qui inclut les demandes et les limites de CPU/mémoire pour les charges de travail conteneurisées.
Il existe deux versions de cgroups sur Linux : cgroup v1 et cgroup v2. cgroup v2 est
la nouvelle génération de l'API cgroup.
Kubernetes v1.25 [stable]
cgroup v2 est la prochaine version de l'API cgroup de Linux. cgroup v2 offre un
système de contrôle unifié avec des capacités de gestion des ressources améliorées.
cgroup v2 propose plusieurs améliorations par rapport à cgroup v1, telles que :
Certaines fonctionnalités de Kubernetes utilisent exclusivement cgroup v2 pour une gestion des ressources et une isolation améliorées. Par exemple, la fonctionnalité MemoryQoS améliore la QoS de la mémoire et repose sur les primitives cgroup v2.
La manière recommandée d'utiliser cgroup v2 est d'utiliser une distribution Linux qui active et utilise cgroup v2 par défaut.
Pour vérifier si votre distribution utilise cgroup v2, consultez Identifier la version de cgroup sur les nœuds Linux.
cgroup v2 a les exigences suivantes :
Pour une liste des distributions Linux qui utilisent cgroup v2, consultez la documentation cgroup v2
Pour vérifier si votre distribution utilise cgroup v2, consultez la documentation de votre distribution ou suivez les instructions de Identifier la version de cgroup sur les nœuds Linux.
Vous pouvez également activer manuellement cgroup v2 sur votre distribution Linux en modifiant
les arguments de démarrage de la ligne de commande du noyau. Si votre distribution utilise GRUB,
systemd.unified_cgroup_hierarchy=1 doit être ajouté dans GRUB_CMDLINE_LINUX
sous /etc/default/grub, suivi de sudo update-grub.
Cependant, l'approche recommandée est d'utiliser une distribution qui active déjà cgroup v2 par
défaut.
Pour migrer vers cgroup v2, assurez-vous de respecter les exigences, puis mettez à jour vers une version du noyau qui active cgroup v2 par défaut.
Le kubelet détecte automatiquement si le système d'exploitation utilise cgroup v2 et agit en conséquence, sans nécessiter de configuration supplémentaire.
Il ne devrait pas y avoir de différence perceptible dans l'expérience utilisateur lors du passage à cgroup v2, sauf si les utilisateurs accèdent directement au système de fichiers cgroup soit sur le nœud, soit depuis les conteneurs.
cgroup v2 utilise une API différente de cgroup v1, donc si des applications accèdent directement au système de fichiers cgroup, elles doivent être mises à jour vers des versions plus récentes qui prennent en charge cgroup v2. Par exemple :
La version de cgroup dépend de la distribution Linux utilisée et de la
version de cgroup par défaut configurée sur le système d'exploitation. Pour vérifier quelle version de cgroup votre
distribution utilise, exécutez la commande stat -fc %T /sys/fs/cgroup/ sur
le nœud :
stat -fc %T /sys/fs/cgroup/
Pour cgroup v2, la sortie est cgroup2fs.
Pour cgroup v1, la sortie est tmpfs.
Le CRI (Container Runtime Interface) est une interface de plugin qui permet au kubelet d'utiliser une grande variété de runtimes de conteneurs, sans avoir besoin de recompiler les composants du cluster.
Vous avez besoin d'un runtime de conteneur fonctionnel sur chaque nœud de votre cluster, afin que le kubelet puisse lancer Pods et leurs conteneurs.
L'Interface de Runtime de Conteneur (CRI) est le protocole principal pour la communication entre le kubelet et le Runtime de Conteneur.
L'Interface du Runtime de Conteneur (CRI) de Kubernetes définit le protocole principal gRPC pour la communication entre les composants du nœud kubelet et le runtime de conteneur.
Kubernetes v1.23 [stable]
Le kubelet agit en tant que client lorsqu'il se connecte au runtime de conteneur via gRPC.
Les points de terminaison du service de runtime et d'image doivent être disponibles
dans le runtime de conteneur, ce qui peut être configuré séparément dans le kubelet
en utilisant les indicateurs de ligne de commande --image-service-endpoint (voir la référence des options du kubelet).
Pour Kubernetes v1.35, le kubelet préfère utiliser CRI v1.
Si un runtime de conteneur ne prend pas en charge v1 de CRI, alors le kubelet essaie de
négocier toute version plus ancienne prise en charge.
Le kubelet de v1.35 peut également négocier CRI v1alpha2, mais
cette version est considérée comme obsolète.
Si le kubelet ne peut pas négocier une version de CRI prise en charge, le kubelet abandonne
et ne s'enregistre pas en tant que nœud.
Lors de la mise à niveau de Kubernetes, le kubelet essaie de sélectionner automatiquement la dernière version de CRI lors du redémarrage du composant. Si cela échoue, alors le fallback aura lieu comme mentionné ci-dessus. Si une nouvelle connexion gRPC était nécessaire car le runtime de conteneur a été mis à niveau, alors le runtime de conteneur doit également prendre en charge la version initialement sélectionnée, sinon la reconnexion est censée échouer. Cela nécessite un redémarrage du kubelet.
Le Garbage collection est un terme générique désignant les différents mécanismes utilisés par Kubernetes pour nettoyer les ressources du cluster. Cela permet le nettoyage des ressources suivantes :
De nombreux objets dans Kubernetes sont liés les uns aux autres par le biais de références de propriétaire. Les références de propriétaire indiquent au plan de contrôle quels objets dépendent des autres. Kubernetes utilise les références de propriétaire pour permettre au plan de contrôle et aux autres clients de l'API de nettoyer les ressources associées avant de supprimer un objet. Dans la plupart des cas, Kubernetes gère automatiquement les références de propriétaire.
La propriété est différente du mécanisme étiquettes et sélecteurs
que certains ressources utilisent également. Par exemple, considérez un
Service qui crée des objets EndpointSlice.
Le Service utilise des étiquettes pour permettre au plan de contrôle de
déterminer quels objets EndpointSlice sont utilisés pour ce Service. En plus
des étiquettes, chaque EndpointSlice géré au nom d'un Service a
une référence de propriétaire. Les références de propriétaire aident les différentes parties de Kubernetes à éviter
d'interférer avec les objets qu'elles ne contrôlent pas.
Les références de propriétaire entre namespaces sont interdites par conception. Les dépendants dans un namespace peuvent spécifier des propriétaires à portée de cluster ou à portée de namespace. Un propriétaire à portée de namespace doit exister dans le même namespace que le dépendant. S'il n'existe pas, la référence de propriétaire est considérée comme absente et le dépendant est susceptible d'être supprimé une fois que tous les propriétaires sont vérifiés comme absents.
Les dépendants à portée de cluster ne peuvent spécifier que des propriétaires à portée de cluster. À partir de la version 1.20, si un dépendant à portée de cluster spécifie un type à portée de namespace en tant que propriétaire, il est considéré comme ayant une référence de propriétaire non résoluble et ne peut pas être collecté par le garbage collector.
À partir de la version 1.20, si le garbage collector détecte une référence de propriétaire non valide entre namespaces,
ou un dépendant à portée de cluster avec une référence de propriétaire faisant référence à un type à portée de namespace, un événement d'avertissement
avec une raison de OwnerRefInvalidNamespace et un involvedObject du dépendant non valide est signalé.
Vous pouvez vérifier ce type d'événement en exécutant
kubectl get events -A --field-selector=reason=OwnerRefInvalidNamespace.
Kubernetes vérifie et supprime les objets qui n'ont plus de références de propriétaire, comme les pods laissés derrière lors de la suppression d'un ReplicaSet. Lorsque vous supprimez un objet, vous pouvez contrôler si Kubernetes supprime automatiquement les objets dépendants, dans un processus appelé suppression en cascade. Il existe deux types de suppression en cascade, comme suit :
Vous pouvez également contrôler comment et quand la collecte des déchets supprime les ressources qui ont des références de propriétaire en utilisant les finalizers Kubernetes.
Dans la suppression en cascade en premier plan, l'objet propriétaire que vous supprimez entre d'abord dans un état de suppression en cours. Dans cet état, les actions suivantes se produisent sur l'objet propriétaire :
metadata.deletionTimestamp de l'objet sur l'heure à laquelle l'objet a été marqué pour suppression.metadata.finalizers sur foregroundDeletion.Après que l'objet propriétaire entre dans l'état de suppression en cours, le contrôleur supprime les dépendants. Après avoir supprimé tous les objets dépendants, le contrôleur supprime l'objet propriétaire. À ce stade, l'objet n'est plus visible dans l'API Kubernetes.
Pendant la suppression en cascade en premier plan, seuls les dépendants qui bloquent la suppression du propriétaire sont ceux qui ont le champ ownerReference.blockOwnerDeletion=true.
Consultez Utiliser la suppression en cascade en premier plan
pour en savoir plus.
Dans la suppression en cascade en arrière-plan, le serveur API Kubernetes supprime immédiatement l'objet propriétaire et le contrôleur nettoie les objets dépendants en arrière-plan. Par défaut, Kubernetes utilise la suppression en cascade en arrière-plan, sauf si vous utilisez manuellement la suppression en premier plan ou choisissez d'abandonner les objets dépendants.
Consultez Utiliser la suppression en cascade en arrière-plan pour en savoir plus.
Lorsque Kubernetes supprime un objet propriétaire, les dépendants laissés derrière sont appelés objets orphelins. Par défaut, Kubernetes supprime les objets dépendants. Pour apprendre comment outrepasser ce comportement, consultez Supprimer les objets propriétaires et les dépendants orphelins.
Le kubelet effectue la collecte des déchets sur les images inutilisées toutes les deux minutes et sur les conteneurs inutilisés toutes les minutes. Vous devez éviter d'utiliser des outils de collecte des déchets externes, car ils peuvent perturber le comportement du kubelet et supprimer des conteneurs qui devraient exister.
Pour configurer les options de collecte des déchets des conteneurs et des images inutilisés, ajustez le
kubelet en utilisant un fichier de configuration
et modifiez les paramètres liés à la collecte des déchets en utilisant le
type de ressource KubeletConfiguration.
Kubernetes gère le cycle de vie de toutes les images via son gestionnaire d'images, qui fait partie du kubelet, en collaboration avec cadvisor. Le kubelet prend en compte les limites d'utilisation du disque suivantes lors de la prise de décision de collecte des déchets :
HighThresholdPercentLowThresholdPercentUne utilisation du disque supérieure à la valeur configurée de HighThresholdPercent déclenche la collecte des déchets, qui supprime les images dans l'ordre en fonction de leur dernière utilisation,
en commençant par les plus anciennes en premier. Le kubelet supprime les images
jusqu'à ce que l'utilisation du disque atteigne la valeur LowThresholdPercent.
Kubernetes v1.35 [stable](enabled by default)En tant que fonctionnalité bêta, vous pouvez spécifier la durée maximale pendant laquelle une image locale peut rester inutilisée, indépendamment de l'utilisation du disque. Il s'agit d'un paramètre du kubelet que vous configurez pour chaque nœud.
Pour configurer le paramètre, activez la fonctionnalité ImageMaximumGCAge
feature gate pour le kubelet,
et définissez également une valeur pour le champ imageMaximumGCAge dans le fichier de configuration du kubelet.
La valeur est spécifiée en tant que durée Kubernetes ;
Les unités de temps valides pour le champ imageMaximumGCAge dans le fichier de configuration du kubelet sont :
Par exemple, vous pouvez définir le champ de configuration sur 12h45m,
ce qui signifie 12 heures et 45 minutes.
imageMaximumGCAge avant de qualifier les images pour la collecte des déchets
en fonction de l'âge de l'image.Le kubelet collecte les conteneurs inutilisés en fonction des variables suivantes, que vous pouvez définir :
MinAge : l'âge minimum auquel le kubelet peut collecter les
conteneurs. Désactivez en définissant sur 0.MaxPerPodContainer : le nombre maximum de conteneurs inactifs que chaque Pod
peut avoir. Désactivez en définissant sur une valeur inférieure à 0.MaxContainers : le nombre maximum de conteneurs inactifs que le cluster peut avoir.
Désactivez en définissant sur une valeur inférieure à 0.En plus de ces variables, le kubelet collecte les conteneurs non identifiés et supprimés, généralement en commençant par les plus anciens.
MaxPerPodContainer et MaxContainers peuvent potentiellement entrer en conflit les uns avec les autres
dans des situations où le maintien du nombre maximum de conteneurs par Pod
(MaxPerPodContainer) dépasserait le total autorisé de conteneurs inactifs globaux (MaxContainers). Dans cette situation, le kubelet ajuste
MaxPerPodContainer pour résoudre le conflit. Le pire des cas serait de
réduire MaxPerPodContainer à 1 et d'évacuer les conteneurs les plus anciens.
De plus, les conteneurs appartenant à des pods qui ont été supprimés sont supprimés une fois
qu'ils sont plus anciens que MinAge.
Vous pouvez ajuster la collecte des déchets des ressources en configurant des options spécifiques aux contrôleurs qui gèrent ces ressources. Les pages suivantes vous montrent comment configurer la collecte des déchets :
Kubernetes v1.28 [alpha](disabled by default)Kubernetes 1.35 inclut une fonctionnalité alpha qui permet à un Serveur API de faire proxy des demandes de ressources vers d'autres serveurs API pairs. Cela est utile lorsqu'il y a plusieurs serveurs API exécutant différentes versions de Kubernetes dans un même cluster (par exemple, pendant un déploiement à long terme vers une nouvelle version de Kubernetes).
Cela permet aux administrateurs de cluster de configurer des clusters hautement disponibles qui peuvent être mis à niveau plus en toute sécurité, en redirigeant les demandes de ressources (effectuées pendant la mise à niveau) vers le kube-apiserver correct. Ce proxy empêche les utilisateurs de voir des erreurs 404 Not Found inattendues qui découlent du processus de mise à niveau.
Ce mécanisme est appelé le Proxy de Version Mixte.
Assurez-vous que la fonctionnalité UnknownVersionInteroperabilityProxy feature gate
est activée lorsque vous démarrez le Serveur API :
kube-apiserver \
--feature-gates=UnknownVersionInteroperabilityProxy=true \
# arguments de ligne de commande requis pour cette fonctionnalité
--peer-ca-file=<chemin vers le certificat CA de kube-apiserver>
--proxy-client-cert-file=<chemin vers le certificat proxy de l'agrégateur>,
--proxy-client-key-file=<chemin vers la clé proxy de l'agrégateur>,
--requestheader-client-ca-file=<chemin vers le certificat CA de l'agrégateur>,
# requestheader-allowed-names peut être laissé vide pour autoriser n'importe quel nom commun
--requestheader-allowed-names=<noms communs valides pour vérifier le certificat client du proxy>,
# indicateurs facultatifs pour cette fonctionnalité
--peer-advertise-ip=`IP de ce kube-apiserver qui doit être utilisée par les pairs pour faire proxy des demandes`
--peer-advertise-port=`port de ce kube-apiserver qui doit être utilisé par les pairs pour faire proxy des demandes`
# ...et d'autres indicateurs comme d'habitude
Le kube-apiserver source réutilise les
indicateurs d'authentification client du serveur API existant
--proxy-client-cert-file et --proxy-client-key-file pour présenter son identité qui
sera vérifiée par son pair (le kube-apiserver de destination). Le serveur API de destination
vérifie cette connexion pair en fonction de la configuration que vous spécifiez en utilisant l'argument de ligne de commande
--requestheader-client-ca-file.
Pour authentifier les certificats de service du serveur de destination, vous devez configurer un ensemble de certificats
d'autorité de certification en spécifiant l'argument de ligne de commande --peer-ca-file au serveur API source.
Pour définir l'emplacement réseau d'un kube-apiserver que les pairs utiliseront pour faire proxy des demandes, utilisez les
arguments de ligne de commande --peer-advertise-ip et --peer-advertise-port pour kube-apiserver ou spécifiez
ces champs dans le fichier de configuration du serveur API.
Si ces indicateurs ne sont pas spécifiés, les pairs utiliseront la valeur de --advertise-address ou
--bind-address comme argument de ligne de commande pour le kube-apiserver.
Si ceux-ci ne sont pas définis non plus, l'interface par défaut de l'hôte est utilisée.
Lorsque vous activez le proxy de version mixte, la couche d'agrégation charge un filtre spécial qui effectue les opérations suivantes :
Lorsqu'un serveur API reçoit une demande de ressource, il vérifie d'abord quels serveurs API peuvent
servir la ressource demandée. Cette vérification se fait en utilisant l'API interne
StorageVersion.
Si la ressource est connue du serveur API qui a reçu la demande
(par exemple, GET /api/v1/pods/quelque-pod), la demande est traitée localement.
S'il n'y a pas d'objet StorageVersion interne trouvé pour la ressource demandée
(par exemple, GET /my-api/v1/my-resource) et que l'APIService configuré spécifie le proxy
vers un serveur API d'extension, ce proxy se fait en suivant le flux habituel
flow pour les API d'extension.
Si un objet StorageVersion interne valide est trouvé pour la ressource demandée
(par exemple, GET /batch/v1/jobs) et que le serveur API qui essaie de traiter la demande
(le serveur API de traitement) a l'API batch désactivée, alors le serveur API de traitement
récupère les serveurs API pairs qui servent le groupe d'API / version / ressource pertinent
(api/v1/batch dans ce cas) en utilisant les informations de l'objet StorageVersion récupéré.
Le serveur API de traitement fait ensuite proxy de la demande vers l'un des serveurs kube-apiservers pairs correspondants
qui sont conscients de la ressource demandée.
S'il n'y a aucun pair connu pour ce groupe d'API / version / ressource, le serveur API de traitement transmet la demande à sa propre chaîne de traitement qui devrait finalement renvoyer une réponse 404 ("Not Found").
Si le serveur API de traitement a identifié et sélectionné un serveur API pair, mais que ce pair échoue à répondre (pour des raisons telles que des problèmes de connectivité réseau ou une course de données entre la demande étant reçue et un contrôleur enregistrant les informations du pair dans le plan de contrôle), alors le serveur de traitement API répond avec une erreur 503 ("Service Unavailable").