E-NO
Kubernetes 8 min de lecture

Erreurs de configuration des définitions de ressources personnalisées Kubernetes : guide pratique de terrain

calendar_today Publié : 2026-10-17
update Dernière mise à jour : 2026-10-17
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Erreurs de configuration des définitions de ressources personnalisées Kubernetes : guide pratique de terrain ».

Introduction

Les définitions de ressources personnalisées (Custom Resource Definitions, CRD) étendent Kubernetes avec des API spécifiques à un domaine, permettant aux équipes de gérer des applications et des infrastructures via des configurations déclaratives. Cependant, les CRD sont puissantes et complexes. Un seul champ mal configuré peut casser des ressources existantes, provoquer des échecs silencieux de l'API ou rendre les mises à niveau impossibles. Ce guide examine les erreurs fréquentes de configuration des CRD à travers des exemples pratiques, en montrant comment les détecter, les prévenir et s'en remettre dans des clusters de production. Vous apprendrez à valider les schémas, à éviter les pièges courants et à établir des flux de travail opérationnels fiables.

Inventaire des versions et de l'environnement

Avant de modifier une CRD, sachez exactement ce que vous exécutez. Capturez la version de Kubernetes, la version de l'API de la CRD et la version du contrôleur qui consomme la CRD. Certains comportements diffèrent entre les versions de Kubernetes, notamment autour des schémas structurels et de l'élagage.

Exécutez ces commandes en lecture seule pour enregistrer l'environnement :

kubectl version --short
kubectl get crd <crd-name> -o yaml
kubectl get deployment -n <namespace> <controller-name> -o yaml

La sortie attendue inclut la version de l'API (apiextensions.k8s.io/v1 ou v1beta1), les versions stockées de la CRD et la balise d'image du contrôleur. Par exemple :

API Version: apiextensions.k8s.io/v1
Kind: CustomResourceDefinition
Spec:
  Group: example.com
  Versions:
    - Name: v1
      Served: true
      Storage: true

Si la CRD utilise apiextensions.k8s.io/v1beta1, planifiez une migration vers v1 car v1beta1 est supprimée dans Kubernetes 1.22 et versions ultérieures. Vérifiez que tous les champs requis par le schéma v1 sont présents, en particulier schema.openAPIV3Schema avec les exigences de schéma structurel.

Test pratique de l'environnement : appliquez une ressource personnalisée minimale et vérifiez qu'elle apparaît dans kubectl get <plural> sans erreurs. Par exemple :

apiVersion: example.com/v1
kind: MyResource
metadata:
  name: test-instance
spec:
  size: 1

Puis :

kubectl apply -f test-instance.yaml
kubectl get myresources

Si la ressource n'est pas listée, vérifiez les journaux du contrôleur et les conditions de la CRD.

Question rapide 1 sur 2

Que crée la définition d'un objet CustomResourceDefinition ?

Le passage 1 indique que 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, et que l'API Kubernetes la dessert et gère son stockage.

Chemin de configuration sûr

Un déploiement sûr d'une CRD minimise le risque de casser des ressources personnalisées et des contrôleurs existants. Suivez ces étapes :

  1. Examinez la CRD actuelle : kubectl get crd <crd-name> -o yaml > crd-backup.yaml
  2. Testez les modifications de schéma localement : Utilisez kubectl apply --dry-run=client et --dry-run=server pour valider sans persister.
  3. Étalez la nouvelle CRD : Si vous ajoutez une nouvelle version, assurez-vous qu'elle est served: false initialement, puis activez-la progressivement.
  4. Mettez à jour le contrôleur d'abord : Le contrôleur doit comprendre le nouveau schéma avant que vous ne l'appliquiez au cluster.
  5. Appliquez la modification de la CRD : kubectl apply -f crd-updated.yaml

Exemple : Ajout d'une nouvelle version v2 à une CRD existante. Commencez avec served: true, storage: false :

versions:
  - name: v1
    served: true
    storage: true
  - name: v2
    served: true
    storage: false

Après la migration des données, définissez progressivement storage: true sur v2 et storage: false sur v1.

Erreur courante : Changer la version de stockage sans chemin de migration. Cela peut entraîner une perte de données ou des erreurs d'API. Kubernetes ne convertit pas automatiquement les objets stockés ; vous devez fournir un webhook de conversion ou le gérer manuellement.

Vérification : Après l'application, vérifiez les conditions d'état de la CRD :

kubectl get crd <crd-name> -o jsonpath='{.status.conditions}' | jq .

Recherchez Established: True et NamesAccepted: True. Essayez également de créer une ressource avec les anciens et les nouveaux champs pour garantir la compatibilité.

Vérification et diagnostics

Un diagnostic efficace commence par l'observation de la réponse du système à votre configuration. Utilisez kubectl describe pour faire apparaître les événements et les détails d'état.

Validez l'exactitude du schéma en appliquant une ressource volontairement invalide :

apiVersion: example.com/v1
kind: MyResource
metadata:
  name: bad-instance
spec:
  size: "large"   # entier attendu

Sortie attendue de kubectl apply :

The request is invalid: spec.size: Invalid value: "string": spec.size in body must be of type integer: "string"

Si vous ne voyez pas d'erreur de validation, le schéma peut manquer type: integer ou le champ n'est pas marqué comme requis. Examinez le schéma OpenAPI v3 sous spec.versions[].schema.openAPIV3Schema.

Diagnostiquez les problèmes du contrôleur : Récupérez les journaux du contrôleur :

kubectl logs -n <namespace> deployment/<controller-name> --tail=50

Recherchez les erreurs de réconciliation répétées, telles que unable to parse resource ou field not recognized. Elles indiquent une inadéquation entre le schéma de la CRD et les attentes du contrôleur.

Vérifiez les conditions d'état de la CRD :

kubectl get crd <crd-name> -o yaml | grep -A 10 conditions:

Conditions à surveiller :

  • NamesAccepted : vrai si les noms sont valides.
  • Established : vrai lorsque le point de terminaison REST est actif.
  • NonStructuralSchema : présent si le schéma n'est pas structurel.

Exemple : Une CRD avec un schéma non structurel déclenchera cet avertissement :

message: 'spec.validation.openAPIV3Schema.type: Required value: must not be empty at the root'

Corrigez en spécifiant type: object à la racine et en ajoutant properties pour chaque champ.

Modes de défaillance et récupération

Les erreurs de configuration des CRD peuvent provoquer des échecs partiels, des pertes de données silencieuses ou une indisponibilité complète de l'API. Préparez des procédures de récupération pour les scénarios les plus probables.

Scénario 1 : Un schéma invalide casse les ressources existantes

Symptôme : Après la mise à jour d'une CRD, les ressources existantes échouent à la validation lors de la mise à jour ou des opérations du contrôleur.

Cause : Le nouveau schéma a des exigences plus strictes (par exemple, de nouveaux champs requis) que les anciennes ressources ne satisfont pas.

Récupération :

  1. Revenez à la version précédente de la CRD en utilisant votre sauvegarde :
   kubectl apply -f crd-backup.yaml
  1. Corrigez le schéma pour qu'il soit rétrocompatible, par exemple en n'ajoutant pas de champs requis sans valeurs par défaut.
  2. Réappliquez la CRD mise à jour.

Scénario 2 : Version de stockage modifiée sans conversion

Symptôme : kubectl get <ressource> renvoie des erreurs comme no kind is registered for the version "v2" ou des erreurs de conversion.

Cause : Vous avez changé la version de storage mais n'avez pas fourni de webhook de conversion, et les objets existants sont stockés dans l'ancienne version.

Récupération :

  1. Remettez la version de stockage à la précédente :
   kubectl patch crd <crd-name> --type='json' -p='[{"op": "replace", "path": "/spec/versions/0/storage", "value": true},{"op": "replace", "path": "/spec/versions/1/storage", "value": false}]'

(Ajustez les indices pour correspondre à vos versions.)

  1. Implémentez un webhook de conversion ou migrez manuellement les objets en utilisant kubectl get --raw et kubectl replace.
  2. Répétez ensuite le changement de version de stockage.

Scénario 3 : Suppression d'une CRD orpheline des ressources personnalisées

Symptôme : Vous supprimez une CRD et toutes ses ressources personnalisées sont supprimées immédiatement, entraînant une perte de données.

Cause : La suppression en cascade est le comportement par défaut. Vous aviez l'intention de conserver les données pour une migration ultérieure.

Récupération : Restaurez à partir d'une sauvegarde etcd ou de snapshots. Pour éviter cela à l'avenir, définir spec.preserveUnknownFields: false ne suffit pas ; vous devez exporter les ressources avant la suppression :

  kubectl get <plural> -o yaml > resources-backup.yaml

Après avoir recréé la CRD, réappliquez les ressources.

Scénario 4 : Contrôleur non mis à jour pour les nouveaux champs

Symptôme : Les nouveaux champs sont ignorés ou provoquent des plantages du contrôleur.

Cause : Les structures Go du contrôleur n'incluent pas les nouveaux champs, ou le contrôleur utilise du code non structuré avec un décodage strict.

Récupération : Mettez à jour le contrôleur pour correspondre au nouveau schéma, puis redémarrez-le. Pour éviter cela, utilisez un webhook de conversion pour conserver plusieurs versions d'API ou coordonnez les versions de la CRD et du contrôleur.

Question rapide 2 sur 2

Quelle contrainte s'applique au nom d'un objet CRD et au nom des objets dont le kind est défini par un CRD ?

Le passage 1 explique que le nom de l'objet CRD doit être un nom de sous-domaine DNS valide dérivé du nom de la ressource et du groupe d'API, et qu'un objet dont le kind/la ressource est défini par un CRD doit également avoir un nom de sous-domaine DNS valide.

Erreurs courantes et comment les éviter

1. Omettre le schéma structurel

Pourquoi cela arrive : Les premières CRD utilisaient souvent preserveUnknownFields: true ou des schémas minimaux pour plus de flexibilité.

Risque : Kubernetes ne peut pas élaguer les champs inconnus, ce qui entraîne un gonflement de la mémoire du serveur d'API et une incompatibilité avec les webhooks d'admission et les outils de validation des CRD.

Évitement : Définissez toujours un openAPIV3Schema complet avec type: object et des propriétés pour tous les champs connus. Définissez preserveUnknownFields: false (par défaut en v1).

Exemple de schéma structurel minimal :

schema:
  openAPIV3Schema:
    type: object
    properties:
      spec:
        type: object
        properties:
          size:
            type: integer
            minimum: 1

2. Oublier les valeurs par défaut pour les nouveaux champs

Pourquoi cela arrive : L'ajout de nouveaux champs sans default peut casser les objets existants qui n'ont pas ce champ défini.

Risque : Les contrôleurs peuvent devenir un pointeur nul vers un champ, provoquant des plantages. Ou les webhooks d'admission rejettent les anciens objets.

Évitement : Définissez une default pour chaque nouveau champ, ou faites en sorte que le contrôleur gère gracieusement les valeurs manquantes.

Exemple :

properties:
  replicas:
    type: integer
    default: 1

3. Changer les types de champs de manière incompatible

Pourquoi cela arrive : Les développeurs supposent que changer un champ de chaîne à entier est facile.

Risque : Cela casse la compatibilité de l'API. Les clients existants et les objets stockés peuvent échouer.

Évitement : Ne changez jamais le type d'un champ dans la même version d'API. Introduisez une nouvelle version (v2) avec le type modifié et utilisez un webhook de conversion.

4. Ne pas tester avec kubectl explain

Pourquoi cela arrive : Les équipes se précipitent pour appliquer les CRD sans vérifier la génération de la documentation.

Risque : Les utilisateurs ne peuvent pas découvrir correctement les champs ; kubectl explain donne des informations incomplètes.

Évitement : Après avoir appliqué la CRD, exécutez kubectl explain <ressource>.<champ> pour vous assurer que les descriptions apparaissent. Ajoutez des champs description dans le schéma.

Exemple :

kubectl explain myresource.spec.size

La sortie attendue inclut la description et le type.

5. Ignorer les webhooks de conversion

Pourquoi cela arrive : Les équipes ne servent initialement qu'une seule version, puis ajoutent plus tard une nouvelle version sans webhook.

Risque : Lorsque plusieurs versions sont servies, le serveur d'API ne peut pas convertir entre elles, provoquant des erreurs pour les clients qui utilisent une version spécifique.

Évitement : Implémentez un webhook de conversion dès que vous avez plus d'une version. Utilisez des outils comme controller-runtime pour générer des webhooks.

Exemple de configuration de webhook dans la CRD :

conversion:
  strategy: Webhook
  webhook:
    conversionReviewVersions: ["v1", "v1beta1"]
    clientConfig:
      service:
        name: conversion-webhook
        namespace: default
        path: /convert

6. Élaguer accidentellement des champs personnalisés

Pourquoi cela arrive : Vous ajoutez un champ mais ne l'incluez pas dans le schéma, et le serveur d'API l'élague car les champs inconnus sont supprimés par défaut.

Risque : Les données disparaissent silencieusement lorsqu'un utilisateur soumet une ressource avec ce champ.

Évitement : Assurez-vous que le schéma inclut chaque champ attendu par votre contrôleur. Utilisez x-kubernetes-preserve-unknown-fields: true uniquement dans des contextes imbriqués spécifiques si nécessaire.

Exemple de préservation des champs inconnus imbriqués :

properties:
  spec:
    type: object
    x-kubernetes-preserve-unknown-fields: true

Mais utilisez avec parcimonie ; il vaut mieux modéliser tous les champs.

Liste de contrôle des opérations

Maintenez une liste de contrôle des opérations CRD reproductible. Attribuez un responsable pour chaque étape majeure et révisez la liste trimestriellement ou après des incidents.

ÉtapeActionResponsableFréquenceVérification
1Sauvegarder le manifeste CRD actuel dans le contrôle de versionResponsable plateforme (ex. Priya Shah)Avant tout changementkubectl get crd <name> -o yaml diff avec le dépôt
2Examiner les modifications de schéma pour la rétrocompatibilitéIngénieur backend (ex. Tom Nguyen)Chaque PRkubectl apply --dry-run=server réussit
3Tester avec des ressources d'exempleIngénieur QA (ex. Maria Lopez)Chaque versionkubectl apply -f samples/ et vérifier l'état
4Vérifier les journaux du contrôleur pour les erreursSRE de garde (ex. Chris Evans)Après le déploiementkubectl logs ne montre aucune erreur liée à la CRD
5Valider la sortie de kubectl explainDéveloppeur (ex. Sam Chen)Chaque changement de schémakubectl explain <ressource> affiche les champs
6Examiner les métriques du webhook de conversionResponsable plateformeMensuelLatence du webhook < 100 ms, taux d'erreur < 0,1 %
7Tester la procédure de retour en arrièreSRE (ex. Dana White)TrimestrielAppliquer la CRD précédente et confirmer que les ressources fonctionnent toujours

Utilisez cette liste comme point de départ : adaptez les responsables et les fréquences à la taille de votre équipe et à votre rythme de publication.

Conclusion

Les erreurs de configuration des CRD peuvent avoir des conséquences considérables, allant de la perte de données silencieuse à des défaillances d'API à l'échelle du cluster. En comprenant les pièges courants, en validant rigoureusement les schémas et en établissant des manuels de récupération, vous pouvez exploiter les CRD en toute confiance. Commencez par un inventaire de vos CRD actuelles, implémentez des schémas structurels et testez chaque changement dans un environnement de préproduction. La prochaine étape consiste à choisir une CRD dans votre cluster, à exécuter les diagnostics décrits ici et à corriger les problèmes que vous trouvez. Prendre ces habitudes dès maintenant vous épargnera un débogage pénible plus tard.

Un flux de travail fiable pour les CRD ne consiste pas seulement à éviter les erreurs ; il s'agit de rendre votre API Kubernetes étendue prévisible, observable et sûre pour tous ceux qui l'utilisent.

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