
Structure de base d'un fichier YAML (apiVersion, kind, metadata, spec)
Maîtrisez la structure essentielle d'un fichier manifeste Kubernetes. Ce guide détaille les rôles cruciaux des champs apiVersion, kind, metadata et spec pour définir vos ressources.
Les piliers d'un manifeste Kubernetes : une vue d'ensemble
Tout manifeste Kubernetes, qu'il décrive un simple Pod ou un ensemble complexe de services, repose sur une structure commune définie par quatre champs principaux. Ces champs sont la clé pour que Kubernetes comprenne quel type de ressource vous souhaitez créer ou modifier, comment l'identifier et quel état désiré elle doit atteindre. Une compréhension approfondie de `apiVersion`, `kind`, `metadata` et `spec` est donc indispensable pour quiconque souhaite interagir efficacement avec un cluster Kubernetes via des fichiers de configuration.
Ces quatre champs de haut niveau constituent l'ossature de votre déclaration d'intention auprès de l'API Kubernetes. Ils ne sont pas optionnels ; leur présence et leur correcte valorisation sont impératives pour la validation et le traitement du manifeste. Chacun joue un rôle distinct mais complémentaire, contribuant à la nature déclarative et à la robustesse du système. Examinons en détail la fonction et l'importance de chacun de ces éléments fondamentaux.
Pensez à ces champs comme aux informations d'en-tête d'un document officiel : `apiVersion` et `kind` définissent le type et la version du formulaire que vous remplissez, `metadata` contient les informations d'identification du signataire et de l'objet concerné, et `spec` détaille le contenu spécifique de votre demande. Sans ces informations claires, votre requête (le manifeste) ne pourrait être comprise ni traitée par l'administration (le cluster Kubernetes).
Le champ `apiVersion` : spécifier la version de l'API Kubernetes
Le champ `apiVersion` indique la version de l'API Kubernetes que vous utilisez pour créer l'objet. Kubernetes est un système en évolution rapide, et ses APIs sont versionnées pour permettre l'introduction de nouvelles fonctionnalités, la modification de structures existantes ou la dépréciation d'anciennes, tout en maintenant une certaine compatibilité ascendante. Ce champ est crucial car il informe le serveur API Kubernetes (kube-apiserver) sur la manière d'interpréter le schéma de l'objet défini dans le reste du manifeste.
Les versions d'API dans Kubernetes peuvent être simples comme `v1` (pour les objets "core" stables comme les Pods, Services, Namespaces) ou groupées comme `apps/v1` (pour les Deployments, StatefulSets, DaemonSets), `batch/v1` (pour les Jobs), `rbac.authorization.k8s.io/v1` (pour les rôles et liaisons de rôles), etc. Le groupe d'API permet d'organiser logiquement les fonctionnalités et d'éviter les conflits de noms. Les versions peuvent également avoir des suffixes indiquant leur maturité : `alpha` (expérimental, peut être retiré sans préavis), `beta` (testé, mais la sémantique peut changer de manière incompatible), ou une version stable (ex: `v1`, `v2`).
Il est impératif de consulter la documentation Kubernetes pour connaître la `apiVersion` correcte à utiliser pour un `kind` d'objet donné. Utiliser une `apiVersion` incorrecte ou inexistante pour un `kind` spécifique entraînera une erreur lors de la tentative d'application du manifeste, par exemple avec `kubectl apply`. Kubernetes ne pourra pas valider ni traiter un objet dont la version d'API n'est pas reconnue ou ne correspond pas au type d'objet.
Par exemple, si vous définissez un Déploiement, vous utiliserez typiquement `apiVersion: apps/v1`. Si vous définissez un Service, ce sera `apiVersion: v1`. Cette distinction est fondamentale pour que Kubernetes sache quel schéma de validation et quel contrôleur utiliser pour la ressource. Le choix de `apiVersion` influence directement les champs disponibles et leur comportement dans la section `spec`.
Le champ `kind` : identifier le type d'objet Kubernetes
Le champ `kind` est une chaîne de caractères qui spécifie le type d'objet Kubernetes que votre manifeste décrit. C'est ce champ qui dit à Kubernetes si vous souhaitez créer un `Pod`, un `Service`, un `Deployment`, un `ConfigMap`, un `Secret`, un `Namespace`, un `Ingress`, ou l'un des nombreux autres types de ressources disponibles. Chaque `kind` correspond à une abstraction spécifique au sein de Kubernetes, avec sa propre logique de gestion et son propre ensemble de spécifications.
La valeur du champ `kind` doit correspondre exactement à l'un des types d'objets reconnus par la `apiVersion` que vous avez spécifiée. Par exemple, sous `apiVersion: v1`, vous trouverez des `kind` tels que `Pod`, `Service`, `PersistentVolumeClaim`. Sous `apiVersion: apps/v1`, vous aurez des `kind` comme `Deployment` ou `ReplicaSet`. Il existe une relation directe et stricte entre `apiVersion` et les `kind` qu'elle supporte.
Le `kind` est déterminant car il dicte la structure et les champs attendus dans la section `spec` du manifeste. Un `Deployment` aura une `spec` très différente de celle d'un `Service` ou d'un `PersistentVolume`. Le serveur API utilise le `kind` pour savoir comment valider la section `spec` et quel contrôleur est responsable de la gestion de cet objet une fois créé.
Comprendre la finalité de chaque `kind` est essentiel pour modéliser correctement vos applications. Voulez-vous simplement exécuter un conteneur ? Un `Pod` pourrait suffire (bien que rarement utilisé seul en production). Voulez-vous gérer un ensemble de Pods répliqués avec des mises à jour progressives ? Un `Deployment` est alors le `kind` approprié. Besoin d'exposer ces Pods via une adresse IP stable ? Un `Service` s'impose.
Le champ `metadata` : nommer et organiser vos ressources
La section `metadata` contient des informations permettant d'identifier et de qualifier l'objet Kubernetes que vous définissez. Elle ne décrit pas le comportement de l'objet (c'est le rôle de `spec`), mais plutôt ses caractéristiques d'identification et d'organisation. Plusieurs sous-champs sont couramment utilisés au sein de `metadata`.
Le sous-champ le plus important est `name`. Il attribue un nom unique à cette instance d'objet au sein d'un `namespace` donné. Par exemple, `name: mon-application-web`. Ce nom sera utilisé pour référencer l'objet dans les commandes `kubectl` (ex: `kubectl get pod mon-application-web`) et par d'autres objets Kubernetes (par exemple, un Service ciblant des Pods par leur nom).
Le sous-champ `namespace` permet de spécifier l'espace de noms dans lequel l'objet doit être créé. Les namespaces sont un moyen d'isoler des groupes de ressources au sein d'un même cluster physique. Si `namespace` n'est pas spécifié, l'objet est créé dans le namespace `default`, ou dans le namespace actif configuré pour le contexte `kubectl` courant. Utiliser des namespaces est une bonne pratique pour organiser les ressources par projet, environnement (développement, production) ou équipe.
Les `labels` (étiquettes) sont des paires clé-valeur arbitraires que vous attachez aux objets. Par exemple, `app: frontend` ou `environment: production`. Les labels sont extrêmement puissants car ils permettent d'organiser et de sélectionner des sous-ensembles d'objets. De nombreux objets Kubernetes, comme les Services ou les Deployments, utilisent des sélecteurs basés sur les labels pour identifier les objets qu'ils gèrent ou ciblent. Par exemple, un Service peut cibler tous les Pods ayant le label `app: backend`.
Enfin, les `annotations` sont similaires aux labels (paires clé-valeur) mais sont utilisées pour stocker des métadonnées non identifiantes. Contrairement aux labels, les annotations ne sont pas utilisées pour sélectionner des objets. Elles servent souvent à ajouter des informations descriptives, des pointeurs vers des outils de monitoring, des informations de build, ou des configurations spécifiques à des contrôleurs personnalisés. Par exemple : `description: "Serveur web principal pour le site e-commerce"`.
Le champ `spec` : définir l'état désiré de la ressource
La section `spec` (abréviation de "specification") est le coeur de votre manifeste Kubernetes. C'est ici que vous décrivez l'état désiré de l'objet que vous créez ou modifiez. Le contenu et la structure de la section `spec` sont entièrement déterminés par le `kind` (et implicitement par l'`apiVersion`) de l'objet.
Contrairement aux autres champs qui sont relativement fixes dans leur structure, la `spec` est hautement variable. Chaque type d'objet Kubernetes a son propre schéma de `spec` avec des champs spécifiques à sa fonction. Par exemple :
- Pour un `Pod` (`kind: Pod`), la `spec` contiendra typiquement une liste de `containers`, chacun décrivant une image à utiliser, les ports à exposer, les variables d'environnement, les volumes à monter, etc. Exemple :
spec: containers: - name: mon-conteneur image: nginx:latest ports: - containerPort: 80 - Pour un `Deployment` (`kind: Deployment`), la `spec` définira le nombre de `replicas` (instances de Pods) souhaitées, un `selector` pour identifier les Pods qu'il gère, et un `template` qui décrit le Pod à créer (ce template contient lui-même une section `metadata` et `spec` pour le Pod). Exemple partiel :
spec: replicas: 3 selector: matchLabels: app: mon-app template: metadata: labels: app: mon-app spec: containers: - name: serveur-app image: mon-image-app:1.0 - Pour un `Service` (`kind: Service`), la `spec` indiquera comment exposer un ensemble de Pods, notamment via un `selector` pour cibler les Pods par leurs labels, une liste de `ports` (définissant le port du Service, le port cible sur les Pods, et potentiellement le `nodePort`), et le `type` de Service (ex: `ClusterIP`, `NodePort`, `LoadBalancer`). Exemple :
spec: selector: app: mon-backend ports: - protocol: TCP port: 8080 targetPort: 80 type: NodePort
C'est en interprétant la `spec` que les contrôleurs Kubernetes travaillent pour faire converger l'état actuel du cluster vers l'état que vous avez déclaré. Si vous modifiez la `spec` d'un objet existant et appliquez le manifeste mis à jour, Kubernetes s'efforcera d'atteindre ce nouvel état désiré (par exemple, en changeant le nombre de réplicas d'un Deployment, ou en mettant à jour l'image d'un conteneur).
La maîtrise de la `spec` pour les objets Kubernetes les plus courants est essentielle pour exploiter pleinement la puissance de la plateforme. La documentation officielle de Kubernetes est la référence incontournable pour découvrir tous les champs disponibles et leur signification pour chaque `kind` d'objet.
Synthèse : un exemple concret de structure YAML
Pour récapituler, examinons un manifeste YAML complet pour un objet `Deployment` simple. Cet exemple illustre comment les quatre champs fondamentaux s'articulent :
# apiVersion: Spécifie la version de l'API pour l'objet Deployment
apiVersion: apps/v1
# kind: Définit le type d'objet comme étant un Deployment
kind: Deployment
# metadata: Contient les informations d'identification de ce Deployment
metadata:
# name: Nom unique de ce Deployment dans son namespace
name: mon-premier-deploiement
# labels: Etiquettes pour organiser et sélectionner ce Deployment
labels:
app: mon-app-web
environnement: test
# spec: Décrit l'état désiré pour ce Deployment
spec:
# replicas: Nombre désiré d'instances de Pods
replicas: 2
# selector: Définit comment le Deployment trouve les Pods à gérer
selector:
matchLabels:
app: mon-app-web # Doit correspondre aux labels du template de Pod
# template: Décrit le Pod que ce Deployment va créer et gérer
template:
metadata:
# labels pour les Pods créés par ce Deployment
labels:
app: mon-app-web # Ce label est utilisé par le selector ci-dessus
spec:
# Spécifications pour les conteneurs à l'intérieur des Pods
containers:
- name: conteneur-web
image: nginx:1.25 # L'image Docker à utiliser
ports:
- containerPort: 80 # Le port que le conteneur exposeDans cet exemple, `apiVersion: apps/v1` et `kind: Deployment` indiquent clairement que nous définissons un objet de type Déploiement utilisant la version `apps/v1` de l'API. La section `metadata` lui donne un nom (`mon-premier-deploiement`) et des labels (`app: mon-app-web`, `environnement: test`). La section `spec` détaille l'état désiré : 2 réplicas d'un Pod (`replicas: 2`), dont le template est également défini (`template`). Ce template de Pod a ses propres `metadata` (avec le label `app: mon-app-web` crucial pour le `selector` du Deployment) et sa propre `spec` (définissant un conteneur Nginx).
La compréhension de cette structure `apiVersion`, `kind`, `metadata`, `spec` est la base sur laquelle repose toute interaction déclarative avec Kubernetes. Une fois ces concepts maîtrisés, vous serez en mesure de lire, comprendre et écrire des manifestes pour une grande variété de besoins applicatifs et infrastructurels.