Objets dans Kubernetes
Les objets Kubernetes sont des entités persistantes dans le système Kubernetes. Kubernetes utilise ces entités pour représenter l'état de votre cluster. Apprenez le modèle d'objet Kubernetes et comment travailler avec ces objets.
Cette page explique comment les objets Kubernetes sont représentés dans l'API Kubernetes et comment vous pouvez
les exprimer au format .yaml
.
Comprendre les objets Kubernetes
Les objets Kubernetes sont des entités persistantes dans le système Kubernetes. Kubernetes utilise ces
entités pour représenter l'état de votre cluster. Plus précisément, ils peuvent décrire :
- Les applications conteneurisées en cours d'exécution (et sur quels nœuds)
- Les ressources disponibles pour ces applications
- Les politiques régissant le comportement de ces applications, telles que les politiques de redémarrage, de mise à niveau et de tolérance aux pannes
Un objet Kubernetes est un "enregistrement d'intention" - une fois que vous avez créé l'objet, le système Kubernetes
travaillera constamment pour s'assurer que l'objet existe. En créant un objet, vous indiquez essentiellement
au système Kubernetes à quoi vous voulez que la charge de travail de votre cluster ressemble ;
c'est l'état souhaité de votre cluster.
Pour travailler avec les objets Kubernetes - que ce soit pour les créer, les modifier ou les supprimer - vous devrez utiliser l'
API Kubernetes. Lorsque vous utilisez l'interface de ligne de commande kubectl
, par exemple,
l'interface CLI effectue les appels d'API Kubernetes nécessaires pour vous.
Vous pouvez également utiliser l'API Kubernetes directement dans vos propres programmes en utilisant l'une des
Librairies clientes.
Spécification de l'objet et état
Presque tous les objets Kubernetes incluent deux champs d'objet imbriqués qui régissent
la configuration de l'objet : la spec
de l'objet et le status
de l'objet.
Pour les objets qui ont une spec
, vous devez la définir lors de la création de l'objet,
en fournissant une description des caractéristiques que vous souhaitez que la ressource ait :
son état souhaité.
Le status
décrit l'état actuel de l'objet, fourni et mis à jour
par le système Kubernetes et ses composants. Le
plan de contrôle Kubernetes
gère continuellement et activement l'état réel de chaque objet pour le faire correspondre à l'état souhaité que vous
avez fourni.
Par exemple : dans Kubernetes, un Déploiement est un objet qui peut représenter une
application en cours d'exécution sur votre cluster. Lorsque vous créez le Déploiement, vous
pouvez définir la spec
du Déploiement pour spécifier que vous souhaitez que trois répliques de
l'application soient en cours d'exécution. Le système Kubernetes lit la spec
du Déploiement
et démarre trois instances de votre application souhaitée - mettant à jour
le statut pour correspondre à votre spécification. Si l'une de ces instances venait à échouer
(un changement d'état), le système Kubernetes réagit à la différence
entre la spécification et le statut en effectuant une correction - dans ce cas, en démarrant
une instance de remplacement.
Pour plus d'informations sur la spécification de l'objet, l'état et les métadonnées, consultez la
Convention de l'API Kubernetes.
Description d'un objet Kubernetes
Lorsque vous créez un objet dans Kubernetes, vous devez fournir la spécification de l'objet qui décrit son
état souhaité, ainsi que des informations de base sur l'objet (comme un nom). Lorsque vous utilisez
l'API Kubernetes pour créer l'objet (directement ou via kubectl
), cette requête API doit
inclure ces informations au format JSON dans le corps de la requête.
Le plus souvent, vous fournissez les informations à kubectl
dans un fichier appelé manifeste.
Par convention, les manifestes sont en YAML (vous pouvez également utiliser le format JSON).
Des outils tels que kubectl
convertissent les informations d'un manifeste en JSON ou dans un autre format de sérialisation
pris en charge lors de l'envoi de la requête API via HTTP.
Voici un exemple de manifeste montrant les champs requis et la spécification de l'objet pour un
Déploiement Kubernetes :
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
Une façon de créer un Déploiement en utilisant un fichier manifeste comme celui ci-dessus est d'utiliser la
commande kubectl apply
dans l'interface
de ligne de commande kubectl
, en passant le fichier .yaml
en argument. Voici un exemple :
kubectl apply -f https://k8s.io/examples/application/deployment.yaml
La sortie est similaire à ceci :
deployment.apps/nginx-deployment created
Champs requis
Dans le manifeste (fichier YAML ou JSON) de l'objet Kubernetes que vous souhaitez créer, vous devrez définir des valeurs pour
les champs suivants :
apiVersion
- La version de l'API Kubernetes que vous utilisez pour créer cet objet
kind
- Le type d'objet que vous souhaitez créer
metadata
- Des données qui aident à identifier de manière unique l'objet, y compris une chaîne name
, un UID
et éventuellement un namespace
facultatif
spec
- L'état souhaité de l'objet
Le format précis de la spec
de l'objet est différent pour chaque objet Kubernetes et contient
des champs imbriqués spécifiques à cet objet. La Référence de l'API Kubernetes
peut vous aider à trouver le format de spécification pour tous les objets que vous pouvez créer avec Kubernetes.
Par exemple, consultez le champ spec
pour la référence de l'API Pod.
Pour chaque Pod, le champ .spec
spécifie le pod et son état souhaité (comme le nom de l'image du conteneur pour
chaque conteneur dans ce pod).
Un autre exemple de spécification d'objet est le
champ spec
pour l'API StatefulSet. Pour StatefulSet, le champ .spec
spécifie le StatefulSet et
son état souhaité.
Dans le .spec
d'un StatefulSet se trouve un modèle
pour les objets Pod. Ce modèle décrit les Pods que le contrôleur StatefulSet va créer afin de
satisfaire la spécification du StatefulSet.
Différents types d'objets peuvent également avoir différents .status
; encore une fois, les pages de référence de l'API
détailent la structure de ce champ .status
et son contenu pour chaque type d'objet différent.
Validation des champs côté serveur
À partir de Kubernetes v1.25, le serveur API offre une validation des champs côté serveur
field validation
qui détecte les champs non reconnus ou en double dans un objet. Il offre toutes les fonctionnalités
de kubectl --validate
côté serveur.
L'outil kubectl
utilise le drapeau --validate
pour définir le niveau de validation des champs. Il accepte les
valeurs ignore
, warn
et strict
, tout en acceptant également les valeurs true
(équivalent à strict
)
et false
(équivalent à ignore
). Le paramètre de validation par défaut pour kubectl
est --validate=true
.
Strict
- Validation stricte des champs, erreurs en cas d'échec de la validation
Warn
- La validation des champs est effectuée, mais les erreurs sont exposées sous forme d'avertissements plutôt que de refuser la requête
Ignore
- Aucune validation des champs côté serveur n'est effectuée
Lorsque kubectl
ne peut pas se connecter à un serveur API prenant en charge la validation des champs, il bascule
vers une validation côté client. Les versions de Kubernetes 1.27 et ultérieures offrent toujours une validation des champs ;
les versions antérieures de Kubernetes peuvent ne pas l'offrir. Si votre cluster est plus ancien que v1.27, consultez la documentation
de votre version de Kubernetes.
A suivre
Si vous débutez avec Kubernetes, lisez-en plus sur les sujets suivants :
La gestion des objets Kubernetes
explique comment utiliser kubectl
pour gérer les objets.
Vous devrez peut-être installer kubectl si vous ne l'avez pas déjà disponible.
Pour en savoir plus sur l'API Kubernetes en général, visitez :
Pour approfondir vos connaissances sur les objets dans Kubernetes, lisez d'autres pages de cette section :
1 - Kubernetes Object Management
L'outil en ligne de commande kubectl
prend en charge plusieurs façons différentes de créer et gérer des objets Kubernetes.
Ce document donne un aperçu des différentes approches.
Consultez le livre Kubectl pour plus de détails
sur la gestion des objets avec Kubectl.
Management techniques
Attention:
Un objet Kubernetes doit être géré en utilisant une seule technique. Mélanger et combiner des techniques pour le même objet entraîne un comportement indéfini.
Technique de gestion |
Opère sur |
Environnement recommandé |
Operateurs supportés |
Courbe d'apprentissage |
Commandes impératives |
Objets en direct |
Projets de développement |
1+ |
La plus basse |
Configuration impérative d'objet |
Fichiers individuels |
Projets de production |
1 |
Modérée |
Configuration déclarative d'objet |
Répertoires de fichiers |
Projets de production |
1+ |
La plus élevée |
Commandes impératives
Lors de l'utilisation de commandes impératives, un utilisateur opère directement sur des objets
en direct dans un cluster.
L'utilisateur fournit les opérations à la commande kubectl
en tant qu'arguments ou indicateurs.
C'est la méthode recommandée pour commencer ou exécuter une tâche ponctuelle dans un cluster.
Étant donné que cette technique opère directement sur des objets en direct,
elle ne fournit aucune historique des configurations précédentes.
Exemples
Exécutez une instance du conteneur nginx en créant un objet Deployment :
kubectl create deployment nginx --image nginx
Compromis
Avantages par rapport à la configuration d'objet :
- Les commandes sont exprimées par un seul mot d'action.
- Les commandes ne nécessitent qu'une seule étape pour apporter des modifications au cluster.
Inconvénients par rapport à la configuration d'objet :
- Les commandes ne s'intègrent pas aux processus de révision des modifications.
- Les commandes ne fournissent pas de piste d'audit associée aux modifications.
- Les commandes ne fournissent pas de source d'enregistrement, sauf ce qui est en direct.
- Les commandes ne fournissent pas de modèle pour créer de nouveaux objets.
Configuration impérative d'objet
Dans la configuration impérative d'objet, la commande kubectl spécifie
l'opération (créer, remplacer, etc.), des indicateurs facultatifs et au moins
un nom de fichier. Le fichier spécifié doit contenir une définition complète
de l'objet au format YAML ou JSON.
Consultez la référence de l'API
pour plus de détails sur les définitions d'objets.
Attention:
La commande impérative replace
remplace la spécification existante
par celle nouvellement fournie, en supprimant toutes les modifications
apportées à l'objet qui ne figurent pas dans le fichier de configuration.
Cette approche ne doit pas être utilisée avec des types de ressources
dont les spécifications sont mises à jour indépendamment du fichier de configuration.
Par exemple, les services de type LoadBalancer
ont leur champ externalIPs
mis à jour indépendamment de la configuration par le cluster.
Exemples
Créez les objets définis dans un fichier de configuration :
kubectl create -f nginx.yaml
Supprimez les objets définis dans deux fichiers de configuration :
kubectl delete -f nginx.yaml -f redis.yaml
Mettre à jour les objets définis dans un fichier de configuration
en écrasant la configuration en direct :
kubectl replace -f nginx.yaml
Compromis
Avantages par rapport aux commandes impératives :
- La configuration d'objet peut être stockée dans un système de contrôle de source tel que Git.
- La configuration d'objet peut s'intégrer à des processus tels que la révision des modifications avant la validation et les pistes d'audit.
- La configuration d'objet fournit un modèle pour créer de nouveaux objets.
Inconvénients par rapport aux commandes impératives :
- La configuration d'objet nécessite une compréhension de base du schéma de l'objet.
- La configuration d'objet nécessite une étape supplémentaire consistant à rédiger un fichier YAML.
Avantages par rapport à la configuration d'objet déclarative :
- Le comportement de la configuration d'objet impérative est plus simple et plus facile à comprendre.
- À partir de la version 1.5 de Kubernetes, la configuration d'objet impérative est plus mature.
Inconvénients par rapport à la configuration d'objet déclarative :
- La configuration d'objet impérative fonctionne mieux sur des fichiers, pas sur des répertoires.
- Les mises à jour des objets en direct doivent être reflétées dans les fichiers de configuration, sinon elles seront perdues lors du prochain remplacement.
Configuration déclarative d'objet
Lors de l'utilisation de la configuration déclarative d'objet, un utilisateur opère
sur des fichiers de configuration d'objet stockés localement,
mais l'utilisateur ne définit pas les opérations à effectuer sur les fichiers.
Les opérations de création, de mise à jour et de suppression sont automatiquement détectées par kubectl
pour chaque objet.
Cela permet de travailler sur des répertoires, où différentes opérations peuvent être nécessaires pour différents objets.
Note:
La configuration déclarative d'objet conserve les modifications apportées par d'autres,
même si les modifications ne sont pas fusionnées dans le fichier de configuration de l'objet.
Cela est possible en utilisant l'opération d'API patch
pour écrire uniquement les différences
observées, au lieu d'utiliser l'opération d'API replace
pour remplacer l'ensemble de la configuration
de l'objet.
Exemples
Traitez tous les fichiers de configuration d'objet dans le répertoire configs
et créez ou
appliquez les modifications aux objets en direct. Vous pouvez d'abord utiliser diff
pour voir quelles modifications vont être
apportées, puis appliquer les modifications :
kubectl diff -f configs/
kubectl apply -f configs/
Traiter récursivement les répertoires :
kubectl diff -R -f configs/
kubectl apply -R -f configs/
Compromis
Avantages par rapport à la configuration impérative d'objet :
- Les modifications apportées directement aux objets en direct sont conservées, même si elles ne sont pas fusionnées dans les fichiers de configuration.
- La configuration déclarative d'objet offre une meilleure prise en charge pour travailler sur des répertoires et détecte automatiquement les types d'opérations (création, patch, suppression) par objet.
Inconvénients par rapport à la configuration impérative d'objet :
- La configuration déclarative d'objet est plus difficile à déboguer et à comprendre lorsque les résultats sont inattendus.
- Les mises à jour partielles à l'aide de diffs créent des opérations de fusion et de patch complexes.
A suivre
2 - Noms et identifiants d'objets
Chaque objet dans votre cluster a un Nom qui est unique pour ce type de ressource.
Chaque objet Kubernetes a également un UID qui est unique dans l'ensemble de votre cluster.
Par exemple, vous ne pouvez avoir qu'un seul Pod nommé myapp-1234
dans le même namespace, mais vous pouvez avoir un Pod et un Déploiement qui sont chacun nommés myapp-1234
.
Pour les attributs fournis par l'utilisateur qui ne sont pas uniques, Kubernetes fournit des labels et des annotations.
Noms
Un texte fourni par le client qui fait référence à un objet dans une URL de ressource, comme /api/v1/pods/some-name
.
Seul un objet d'un certain type peut avoir un nom donné à la fois. Cependant, si vous supprimez l'objet, vous pouvez créer un nouvel objet avec le même nom.
Les noms doivent être uniques pour toutes les versions d'API
de la même ressource. Les ressources API sont distinguées par leur groupe API, leur type de ressource, leur label
(pour les ressources avec label) et leur nom. En d'autres termes, la version de l'API est sans importance dans ce contexte.
Note:
Dans les cas où les objets représentent une entité physique, comme un Noeud représentant un hôte physique, lorsque l'hôte est recréé sous le même nom sans supprimer et recréer le Noeud, Kubernetes considère le nouvel hôte comme l'ancien, ce qui peut entraîner des incohérences.
Voici quatre types de contraintes de nom couramment utilisées pour les ressources.
Noms de sous-domaine DNS
La plupart des types de ressources nécessitent un nom qui peut être utilisé comme un sous-domaine DNS
tel que défini dans RFC 1123.
Cela signifie que le nom doit :
- ne pas contenir plus de 253 caractères
- contenir uniquement des caractères alphanumériques minuscules, '-' ou '.'
- commencer par un caractère alphanumérique
- se terminer par un caractère alphanumérique
Noms de label RFC 1123
Certains types de ressources nécessitent que leurs noms suivent la norme des labels DNS
telle que définie dans RFC 1123.
Cela signifie que le nom doit :
- contenir au maximum 63 caractères
- contenir uniquement des caractères alphanumériques minuscules ou '-'
- commencer par un caractère alphanumérique
- se terminer par un caractère alphanumérique
Noms de label RFC 1035
Certains types de ressources nécessitent que leurs noms suivent la norme des labels DNS
telle que définie dans RFC 1035.
Cela signifie que le nom doit :
- contenir au maximum 63 caractères
- contenir uniquement des caractères alphanumériques minuscules ou '-'
- commencer par un caractère alphabétique
- se terminer par un caractère alphanumérique
Note:
La seule différence entre les normes des labels RFC 1035 et RFC 1123
est que les labels RFC 1123 sont autorisées à
commencer par un chiffre, tandis que les labels RFC 1035 ne peuvent commencer
qu'avec une lettre alphabétique minuscule.
Noms de segment de chemin
Certains types de ressources nécessitent que leurs noms puissent être encodés en toute sécurité en tant que
segment de chemin. En d'autres termes, le nom ne peut pas être "." ou ".." et le nom ne peut
pas contenir "/" ou "%".
Voici un exemple de manifeste pour un Pod nommé nginx-demo
.
apiVersion: v1
kind: Pod
metadata:
name: nginx-demo
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
Note:
Certains types de ressources ont des restrictions supplémentaires sur leurs noms.
UIDs
Chaîne de caractères générée par les systèmes Kubernetes pour identifier de manière unique les objets.
Chaque objet créé pendant toute la durée de vie d'un cluster Kubernetes possède un UID distinct. Il vise à distinguer les occurrences historiques d'entités similaires.
Les UIDs Kubernetes sont des identifiants universellement uniques (également connus sous le nom d'UUID).
Les UUID sont normalisés selon ISO/IEC 9834-8 et ITU-T X.667.
A suivre
3 - Labels et sélecteurs
Les labels sont des paires clé/valeur qui sont attachées aux
objets tels que les Pods.
Les labels sont destinées à être utilisées pour spécifier des attributs d'identification des objets
qui sont significatifs et pertinents pour les utilisateurs, mais n'impliquent pas directement de sémantique
au système principal. Les labels peuvent être utilisées pour organiser et sélectionner des sous-ensembles d'objets.
Les labels peuvent être attachées aux objets lors de leur création et ultérieurement
ajoutées et modifiées à tout moment. Chaque objet peut avoir un ensemble de labels clé/valeur
définies. Chaque clé doit être unique pour un objet donné.
"metadata": {
"labels": {
"key1" : "value1",
"key2" : "value2"
}
}
Les labels permettent des requêtes et des surveillances efficaces et sont idéaux pour une utilisation dans les interfaces utilisateur (UI) et les interfaces en ligne de commande (CLI). Les informations non identifiantes doivent être enregistrées à l'aide des annotations.
Motivation
Les labels permettent aux utilisateurs de mapper leurs propres structures organisationnelles sur les objets système de manière lâchement couplée, sans nécessiter aux clients de stocker ces mappings.
Les déploiements de services et les pipelines de traitement par lots sont souvent des entités multidimensionnelles (par exemple, plusieurs partitions ou déploiements, plusieurs pistes de version, plusieurs niveaux, plusieurs micro-services par niveau). La gestion nécessite souvent des opérations transversales, ce qui rompt l'encapsulation des représentations strictement hiérarchiques, en particulier les hiérarchies rigides déterminées par l'infrastructure plutôt que par les utilisateurs.
Exemples de labels :
"release" : "stable"
, "release" : "canary"
"environment" : "dev"
, "environment" : "qa"
, "environment" : "production"
"tier" : "frontend"
, "tier" : "backend"
, "tier" : "cache"
"partition" : "customerA"
, "partition" : "customerB"
"track" : "daily"
, "track" : "weekly"
Voici des exemples de label couramment utilisées; vous êtes libre de développer vos propres conventions. Gardez à l'esprit que la clé du label doit être unique pour un objet donné.
Syntaxe et jeu de caractères
Les labels sont des paires clé/valeur. Les clés de label valides ont deux segments : un préfixe facultatif et un nom, séparés par une barre oblique (/
). Le segment du nom est requis et ne doit pas dépasser 63 caractères, en commençant et en terminant par un caractère alphanumérique ([a-z0-9A-Z]
) avec des tirets (-
), des traits de soulignement (_
), des points (.
) et des caractères alphanumériques entre eux. Le préfixe est facultatif. S'il est spécifié, le préfixe doit être un sous-domaine DNS : une série de labels DNS séparées par des points (.
), ne dépassant pas 253 caractères au total, suivi d'une barre oblique (/
).
Si le préfixe est omis, la clé du label est considérée comme privée pour l'utilisateur. Les composants système automatisés (par exemple, kube-scheduler
, kube-controller-manager
, kube-apiserver
, kubectl
ou d'autres automatisations tierces) qui ajoutent des labels aux objets des utilisateurs finaux doivent spécifier un préfixe.
Les préfixes kubernetes.io/
et k8s.io/
sont réservés pour les composants principaux de Kubernetes.
Valeur de label valide :
- doit comporter 63 caractères ou moins (peut être vide),
- sauf s'il est vide, doit commencer et se terminer par un caractère alphanumérique (
[a-z0-9A-Z]
),
- peut contenir des tirets (
-
), des traits de soulignement (_
), des points (.
) et des caractères alphanumériques entre eux.
Par exemple, voici un manifeste pour un Pod qui a deux labels environment: production
et app: nginx
:
apiVersion: v1
kind: Pod
metadata:
name: label-demo
labels:
environment: production
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
Sélecteurs de labels
Contrairement aux noms et UIDs, les labels ne garantissent pas l'unicité. En général, nous nous attendons à ce que de nombreux objets portent les mêmes label(s).
Via un sélecteur de label, le client/utilisateur peut identifier un ensemble d'objets.
Le sélecteur de label est le principe de regroupement central dans Kubernetes.
L'API prend actuellement en charge deux types de sélecteurs : basés sur l'égalité et basés sur un ensemble.
Un sélecteur de label peut être composé de plusieurs exigences séparées par des virgules.
Dans le cas de plusieurs exigences, toutes doivent être satisfaites, donc le séparateur de virgule
agit comme un opérateur logique ET (&&
).
La signification des sélecteurs vides ou non spécifiés dépend du contexte,
et les types d'API qui utilisent des sélecteurs doivent documenter leur validité et leur signification.
Note:
Pour certains types d'API, tels que les ReplicaSets, les sélecteurs de labels de deux instances ne doivent pas se chevaucher dans un namespace, sinon le contrôleur peut considérer cela comme des instructions contradictoires et échouer à déterminer combien de répliques doivent être présentes.
Avertissement:
Pour les conditions basées sur l'égalité et les conditions basées sur un ensemble, il n'y a pas d'opérateur logique OU (||
).
Assurez-vous que vos déclarations de filtre sont structurées en conséquence.
Exigence basée sur l'égalité
Les exigences basées sur l'égalité ou l'inégalité permettent de filtrer par clés et valeurs de label.
Les objets correspondants doivent satisfaire toutes les contraintes de label spécifiées, bien qu'ils puissent également avoir des labels supplémentaires. Trois types d'opérateurs sont admis : =
, ==
, !=
.
Les deux premiers représentent l'égalité (et sont synonymes), tandis que le dernier représente l'inégalité.
Par exemple :
environment = production
tier != frontend
Le premier sélectionne toutes les ressources avec une clé égale à environment
et une valeur égale à production
.
Le second sélectionne toutes les ressources avec une clé égale à tier
et une valeur différente de frontend
,
ainsi que toutes les ressources sans labels avec la clé tier
. On peut filtrer les ressources en production
en excluant frontend
en utilisant l'opérateur virgule : environment=production,tier!=frontend
Un scénario d'utilisation pour une exigence de label basée sur l'égalité est de spécifier des critères de sélection de nœud pour les Pods. Par exemple, le Pod d'exemple ci-dessous sélectionne les nœuds où le label "accelerator" existe et est définie sur "nvidia-tesla-p100".
apiVersion: v1
kind: Pod
metadata:
name: cuda-test
spec:
containers:
- name: cuda-test
image: "registry.k8s.io/cuda-vector-add:v0.1"
resources:
limits:
nvidia.com/gpu: 1
nodeSelector:
accelerator: nvidia-tesla-p100
Exigence basée sur un ensemble
Les exigences basées sur un ensemble permettent de filtrer les clés en fonction d'un ensemble de valeurs.
Trois types d'opérateurs sont pris en charge : in
, notin
et exists
(uniquement l'identifiant de clé).
Par exemple :
environment in (production, qa)
tier notin (frontend, backend)
partition
!partition
- Le premier exemple sélectionne toutes les ressources avec une clé égale à
environment
et une valeur égale à production
ou qa
.
- Le deuxième exemple sélectionne toutes les ressources avec une clé égale à
tier
et des valeurs autres que frontend
et backend
, ainsi que toutes les ressources sans labels avec la clé tier
.
- Le troisième exemple sélectionne toutes les ressources incluant un label avec la clé
partition
; aucune valeur n'est vérifiée.
- Le quatrième exemple sélectionne toutes les ressources sans un label avec la clé
partition
; aucune valeur n'est vérifiée.
De même, le séparateur virgule agit comme un opérateur ET. Ainsi, pour filtrer les ressources avec une clé partition
(peu importe la valeur) et avec environment
différent de qa
, vous pouvez utiliser partition,environment notin (qa)
. Le sélecteur de label basé sur un ensemble est une forme générale d'égalité, car environment=production
est équivalent à environment in (production)
; de même pour !=
et notin
.
Les exigences basées sur un ensemble peuvent être mélangées avec des exigences basées sur l'égalité. Par exemple: partition in (customerA, customerB),environment!=qa
.
API
Filtrage LIST et WATCH
Pour les opérations list et watch, vous pouvez spécifier des sélecteurs de labels pour filtrer les ensembles d'objets retournés ; vous spécifiez le filtre à l'aide d'un paramètre de requête.
(Pour en savoir plus en détail sur les watches dans Kubernetes, lisez détection efficace des changements).
Les deux types d'exigences sont autorisés
(présentés ici tels qu'ils apparaîtraient dans une chaîne de requête d'URL) :
- exigences basées sur l'égalité :
?labelSelector=environment%3Dproduction,tier%3Dfrontend
- exigences basées sur un ensemble :
?labelSelector=environment+in+%28production%2Cqa%29%2Ctier+in+%28frontend%29
Les deux styles de sélecteurs de labels peuvent être utilisés pour lister ou surveiller des ressources via un client REST.
Par exemple, en ciblant apiserver
avec kubectl
et en utilisant une exigence basée sur l'égalité, on peut écrire :
kubectl get pods -l environment=production,tier=frontend
ou en utilisant des exigences basées sur un ensemble :
kubectl get pods -l 'environment in (production),tier in (frontend)'
Comme déjà mentionné, les exigences basées sur un ensemble sont plus expressives.
Par exemple, elles peuvent implémenter l'opérateur OU sur les valeurs :
kubectl get pods -l 'environment in (production, qa)'
ou restreindre la correspondance négative via l'opérateur notin :
kubectl get pods -l 'environment,environment notin (frontend)'
Définir des références dans les objets API
Certains objets Kubernetes, tels que les services
et les replicationcontrollers
, utilisent également des sélecteurs de labels pour spécifier des ensembles d'autres ressources, telles que les pods.
Service et ReplicationController
L'ensemble des pods ciblés par un service
est défini avec un sélecteur de labels.
De même, la population de pods qu'un replicationcontroller
doit gérer est également définie avec un sélecteur de labels.
Les sélecteurs de labels pour ces deux objets sont définis dans des fichiers json
ou yaml
en utilisant des maps,
et seules les exigences basées sur l'égalité sont prises en charge :
"selector": {
"component" : "redis",
}
ou
selector:
component: redis
Ce sélecteur (respectivement au format json
ou yaml
) est équivalent à component=redis
ou component in (redis)
.
Ressources prenant en charge les exigences basées sur un ensemble
Les nouvelles ressources, telles que Job
,
Deployment
,
ReplicaSet
et
DaemonSet
,
prennent également en charge les exigences basées sur un ensemble.
selector:
matchLabels:
component: redis
matchExpressions:
- { key: tier, operator: In, values: [cache] }
- { key: environment, operator: NotIn, values: [dev] }
matchLabels
est une carte de paires {clé, valeur}
. Une seule paire {clé, valeur}
dans la carte matchLabels
est équivalente à un élément de matchExpressions
, dont le champ key
est "clé", l'opérateur est "In" et le tableau values
contient uniquement "valeur". matchExpressions
est une liste d'exigences de sélecteur de pod. Les opérateurs valides incluent In, NotIn, Exists et DoesNotExist. Les ensembles de valeurs doivent être non vides dans le cas de In et NotIn. Toutes les exigences, à la fois de matchLabels
et de matchExpressions
, sont combinées avec un ET -- elles doivent toutes être satisfaites pour correspondre.
Sélection de jeux de nœuds
Un cas d'utilisation pour la sélection basée sur les labels est de restreindre l'ensemble des nœuds sur lesquels un pod peut être planifié. Consultez la documentation sur la sélection de nœuds pour plus d'informations.
Utilisation efficace des labels
Vous pouvez appliquer un seul label à n'importe quelle ressource, mais ce n'est pas toujours la meilleure pratique. Il existe de nombreux scénarios où plusieurs labels doivent être utilisés pour distinguer des ensembles de ressources les uns des autres.
Par exemple, différentes applications utiliseraient des valeurs différentes pour le label app
, mais une application multi-niveaux, telle que l'exemple guestbook, aurait également besoin de distinguer chaque niveau. Le frontend pourrait avoir les labels suivants:
labels:
app: guestbook
tier: frontend
while the Redis master and replica would have different tier
labels, and perhaps even an
additional role
label:
labels:
app: guestbook
tier: backend
role: master
and
labels:
app: guestbook
tier: backend
role: replica
Les labels permettent de découper les ressources selon n'importe quelle dimension spécifiée par un label :
kubectl apply -f examples/guestbook/all-in-one/guestbook-all-in-one.yaml
kubectl get pods -Lapp -Ltier -Lrole
NAME READY STATUS RESTARTS AGE APP TIER ROLE
guestbook-fe-4nlpb 1/1 Running 0 1m guestbook frontend <none>
guestbook-fe-ght6d 1/1 Running 0 1m guestbook frontend <none>
guestbook-fe-jpy62 1/1 Running 0 1m guestbook frontend <none>
guestbook-redis-master-5pg3b 1/1 Running 0 1m guestbook backend master
guestbook-redis-replica-2q2yf 1/1 Running 0 1m guestbook backend replica
guestbook-redis-replica-qgazl 1/1 Running 0 1m guestbook backend replica
my-nginx-divi2 1/1 Running 0 29m nginx <none> <none>
my-nginx-o0ef1 1/1 Running 0 29m nginx <none> <none>
kubectl get pods -lapp=guestbook,role=replica
NAME READY STATUS RESTARTS AGE
guestbook-redis-replica-2q2yf 1/1 Running 0 3m
guestbook-redis-replica-qgazl 1/1 Running 0 3m
Mise à jour des labels
Parfois, vous souhaiterez renommer les pods existants et d'autres ressources avant de créer de nouvelles ressources. Cela peut être fait avec kubectl label
.
Par exemple, si vous souhaitez étiqueter tous vos pods NGINX en tant que niveau frontend, exécutez :
kubectl label pods -l app=nginx tier=fe
pod/my-nginx-2035384211-j5fhi labeled
pod/my-nginx-2035384211-u2c7e labeled
pod/my-nginx-2035384211-u3t6x labeled
Ce premier filtre tous les pods avec le label "app=nginx", puis les labels avec "tier=fe".
Pour voir les pods que vous avez étiquetés, exécutez :
kubectl get pods -l app=nginx -L tier
NAME READY STATUS RESTARTS AGE TIER
my-nginx-2035384211-j5fhi 1/1 Running 0 23m fe
my-nginx-2035384211-u2c7e 1/1 Running 0 23m fe
my-nginx-2035384211-u3t6x 1/1 Running 0 23m fe
Cela affiche tous les pods "app=nginx", avec une colonne de label supplémentaire pour le niveau des pods (spécifié avec -L
ou --label-columns
).
Pour plus d'informations, veuillez consulter kubectl label.
A suivre
4 - Namespaces
Dans Kubernetes, les namespaces (espace de nommage en français) fournissent un mécanisme pour isoler des groupes de ressources au sein d'un seul cluster. Les noms des ressources doivent être uniques dans un namespace, mais pas à travers les namespaces. La portée basée sur les namespaces s'applique uniquement aux objets dans les namespaces (par exemple, les déploiements, les services, etc.) et non aux objets à l'échelle du cluster (par exemple, StorageClass, Nodes, PersistentVolumes, etc.).
Quand utiliser plusieurs namespaces
Les Namespaces sont destinés à être utilisés dans des environnements avec de nombreux utilisateurs répartis sur plusieurs équipes ou projets. Pour les clusters avec quelques dizaines d'utilisateurs, vous n'avez pas besoin de créer ou de penser aux namespaces. Commencez à utiliser les namespaces lorsque vous avez besoin des fonctionnalités qu'ils offrent.
Les namespaces fournissent une portée pour les noms. Les noms des ressources doivent être uniques dans un namespace, mais pas à travers les namespaces. Les namespaces ne peuvent pas être imbriqués les uns dans les autres et chaque ressource Kubernetes ne peut être présente que dans un seul namespace.
Les namespaces sont un moyen de diviser les ressources du cluster entre plusieurs utilisateurs (via des quotas de ressources).
Il n'est pas nécessaire d'utiliser plusieurs namespaces pour séparer légèrement différentes ressources, telles que différentes versions du même logiciel : utilisez des labels pour distinguer les ressources dans le même namespace.
Note:
Pour un cluster de production, envisagez de ne pas utiliser le namespace default
. Au lieu de cela, créez d'autres namespaces et utilisez-les.
namespaces initiaux
Kubernetes démarre avec quatre namespaces initiaux :
default
- Kubernetes inclut ce namespace afin que vous puissiez commencer à utiliser votre nouveau cluster sans avoir à créer d'namespace.
kube-node-lease
- ce namespace contient des objets Lease associés à chaque nœud. Les leases de nœud permettent au kubelet d'envoyer des contrôles afin que le plan de contrôle puisse détecter une défaillance du nœud.
kube-public
- ce namespace est lisible par tous les clients (y compris ceux qui ne sont pas authentifiés). ce namespace est principalement réservé à l'utilisation du cluster, au cas où certaines ressources devraient être visibles et lisibles publiquement dans l'ensemble du cluster. L'aspect public de ce namespace est seulement une convention, pas une exigence.
kube-system
- Le namespace pour les objets créés par le système Kubernetes.
Travailler avec les namespaces
La création et la suppression des namespaces sont décrites dans la documentation du guide d'administration pour les namespaces.
Note:
Évitez de créer des namespaces avec le préfixe kube-
, car il est réservé aux namespaces système de Kubernetes.
Affichage des namespaces
Vous pouvez lister les namespaces actuels dans un cluster en utilisant :
NAME STATUS AGE
default Active 1d
kube-node-lease Active 1d
kube-public Active 1d
kube-system Active 1d
Définir le namespace pour une requête
Pour définir le namespace pour une requête en cours, utilisez le drapeau --namespace
.
Par exemple :
kubectl run nginx --image=nginx --namespace=<insérer-nom-du-namespace-ici>
kubectl get pods --namespace=<insérer-nom-du-namespace-ici>
Définir la préférence de namespace
Vous pouvez enregistrer de manière permanente le namespace pour toutes les commandes kubectl ultérieures dans ce contexte.
kubectl config set-context --current --namespace=<insérer-nom-du-namespace-ici>
# Validez-le
kubectl config view --minify | grep namespace:
Namespaces et DNS
Lorsque vous créez un Service,
cela crée une entrée DNS correspondante.
Cette entrée est de la forme <nom-du-service>.<nom-du-namespace>.svc.cluster.local
, ce qui signifie
que si un conteneur utilise uniquement <nom-du-service>
, il résoudra vers le service
qui est local à un namespace. Cela est utile pour utiliser la même configuration à travers
plusieurs namespaces tels que Développement, Staging et Production. Si vous souhaitez accéder
à travers les namespaces, vous devez utiliser le nom de domaine complet (FQDN).
En conséquence, tous les noms de namespace doivent être valides
DNS RFC 1123.
Attention:
En créant des namespaces avec le même nom que des domaines de premier niveau publics, les Services dans ces
espaces de noms peuvent avoir des noms DNS courts qui se chevauchent avec des enregistrements DNS publics.
Les charges de travail de n'importe quel namespace effectuant une recherche DNS sans un point final seront
redirigées vers ces services, prenant le pas sur les DNS publics.
Pour atténuer cela, limitez les privilèges de création de namespaces aux utilisateurs de confiance. Si
nécessaire, vous pouvez également configurer des contrôles de sécurité tiers, tels que des
admission
webhooks,
pour bloquer la création de tout namespace avec le nom de TLDs publics.
Tous les objets ne sont pas dans un namespace
La plupart des ressources Kubernetes (par exemple, les pods, les services, les contrôleurs de réplication, et autres) se trouvent dans des namespaces. Cependant, les ressources de namespace elles-mêmes ne se trouvent pas dans un namespace. Et les ressources de bas niveau, telles que les nœuds et les persistentVolumes, ne se trouvent dans aucun namespace.
Pour voir quelles ressources Kubernetes se trouvent ou ne se trouvent pas dans un namespace :
# Dans un namespace
kubectl api-resources --namespaced=true
# Pas dans un namespace
kubectl api-resources --namespaced=false
Étiquetage automatique
FEATURE STATE:
Kubernetes 1.22 [stable]
Le plan de contrôle de Kubernetes définit un label immuable kubernetes.io/metadata.name
sur tous les namespaces.
La valeur du label est le nom du namespace.
A suivre
5 - Annotations
Vous pouvez utiliser les annotations Kubernetes pour attacher des métadonnées non identifiantes arbitraires aux objets.
Les clients tels que les outils et les bibliothèques peuvent récupérer ces métadonnées.
Attacher des métadonnées aux objets
Vous pouvez utiliser des labels ou des annotations pour attacher des métadonnées aux objets Kubernetes. Les labels peuvent être utilisées pour sélectionner des objets et trouver des collections d'objets qui satisfont certaines conditions. En revanche, les annotations ne sont pas utilisées pour identifier et sélectionner des objets. Les métadonnées dans une annotation peuvent être petites ou grandes, structurées ou non structurées, et peuvent inclure des caractères non autorisés par les labels. Il est possible d'utiliser des labels ainsi que des annotations dans les métadonnées du même objet.
Les annotations, comme les labels, sont des cartes clé/valeur :
"metadata": {
"annotations": {
"key1" : "value1",
"key2" : "value2"
}
}
Note:
Les clés et les valeurs dans la carte doivent être des chaînes de caractères. En d'autres termes, vous ne pouvez pas utiliser des types numériques, booléens, listes ou autres pour les clés ou les valeurs.
Voici quelques exemples d'informations qui pourraient être enregistrées dans les annotations :
-
Champs gérés par une couche de configuration déclarative. Attacher ces champs en tant qu'annotations les distingue des valeurs par défaut définies par les clients ou les serveurs, et des champs générés automatiquement et des champs définis par des systèmes de dimensionnement ou de mise à l'échelle automatique.
-
Informations de build, de version ou d'image comme les horodatages, les identifiants de version, les branches git, les numéros de PR, les hachages d'image et l'adresse du registre.
-
Pointeurs vers des dépôts de journalisation, de surveillance, d'analyse ou d'audit.
-
Informations sur la bibliothèque cliente ou l'outil qui peuvent être utilisées à des fins de débogage : par exemple, nom, version et informations de build.
-
Informations de provenance de l'utilisateur ou de l'outil/système, telles que les URL d'objets connexes provenant d'autres composants de l'écosystème.
-
Métadonnées d'outil de déploiement léger : par exemple, configuration ou points de contrôle.
-
Numéros de téléphone ou de pager des personnes responsables, ou entrées d'annuaire spécifiant où ces informations peuvent être trouvées, comme un site web d'équipe.
-
Directives de l'utilisateur final aux implémentations pour modifier le comportement ou activer des fonctionnalités non standard.
Au lieu d'utiliser des annotations, vous pourriez stocker ce type d'informations dans une base de données ou un annuaire externe, mais cela rendrait beaucoup plus difficile la production de bibliothèques clientes et d'outils partagés pour le déploiement, la gestion, l'introspection, etc.
Syntaxe et jeu de caractères
Les Annotations sont des paires clé/valeur. Les clés d'annotation valides ont deux segments : un préfixe optionnel et un nom, séparés par une barre oblique (/
). Le segment de nom est requis et doit comporter 63 caractères ou moins, commencer et se terminer par un caractère alphanumérique ([a-z0-9A-Z]
) avec des tirets (-
), des underscores (_
), des points (.
), et des alphanumériques entre. Le préfixe est optionnel. S'il est spécifié, le préfixe doit être un sous-domaine DNS : une série de labels DNS séparées par des points (.
), ne dépassant pas 253 caractères au total, suivie d'une barre oblique (/
).
Si le préfixe est omis, la clé d'annotation est présumée être privée pour l'utilisateur. Les composants système automatisés (par exemple, kube-scheduler
, kube-controller-manager
, kube-apiserver
, kubect
l`, ou autre automatisation tierce) qui ajoutent des annotations aux objets des utilisateurs finaux doivent spécifier un préfixe.
Les préfixes kubernetes.io/
et k8s.io/
sont réservés aux composants de base de Kubernetes.
Par exemple, voici un manifeste pour un Pod qui a l'annotation imageregistry: https://hub.docker.com/
:
apiVersion: v1
kind: Pod
metadata:
name: annotations-demo
annotations:
imageregistry: "https://hub.docker.com/"
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
A suivre
6 - Sélecteurs de champs
Les sélecteurs de champs vous permettent de sélectionner des objets Kubernetes en fonction de la valeur d'un ou plusieurs champs de ressources. Voici quelques exemples de requêtes de sélecteurs de champs :
metadata.name=my-service
metadata.namespace!=default
status.phase=Pending
Cette commande kubectl
sélectionne tous les Pods pour lesquels la valeur du champ status.phase
est Running
:
kubectl get pods --field-selector status.phase=Running
Note:
Les sélecteurs de champs sont essentiellement des filtres de ressources. Par défaut, aucun sélecteur/filtre n'est appliqué, ce qui signifie que toutes les ressources du type spécifié sont sélectionnées. Cela rend les requêtes kubectl get pods
et kubectl get pods --field-selector ""
équivalentes.
Champs pris en charge
Les sélecteurs de champs pris en charge varient en fonction du type de ressource Kubernetes. Tous les types de ressources prennent en charge les champs metadata.name
et metadata.namespace
. L'utilisation de sélecteurs de champs non pris en charge génère une erreur. Par exemple :
kubectl get ingress --field-selector foo.bar=baz
Erreur du serveur (BadRequest) : Impossible de trouver des "ingresses" correspondant au sélecteur de labels "", au sélecteur de champs "foo.bar=baz" : "foo.bar" n'est pas un sélecteur de champ connu : seuls "metadata.name", "metadata.namespace"
Liste des champs pris en charge
Kind |
Champs |
Pod |
spec.nodeName
spec.restartPolicy
spec.schedulerName
spec.serviceAccountName
spec.hostNetwork
status.phase
status.podIP
status.nominatedNodeName |
Event |
involvedObject.kind
involvedObject.namespace
involvedObject.name
involvedObject.uid
involvedObject.apiVersion
involvedObject.resourceVersion
involvedObject.fieldPath
reason
reportingComponent
source
type |
Secret |
type |
Namespace |
status.phase |
ReplicaSet |
status.replicas |
ReplicationController |
status.replicas |
Job |
status.successful |
Node |
spec.unschedulable |
CertificateSigningRequest |
spec.signerName |
Opérateurs pris en charge
Vous pouvez utiliser les opérateurs =
, ==
et !=
avec les sélecteurs de champs (=
et ==
signifient la même chose). Cette commande kubectl
, par exemple, sélectionne tous les services Kubernetes qui ne sont pas dans le namespace default
:
kubectl get services --all-namespaces --field-selector metadata.namespace!=default
Note:
Les opérateurs basés sur les ensembles (in
, notin
, exists
) ne sont pas pris en charge pour les sélecteurs de champs.
Sélecteurs enchaînés
Comme pour les labels et autres sélecteurs, les sélecteurs de champs peuvent être enchaînés ensemble sous forme d'une liste séparée par des virgules. Cette commande kubectl
sélectionne tous les Pods pour lesquels le champ status.phase
n'est pas égal à Running
et le champ spec.restartPolicy
est égal à Always
:
kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always
Types de ressources multiples
Vous pouvez utiliser des sélecteurs de champs sur plusieurs types de ressources. Cette commande kubectl
sélectionne tous les Statefulsets et Services qui ne sont pas dans le namespace default
:
kubectl get statefulsets,services --all-namespaces --field-selector metadata.namespace!=default
7 - Finalisateurs
Les finalizers sont des clés des namespaces qui indiquent à Kubernetes d'attendre que certaines
conditions soient remplies avant de supprimer complètement les ressources marquées pour la suppression.
Les finalizers alertent les contrôleurs pour nettoyer les ressources appartenant à l'objet supprimé.
Lorsque vous demandez à Kubernetes de supprimer un objet qui a des finalizers spécifiés,
l'API Kubernetes marque l'objet pour la suppression en remplissant le champ .metadata.deletionTimestamp
,
et renvoie un code d'état 202
(HTTP "Accepté"). L'objet cible reste dans un état de terminaison pendant que le
plan de contrôle, ou d'autres composants, effectuent les actions définies par les finalizers.
Une fois ces actions terminées, le contrôleur supprime les finalizers pertinents
de l'objet cible. Lorsque le champ metadata.finalizers
est vide,
Kubernetes considère la suppression comme terminée et supprime l'objet.
Vous pouvez utiliser des finalizers pour contrôler la collecte des déchets
des ressources. Par exemple, vous pouvez définir un finalizer pour nettoyer les ressources ou
l'infrastructure associée avant que le contrôleur ne supprime la ressource cible.
Vous pouvez utiliser des finalisateurs pour contrôler la collecte des déchets
des objets en alertant les contrôleurs
d'effectuer des tâches de nettoyage spécifiques avant de supprimer la ressource cible.
Les finalisateurs ne spécifient généralement pas le code à exécuter. Au lieu de cela, ils sont
généralement des listes de clés sur une ressource spécifique similaires aux annotations.
Kubernetes spécifie automatiquement certains finalisateurs, mais vous pouvez également spécifier
les vôtres.
Lorsque vous créez une ressource à l'aide d'un fichier de manifeste, vous pouvez spécifier des finalisateurs dans
le champ metadata.finalizers
. Lorsque vous tentez de supprimer la ressource, le
serveur API traitant la demande de suppression remarque les valeurs dans le champ finalizers
et effectue les opérations suivantes :
- Modifie l'objet pour ajouter un champ
metadata.deletionTimestamp
avec l'heure de début de la suppression.
- Empêche la suppression de l'objet tant que tous les éléments sont supprimés de son champ
metadata.finalizers
- Renvoie un code d'état
202
(HTTP "Accepté")
Le contrôleur gérant ce finaliseur remarque la mise à jour de l'objet en définissant le
metadata.deletionTimestamp
, indiquant que la suppression de l'objet a été demandée.
Le contrôleur tente ensuite de satisfaire les exigences des finalisateurs
spécifiés pour cette ressource. Chaque fois qu'une condition de finaliseur est satisfaite, le
contrôleur supprime cette clé du champ finalizers
de la ressource. Lorsque le
champ finalizers
est vidé, un objet avec un champ deletionTimestamp
défini
est automatiquement supprimé. Vous pouvez également utiliser des finalisateurs pour empêcher la suppression de ressources non gérées.
Un exemple courant de finaliseur est kubernetes.io/pv-protection
, qui empêche
la suppression accidentelle des objets PersistentVolume
. Lorsqu'un objet PersistentVolume
est utilisé par un Pod, Kubernetes ajoute le finaliseur pv-protection
. Si vous
essayez de supprimer le PersistentVolume
, il passe à l'état Terminating
, mais le
contrôleur ne peut pas le supprimer car le finaliseur existe. Lorsque le Pod cesse
d'utiliser le PersistentVolume
, Kubernetes supprime le finaliseur pv-protection
,
et le contrôleur supprime le volume.
Note:
-
Lorsque vous DELETE
un objet, Kubernetes ajoute le timestamp de suppression pour cet objet, puis
commence immédiatement à restreindre les modifications du champ .metadata.finalizers
pour l'objet qui est
maintenant en attente de suppression. Vous pouvez supprimer les finalisateurs existants (supprimer une entrée de la liste des finalizers
)
mais vous ne pouvez pas ajouter un nouveau finaliseur. Vous ne pouvez pas non plus modifier le deletionTimestamp
d'un
objet une fois qu'il est défini.
-
Après que la suppression a été demandée, vous ne pouvez pas ressusciter cet objet. La seule solution est de le supprimer et de créer un nouvel objet similaire.
Références de propriétaire, labels et finalisateurs
Comme les labels,
les références de propriétaire
décrivent les relations entre les objets dans Kubernetes, mais sont utilisées à
une fin différente. Lorsqu'un
contrôleur gère des objets
comme des Pods, il utilise des labels pour suivre les modifications apportées à des groupes d'objets liés. Par
exemple, lorsqu'un Job crée un ou
plusieurs Pods, le contrôleur de Job applique des labels à ces pods et suit les modifications apportées à
tous les Pods du cluster ayant le même label.
Le contrôleur de Job ajoute également des références de propriétaire à ces Pods, pointant vers le
Job qui a créé les Pods. Si vous supprimez le Job pendant que ces Pods sont en cours d'exécution,
Kubernetes utilise les références de propriétaire (pas les labels) pour déterminer quels Pods dans le
cluster ont besoin d'un nettoyage.
Kubernetes traite également les finalisateurs lorsqu'il identifie des références de propriétaire sur une
ressource destinée à la suppression.
Dans certaines situations, les finalisateurs peuvent bloquer la suppression d'objets dépendants,
ce qui peut entraîner le maintien de l'objet propriétaire ciblé pendant
plus longtemps que prévu sans être entièrement supprimé. Dans ces situations, vous
devriez vérifier les finalisateurs et les références de propriétaire sur l'objet propriétaire cible et les objets dépendants
pour résoudre le problème.
Note:
Dans les cas où les objets restent bloqués dans un état de suppression, évitez de supprimer manuellement
les finalisateurs pour permettre la poursuite de la suppression. Les finalisateurs sont généralement ajoutés
aux ressources pour une raison, donc les supprimer de force peut entraîner des problèmes dans
votre cluster. Cela ne doit être fait que lorsque le but du finaliseur est
compris et est accompli d'une autre manière (par exemple, nettoyage manuel
de certains objets dépendants).
A suivre
8 - Propriétaires et dépendants
Dans Kubernetes, certains objets sont
propriétaires d'autres objets. Par exemple, un
ReplicaSet est le propriétaire
d'un ensemble de Pods. Ces objets dépendants sont les dépendants de leur propriétaire.
La propriété est différente du mécanisme labels et sélecteurs
que certains ressources utilisent également. Par exemple, considérez un Service qui
crée des objets EndpointSlice
. Le Service utilise des label pour permettre au plan de contrôle de
déterminer quels objets EndpointSlice
sont utilisés pour ce Service. En plus
des labels, 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 différentes parties de Kubernetes à éviter
d'interférer avec des objets qu'elles ne contrôlent pas.
Références de propriétaire dans les spécifications d'objet
Les objets dépendants ont un champ metadata.ownerReferences
qui référence leur
objet propriétaire. Une référence de propriétaire valide est composée du nom de l'objet et d'un UID
dans le même namespace que l'objet dépendant. Kubernetes définit automatiquement la valeur de
ce champ pour les objets qui sont des dépendants d'autres objets comme
ReplicaSets, DaemonSets, Deployments, Jobs et CronJobs, et ReplicationControllers.
Vous pouvez également configurer ces relations manuellement en modifiant la valeur de
ce champ. Cependant, vous n'avez généralement pas besoin de le faire et pouvez permettre à Kubernetes de
gérer automatiquement les relations.
Les objets dépendants ont également un champ ownerReferences.blockOwnerDeletion
qui
prend une valeur booléenne et contrôle si des dépendants spécifiques peuvent bloquer la suppression
de leur objet propriétaire par la collecte des déchets. Kubernetes définit automatiquement ce
champ à true
si un contrôleur
(par exemple, le contrôleur de déploiement) définit la valeur du champ
metadata.ownerReferences
. Vous pouvez également définir manuellement la valeur du
champ blockOwnerDeletion
pour contrôler quels dépendants bloquent la collecte des déchets.
Un contrôleur d'admission Kubernetes contrôle l'accès utilisateur pour modifier ce champ pour
les ressources dépendantes, en fonction des autorisations de suppression du propriétaire. Ce contrôle
empêche les utilisateurs non autorisés de retarder la suppression de l'objet propriétaire.
Note:
Les références de propriétaire entre espaces de noms 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 la collecte des déchets.
À partir de la version 1.20, si le collecteur de déchets détecte une référence de propriétaire invalide entre espaces de noms,
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 invalide est signalé.
Vous pouvez vérifier ce type d'événement en exécutant
kubectl get events -A --field-selector=reason=OwnerRefInvalidNamespace
.
Propriété et finalisateurs
Lorsque vous demandez à Kubernetes de supprimer une ressource, le serveur API permet au
contrôleur de gestion de traiter toutes les règles de finalisation
pour la ressource. Les Finalizer
empêchent la suppression accidentelle de ressources dont votre cluster peut encore avoir besoin
pour fonctionner correctement. Par exemple, si vous essayez de supprimer un PersistentVolume qui est encore
utilisé par un Pod, la suppression ne se produit pas immédiatement car le
PersistentVolume
a le finaliseur kubernetes.io/pv-protection
.
Au lieu de cela, le volume reste dans l'état Terminating
jusqu'à ce que Kubernetes supprime
le finaliseur, ce qui se produit uniquement après que le PersistentVolume
n'est plus
lié à un Pod.
Kubernetes ajoute également des finalisateurs à une ressource propriétaire lorsque vous utilisez soit
la suppression en premier plan ou la suppression en cascade des orphelins](/docs/concepts/architecture/garbage-collection/#cascading-deletion).
Dans la suppression en premier plan, il ajoute le finaliseur foreground
de sorte que le
contrôleur doit supprimer les ressources dépendantes qui ont également
ownerReferences.blockOwnerDeletion=true
avant de supprimer le propriétaire. Si vous
spécifiez une politique de suppression des orphelins, Kubernetes ajoute le finaliseur orphan
de sorte
que le contrôleur ignore les ressources dépendantes après avoir supprimé l'objet propriétaire.
A suivre
9 - labels recommandées
Vous pouvez visualiser et gérer les objets Kubernetes avec plus d'outils que kubectl et le tableau de bord. Un ensemble commun de labels permet aux outils de fonctionner de manière interopérable, en décrivant les objets de manière commune que tous les outils peuvent comprendre.
En plus de prendre en charge les outils, les labels recommandées décrivent les applications de manière à pouvoir être interrogées.
Les métadonnées sont organisées autour du concept d'une application. Kubernetes n'est pas une plateforme en tant que service (PaaS) et n'a pas de notion formelle d'une application. Au lieu de cela, les applications sont informelles et décrites avec des métadonnées. La définition de ce qu'une application contient est vague.
Note:
Ce sont des labels recommandées. Elles facilitent la gestion des applications mais ne sont pas requises pour les outils principaux.
Les labels et annotations partagées ont un préfixe commun : app.kubernetes.io
. Les labels sans préfixe sont privées aux utilisateurs. Le préfixe partagé garantit que les labels partagées n'interfèrent pas avec les labels personnalisées des utilisateurs.
labels
Afin de tirer pleinement parti de l'utilisation de ces labels, elles doivent être appliquées à chaque objet de ressource.
Clé |
Description |
Exemple |
Type |
app.kubernetes.io/name |
Le nom de l'application |
mysql |
string |
app.kubernetes.io/instance |
Un nom unique identifiant l'instance d'une application |
mysql-abcxyz |
string |
app.kubernetes.io/version |
La version actuelle de l'application (par exemple, un SemVer 1.0, un hachage de révision, etc.) |
5.7.21 |
string |
app.kubernetes.io/component |
Le composant au sein de l'architecture |
database |
string |
app.kubernetes.io/part-of |
Le nom d'une application de niveau supérieur dont celle-ci fait partie |
wordpress |
string |
app.kubernetes.io/managed-by |
L'outil utilisé pour gérer le fonctionnement d'une application |
Helm |
string |
Pour illustrer ces labels en action, considérez l'objet StatefulSet suivant :
# Ceci est un extrait
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
app.kubernetes.io/name: mysql
app.kubernetes.io/instance: mysql-abcxyz
app.kubernetes.io/version: "5.7.21"
app.kubernetes.io/component: database
app.kubernetes.io/part-of: wordpress
app.kubernetes.io/managed-by: Helm
Applications et instances d'applications
Une application peut être installée une ou plusieurs fois dans un cluster Kubernetes et, dans certains cas, dans le même namespace. Par exemple, WordPress peut être installé plusieurs fois où différents sites Web sont différentes installations de WordPress.
Le nom d'une application et le nom de l'instance sont enregistrés séparément. Par exemple, WordPress a un app.kubernetes.io/name
de wordpress
tandis qu'il a un nom d'instance, représenté par app.kubernetes.io/instance
avec une valeur de wordpress-abcxyz
. Cela permet d'identifier l'application et l'instance de l'application. Chaque instance d'une application doit avoir un nom unique.
Exemples
Pour illustrer les différentes façons d'utiliser ces labels, les exemples suivants ont une complexité variable.
Un service simple sans état
Considérez le cas d'un service simple sans état déployé à l'aide d'objets Deployment
et Service
. Les deux extraits suivants représentent comment les labels pourraient être utilisées dans leur forme la plus simple.
Le Deployment
est utilisé pour superviser les pods exécutant l'application elle-même.
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/name: myservice
app.kubernetes.io/instance: myservice-abcxyz
...
Le Service
est utilisé pour exposer l'application.
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/name: myservice
app.kubernetes.io/instance: myservice-abcxyz
...
Application Web avec une base de données
Considérez une application légèrement plus complexe : une application web (WordPress) utilisant une base de données (MySQL), installée à l'aide de Helm. Les extraits suivants illustrent le début des objets utilisés pour déployer cette application.
Le début du Deployment
suivant est utilisé pour WordPress :
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/name: wordpress
app.kubernetes.io/instance: wordpress-abcxyz
app.kubernetes.io/version: "4.9.4"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: server
app.kubernetes.io/part-of: wordpress
...
Le Service
est utilisé pour exposer WordPress :
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/name: wordpress
app.kubernetes.io/instance: wordpress-abcxyz
app.kubernetes.io/version: "4.9.4"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: server
app.kubernetes.io/part-of: wordpress
...
MySQL est exposé en tant que StatefulSet
avec des métadonnées à la fois pour lui-même et pour l'application plus large à laquelle il appartient :
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
app.kubernetes.io/name: mysql
app.kubernetes.io/instance: mysql-abcxyz
app.kubernetes.io/version: "5.7.21"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: database
app.kubernetes.io/part-of: wordpress
...
Le Service
est utilisé pour exposer MySQL en tant que partie de WordPress:
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/name: mysql
app.kubernetes.io/instance: mysql-abcxyz
app.kubernetes.io/version: "5.7.21"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: database
app.kubernetes.io/part-of: wordpress
...
Avec le StatefulSet
MySQL et le Service
, vous remarquerez que des informations sur à la fois MySQL et WordPress, l'application plus large, sont incluses.