>
E-NO
Kubernetes 8 min de lecture

Configuration d'un laboratoire local de définitions de ressources personnalisées Kubernetes avec exemples pratiques

calendar_today Publié : 2026-08-28
update Dernière mise à jour : 2026-08-28
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Configuration d'un laboratoire local de définitions de ressources personnalisées Kubernetes avec exemples pratiques ».

Introduction

Les définitions de ressources personnalisées (Custom Resource Definitions, CRD) Kubernetes vous permettent d'étendre l'API Kubernetes avec vos propres types de ressources. Cet article présente une configuration complète de laboratoire local pour les CRD, destinée aux développeurs, aux consultants DevOps et aux équipes techniques de startups. Il relie la configuration, les tests, les exemples et le développement des CRD Kubernetes à des commandes spécifiques, des sorties attendues, des signaux d'échec et des décisions de récupération.

L'objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des espaces réservés au lieu de secrets, vérifier le résultat et documenter comment récupérer si l'état attendu n'est pas atteint. À la fin, vous disposerez d'un environnement local reproductible, d'exemples de CRD fonctionnels et de modèles de dépannage que vous pourrez appliquer à vos propres opérateurs.

Inventaire des versions et de l'environnement

Avant d'appliquer toute CRD, vous devez connaître votre environnement. Cette section couvre les plages de versions prises en charge, les prérequis, l'observation en lecture seule, le plus petit changement justifié et les commandes de vérification.

Prérequis et vérifications de version

Pour le développement local de CRD, vous avez besoin d'un cluster Kubernetes. Le moyen le plus simple est d'utiliser kind (Kubernetes in Docker), minikube ou le Kubernetes de Docker Desktop. Nous utiliserons kind dans cet article car il est léger et scriptable. Assurez-vous d'avoir installé :

  • kubectl (v1.25 ou version ultérieure recommandée)
  • kind (v0.17.0 ou version ultérieure)
  • Docker (pour les nœuds kind)
  • jq (facultatif, pour filtrer les sorties JSON)

Vérifiez les versions :

kubectl version --client
# Exemple de sortie : Client Version: v1.27.3

kind version
# Exemple de sortie : kind v0.20.0 go1.20.4 linux/amd64

docker version --format '{{.Server.Version}}'
# Exemple de sortie : 24.0.2

Observation en lecture seule

Avant d'apporter des modifications, observez l'état actuel du cluster. Si vous n'avez pas encore de cluster, créez-en un, mais vérifiez d'abord si un cluster est déjà configuré :

kubectl config current-context
# Exemple de sortie : kind-kind (s'il existe déjà) ou une erreur s'il n'y en a pas

Si vous voyez un contexte, inspectez ses nœuds et la version du serveur API :

kubectl get nodes
# Exemple de sortie : NAME                 STATUS   ROLES           AGE   VERSION
#                  kind-control-plane   Ready    control-plane   10m   v1.27.3

kubectl version --short
# Exemple de sortie : Client Version: v1.27.3
#                 Server Version: v1.27.3

S'il n'existe pas de cluster, créez-en un pour ce laboratoire :

kind create cluster --name crd-lab --image kindest/node:v1.27.3
# Exemple de sortie :
# Creating cluster "crd-lab" ...
#  ✓ Ensuring node image (kindest/node:v1.27.3) 🖼
#  ✓ Preparing nodes 📦
#  ✓ Writing configuration 📜
#  ✓ Starting control-plane 🕹️
#  ✓ Installing CNI 🔌
#  ✓ Installing StorageClass 💾
# Set kubectl context to "kind-crd-lab"

Maintenant, définissez le contexte sur le nouveau cluster :

kubectl config use-context kind-crd-lab
# Exemple de sortie : Switched to context "kind-crd-lab".

Plus petit changement justifié

Maintenant que nous avons un cluster, nous allons ajouter une CustomResourceDefinition. Une CRD définit un nouveau type et son schéma. Nous commencerons par une CRD minimale pour une ressource fictive Widget.

Créez un fichier widget-crd.yaml :

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: widgets.example.com
spec:
  group: example.com
  names:
    kind: Widget
    listKind: WidgetList
    plural: widgets
    singular: widget
  scope: Namespaced
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                size:
                  type: integer
                  minimum: 1
                  maximum: 10
                color:
                  type: string
                  enum: [red, green, blue]
              required: [size, color]

Cette CRD définit une ressource à espace de noms widgets dans le groupe example.com, avec un schéma qui exige size (entier entre 1 et 10) et color (un parmi red, green, blue). Appliquez-la :

kubectl apply -f widget-crd.yaml
# Exemple de sortie : customresourcedefinition.apiextensions.k8s.io/widgets.example.com created

Vérifiez que la CRD est établie :

kubectl get crd widgets.example.com
# Exemple de sortie :
# NAME                    CREATED AT
# widgets.example.com     2023-07-01T12:00:00Z

Vérifiez ses conditions :

kubectl get crd widgets.example.com -o jsonpath='{.status.conditions[?(@.type=="Established")].status}'
# Exemple de sortie : True

Désormais, le cluster dispose d'un nouveau point de terminaison API. Vous pouvez lister les ressources personnalisées (actuellement aucune) :

kubectl get widgets
# Exemple de sortie : No resources found in default namespace.

Question rapide 1 sur 2

Quel est l'objectif d'une CustomResourceDefinition (CRD) dans Kubernetes ?

Selon la référence, la ressource d'API CustomResourceDefinition vous permet de définir des ressources personnalisées. La définition d'un objet CRD crée une nouvelle ressource personnalisée avec un nom et un schéma que vous spécifiez.

Chemin de configuration sûr

Dans cette section, nous étendons la CRD précédente à un scénario plus réaliste : une ressource personnalisée à espace de noms avec des valeurs par défaut de validation, des colonnes d'impression supplémentaires et un modèle de contrôleur simple simulé via un script shell. Nous couvrons également comment apporter des modifications sûres et revenir en arrière si nécessaire.

CRD à espace de noms avec sous-ressource de statut

Ajoutez une sous-ressource de statut et des colonnes d'impression pour rendre kubectl get plus informatif. Modifiez widget-crd.yaml (ou créez un nouveau fichier widget-crd-v2.yaml) :

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: widgets.example.com
spec:
  group: example.com
  names:
    kind: Widget
    listKind: WidgetList
    plural: widgets
    singular: widget
    shortNames:
      - wd
  scope: Namespaced
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                size:
                  type: integer
                  minimum: 1
                  maximum: 10
                color:
                  type: string
                  enum: [red, green, blue]
              required: [size, color]
            status:
              type: object
              properties:
                phase:
                  type: string
                  enum: [Pending, Running, Failed]
                message:
                  type: string
      subresources:
        status: {}
      additionalPrinterColumns:
        - name: Size
          type: integer
          jsonPath: .spec.size
        - name: Color
          type: string
          jsonPath: .spec.color
        - name: Phase
          type: string
          jsonPath: .status.phase

Appliquez la CRD mise à jour :

kubectl apply -f widget-crd-v2.yaml
# Exemple de sortie : customresourcedefinition.apiextensions.k8s.io/widgets.example.com configured

Remarque : la mise à jour d'une CRD est un changement sûr si vous ajoutez uniquement des champs, des sous-ressources ou des colonnes d'impression. La suppression de champs ou la modification de la validation peut affecter les ressources personnalisées existantes.

Créez maintenant un exemple de Widget :

cat <<EOF | kubectl apply -f -
apiVersion: example.com/v1
kind: Widget
metadata:
  name: my-widget
  namespace: default
spec:
  size: 5
  color: blue
EOF
# Exemple de sortie : widget.example.com/my-widget created

Vérifiez-le avec les colonnes personnalisées :

kubectl get widgets
# Exemple de sortie :
# NAME        SIZE   COLOR   PHASE
# my-widget   5      blue

Simulation d'un contrôleur avec une boucle de surveillance Bash

Un vrai contrôleur surveille les changements et met à jour le statut. Pour la sécurité, nous pouvons simuler un contrôleur minimal à l'aide d'une boucle shell qui liste tous les widgets et définit un statut si aucun n'existe. Ce n'est pas de qualité production, mais cela démontre le modèle.

Tout d'abord, créez un petit script simple-controller.sh :

#!/usr/bin/env bash
set -euo pipefail

while true; do
  for widget in $(kubectl get widgets -o jsonpath='{.items[*].metadata.name}'); do
    phase=$(kubectl get widget "$widget" -o jsonpath='{.status.phase}')
    if [ -z "$phase" ]; then
      echo "Setting status for $widget to Pending"
      kubectl patch widget "$widget" --type merge -p '{"status":{"phase":"Pending","message":"Processing"}}'
    fi
  done
  sleep 10
done

Rendez-le exécutable et lancez-le dans un terminal séparé (ou en arrière-plan) :

chmod +x simple-controller.sh
./simple-controller.sh

Après quelques secondes, vérifiez le statut du widget :

kubectl get widget my-widget -o yaml
# Extrait de sortie attendu :
# status:
#   message: Processing
#   phase: Pending

Cela démontre comment un contrôleur peut gérer les mises à jour de statut en toute sécurité à l'aide de kubectl patch avec stratégie de fusion.

Retour en arrière et récupération

Si vous appliquez une modification de CRD qui casse les ressources existantes, vous pouvez parfois revenir en arrière en appliquant un manifeste précédent. Conservez les manifestes versionnés dans un référentiel Git. Par exemple, pour revenir à la v1 :

kubectl apply -f widget-crd.yaml
# Exemple de sortie : customresourcedefinition.apiextensions.k8s.io/widgets.example.com configured

Si une mise à jour de CRD invalide des ressources personnalisées existantes, vous devrez peut-être modifier ou supprimer ces ressources d'abord. Testez toujours dans un laboratoire local avant de toucher à la production.

Vérification et diagnostics

La vérification ne se limite pas à kubectl apply ; il s'agit de confirmer que la ressource se comporte comme prévu. Cette section fournit des contrôles concrets, des signaux d'échec courants et des commandes de diagnostic.

Vérification fonctionnelle du schéma de la CRD

Le schéma que nous avons défini applique des contraintes. Essayez de créer un widget avec une couleur invalide :

cat <<EOF | kubectl apply -f -
apiVersion: example.com/v1
kind: Widget
metadata:
  name: bad-widget
spec:
  size: 7
  color: purple
EOF
# Erreur attendue :
# The Widget "bad-widget" is invalid: spec.color: Unsupported value: "purple": supported values: "red", "green", "blue"

Le serveur API rejette la demande avant de la stocker. Cela confirme que la validation du schéma fonctionne.

Testez les limites de taille :

cat <<EOF | kubectl apply -f -
apiVersion: example.com/v1
kind: Widget
metadata:
  name: big-widget
spec:
  size: 11
  color: red
EOF
# Erreur attendue :
# The Widget "big-widget" is invalid: spec.size: Invalid value: 11: spec.size in body should be less than or equal to 10

Commandes de diagnostic pour les problèmes de CRD

Si votre CRD ne s'établit pas, vérifiez ses conditions de statut et ses événements.

kubectl describe crd widgets.example.com
# Recherchez les événements en bas, par exemple :
# Events:
#   Type     Reason                 Age   From                            Message
#   Warning  NonStructuralSchema    2m    customresourcedefinition-api   spec.validation.openAPIV3Schema.type: Required value: must not be empty at the root

Signaux d'échec courants :

  • NonStructuralSchema : Le schéma n'est pas structurel (par exemple, il manque type: object).
  • NoServedVersions : La liste versions est vide ou toutes les versions ont served: false.
  • Terminating : La CRD est bloquée en suppression en raison de finaliseurs.

Si vous voyez Terminating, inspectez les finaliseurs :

kubectl get crd widgets.example.com -o jsonpath='{.metadata.finalizers}'
# Exemple de sortie : ["customresourcecleanup.apiextensions.k8s.io"]

Si vous devez forcer la suppression (uniquement en laboratoire, pas en production), supprimez le finaliseur :

kubectl patch crd widgets.example.com -p '{"metadata":{"finalizers":[]}}' --type=merge
# Exemple de sortie : customresourcedefinition.apiextensions.k8s.io/widgets.example.com patched

Vérifiez ensuite s'il disparaît.

Vérification du comportement du contrôleur

Si votre contrôleur personnalisé ne détecte pas les changements, vérifiez ses journaux. Comme notre contrôleur simple s'exécute dans un shell local, sa sortie va au terminal. Dans un vrai pod, vous utiliseriez :

kubectl logs <controller-pod-name>

Problèmes courants de contrôleur :

  • Mauvaise configuration RBAC : Le contrôleur n'a pas la permission de lister/surveiller les widgets. Vérifiez avec kubectl auth can-i list widgets --as=system:serviceaccount:default:controller-sa
  • CRD non servie : kubectl get widgets renvoie l'erreur "the server could not find the requested resource". Assurez-vous que la CRD est appliquée et que served: true.
  • Dépréciation de l'API : Si vous utilisez une ancienne version d'API, assurez-vous d'utiliser apiextensions.k8s.io/v1 (pas v1beta1).

Question rapide 2 sur 2

Quel est le format correct pour le champ metadata.name d'une CRD ?

La référence indique : 'le nom doit correspondre aux champs spec ci-dessous et être sous la forme : <plural>.<group>'. L'exemple utilise 'crontabs.stable.example.com'.

Modes de défaillance et récupération

Les opérateurs doivent prévoir les défaillances. Cette section détaille les modes de défaillance courants pour les CRD et les ressources personnalisées, ainsi que les étapes de récupération.

Mode de défaillance : la suppression de la CRD laisse des ressources personnalisées orphelines

Lorsque vous supprimez une CRD, toutes les ressources personnalisées de ce type sont supprimées immédiatement (récupérées par le ramasse-miettes). Si vous supprimez accidentellement une CRD avec des données importantes, vous risquez de perdre des ressources. La récupération nécessite des sauvegardes.

Avant de supprimer une CRD, sauvegardez toutes les ressources personnalisées :

kubectl get widgets -o yaml > widgets-backup.yaml

Si vous supprimez la CRD et devez la restaurer, recréez d'abord la CRD, puis réappliquez la sauvegarde :

kubectl delete crd widgets.example.com
# Exemple de sortie : customresourcedefinition.apiextensions.k8s.io "widgets.example.com" deleted

# Maintenant, recréez la CRD (en supposant que votre manifeste est sauvegardé)
kubectl apply -f widget-crd.yaml
# Puis restaurez les ressources
kubectl apply -f widgets-backup.yaml

Mais notez : si les ressources personnalisées avaient des champs de statut, ils peuvent ne pas être conservés car les sauvegardes capturées avant la suppression peuvent manquer le statut. Meilleure pratique : utilisez un outil de sauvegarde comme Velero.

Mode de défaillance : un schéma trop restrictif bloque les mises à jour

Si un schéma empêche des mises à jour légitimes en raison d'un nouveau champ, vous pouvez assouplir le schéma en ajoutant le champ comme facultatif. Exemple : ajoutez un champ description au schéma :

spec:
  description:
    type: string

Appliquez la CRD mise à jour, et les ressources existantes ne sont pas affectées car le champ est facultatif.

Pour éviter les changements cassants, suivez ces règles :

  • Ne supprimez jamais un champ du schéma.
  • Ne modifiez jamais le type d'un champ.
  • Ajoutez uniquement de nouveaux champs facultatifs.

Pour les changements majeurs, introduisez une nouvelle version d'API (par exemple, v2) et laissez les anciennes ressources migrer progressivement.

Mode de défaillance : mauvaise configuration du webhook de conversion

Si vous utilisez des webhooks de conversion pour plusieurs versions, un webhook mal configuré peut casser tous les appels API pour la CRD. Pour récupérer, patchez la CRD pour supprimer la stratégie de conversion ou réparer le service webhook.

Exemple : vérifiez les paramètres de conversion :

kubectl get crd widgets.example.com -o jsonpath='{.spec.conversion}'
# Exemple de sortie : {"strategy":"Webhook","webhook":{"clientConfig":{"service":{"name":"conversion-webhook","namespace":"default","path":"/convert","port":443}},"conversionReviewVersions":["v1"]}}

Si le webhook est en panne, les demandes d'API peuvent échouer avec conversion webhook not found. Changez temporairement la stratégie en None (si une seule version est servie) pour rétablir l'accès :

kubectl patch crd widgets.example.com --type merge -p '{"spec":{"conversion":{"strategy":"None"}}}'

Remarque : cela exige que toutes les versions soient servies par le serveur API sans conversion, donc assurez-vous de n'avoir qu'une seule version ou que toutes les versions sont structurellement identiques.

Vérification de la récupération

Après toute action de récupération, vérifiez en listant et en décrivant les ressources, en vérifiant les conditions de la CRD et en vous assurant que les contrôleurs sont en cours d'exécution.

kubectl get crd widgets.example.com -o jsonpath='{.status.conditions}' | jq .

Liste de contrôle opérationnelle

Utilisez cette liste de contrôle avant et après tout changement de CRD dans votre laboratoire local (ou comme modèle pour la production). Chaque élément inclut un exemple concret.

#Élément de la listeExemple de commande / actionRésultat attendu
1Enregistrez les versions actuelles du cluster et de la CRDkubectl version --short et kubectl get crd widgets.example.com -o yaml | grep -A1 'name: v'Exemple : v1.27.3, version de CRD v1 uniquement
2Sauvegardez les ressources personnalisées existanteskubectl get widgets -o yaml > widgets-backup-$(date +%Y%m%d).yamlFichier enregistré (par exemple, widgets-backup-20230701.yaml)
3Appliquez le nouveau manifeste de CRDkubectl apply -f widget-crd-v2.yamlSortie : customresourcedefinition configured
4Vérifiez que la CRD est établiekubectl get crd widgets.example.com -o jsonpath='{.status.conditions[?(@.type=="Established")].status}'True
5Testez la validation du schéma avec un objet invalideecho '{"apiVersion":"example.com/v1","kind":"Widget","metadata":{"name":"test"},"spec":{"size":5,"color":"purple"}}' | kubectl apply -f -Erreur : Unsupported value: "purple"
6Créez une ressource personnalisée valideAppliquez un manifeste avec size=3, color=greenSortie : widget.example.com/test created
7Vérifiez les champs de la ressource personnalisée via kubectl getkubectl get widgets testAffiche SIZE=3, COLOR=green, PHASE vide
8Simulez la mise à jour du statut par le contrôleurExécutez simple-controller.shPatche le widget avec phase Pending
9Vérifiez la mise à jour du statutkubectl get widget test -o jsonpath='{.status.phase}'Pending
10Testez le retour en arrièrekubectl apply -f widget-crd.yaml (ancienne CRD)CRD configurée sans sous-ressource de statut
11Nettoyez les ressourceskubectl delete crd widgets.example.com après sauvegardeCRD supprimée, toutes les ressources personnalisées supprimées

Conclusion

La configuration d'un laboratoire local de définitions de ressources personnalisées Kubernetes avec des exemples pratiques est essentielle pour le développement sûr d'opérateurs personnalisés. Cet article a fourni un guide étape par étape : inventaire de l'environnement, CRD minimale, configuration sûre avec sous-ressources et colonnes d'impression, commandes de vérification et scénarios de récupération en cas de défaillance.

Pour renforcer l'apprentissage, pratiquez ces tâches :

  1. Étendez la CRD Widget avec un nouveau champ facultatif et un modèle de validation.
  2. Implémentez une deuxième version d'API (v2) avec une stratégie de conversion (None ou Webhook) et testez la migration.
  3. Déployez un vrai contrôleur à l'aide d'un déploiement Kubernetes et d'un compte de service avec RBAC approprié.
  4. Utilisez kubectl explain widgets pour explorer la documentation API générée.

Rappelez-vous les principes de sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des espaces réservés, vérifier et documenter la récupération. Avec un laboratoire local solide, vous pouvez itérer plus rapidement et réduire les risques en production.

Prochaine étape : choisissez une vérification à faible risque de la liste de contrôle (par exemple, la validation du schéma), enregistrez l'état actuel, exécutez la vérification, comparez avec la sortie attendue et examinez les dépendances telles que les rôles RBAC pour votre contrôleur.

Un flux de travail technique fiable rend les défaillances visibles, protège les valeurs sensibles, limite les modifications à la ressource prévue et définit la vérification de récupération avant qu'un incident ne force la décision.

Recherches connexes

Score de qualité de l’article

Utilité pour le lecteur 100%
  • check_circle Guide prêt à lire
  • check_circle Exemples pratiques inclus
  • check_circle URL d’article optimisée pour le SEO