
Les Custom Resource Definitions (CRDs) étendent Kubernetes avec de nouveaux types de ressources. En tant que développeur, vous n'avez pas besoin de créer des opérateurs, mais vous devez savoir utiliser les ressources custom que d'autres ont créées. Ce guide vous montre comment découvrir, manipuler et diagnostiquer les CRDs dans votre cluster.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »Le parcours va de la découverte des CRDs enregistrées dans un cluster jusqu'au déblocage d'une ressource en Terminating. Les exemples s'appuient sur des opérateurs répandus, cert-manager et le Prometheus Operator en tête, mais la mécanique reste identique quelle que soit l'extension installée.
- Comprendre le modèle CRD/Operator sans entrer dans le développement
- Découvrir les CRDs disponibles dans votre cluster
- Manipuler des ressources custom avec kubectl
- Installer un opérateur depuis OperatorHub
- Diagnostiquer les problèmes courants liés aux CRDs
CRD et Operator : l'essentiel pour un développeur
Section intitulée « CRD et Operator : l'essentiel pour un développeur »Deux objets distincts se cachent derrière le sujet : la CRD déclare un nouveau type auprès de l'API server, l'opérateur est le programme qui donne un sens à ce type en créant les ressources sous-jacentes. Sans opérateur, une CRD ne produit rien, elle se contente de stocker vos manifests.
Qu'est-ce qu'une CRD ?
Section intitulée « Qu'est-ce qu'une CRD ? »Une Custom Resource Definition (CRD) ajoute un nouveau type d'objet à Kubernetes. Au lieu de manipuler uniquement des Pods, Services ou Deployments, vous pouvez manipuler des objets métier comme PostgresCluster, Certificate ou GitRepository.
| Concept | Exemple |
|---|---|
| CRD | kind: PostgresCluster |
| Custom Resource (CR) | Un cluster PostgreSQL spécifique |
| Operator | Crée les Pods, Services, Secrets nécessaires |
Le pattern Controller
Section intitulée « Le pattern Controller »L'opérateur est un controller qui observe les ressources custom et agit pour atteindre l'état désiré :
┌─────────────────────────────────────────────────────────────┐│ Boucle de réconciliation │├─────────────────────────────────────────────────────────────┤│ 1. OBSERVER : L'opérateur watch les CRs ││ 2. COMPARER : État actuel vs état désiré ││ 3. AGIR : Créer/modifier/supprimer des ressources ││ 4. RÉPÉTER : En continu │└─────────────────────────────────────────────────────────────┘Découvrir les CRDs de votre cluster
Section intitulée « Découvrir les CRDs de votre cluster »Les types disponibles changent d'un cluster à l'autre selon les opérateurs installés. Avant d'écrire un manifest, il faut savoir quelles CRDs sont enregistrées, dans quelle version d'API elles sont servies, et si la ressource est namespacée ou globale.
Lister toutes les CRDs
Section intitulée « Lister toutes les CRDs »Le nom complet d'une CRD suit toujours la forme <pluriel>.<groupe d'API>, ce qui identifie d'un coup d'œil l'opérateur qui l'a posée. La colonne CREATED AT donne la date d'installation, pratique pour repérer une extension ajoutée récemment sur un cluster partagé.
# Toutes les CRDs installéeskubectl get crds
# Exemple de sortie :# NAME CREATED AT# certificates.cert-manager.io 2026-03-20T10:00:00Z# issuers.cert-manager.io 2026-03-20T10:00:00Z# postgresclusters.postgres-operator.crunchydata.com 2026-03-15T08:30:00ZExplorer une CRD spécifique
Section intitulée « Explorer une CRD spécifique »describe affiche les versions servies, la portée de la ressource et les shortnames déclarés. La sortie YAML complète contient en plus le schéma OpenAPI qui valide vos manifests : c'est lui qui provoque le rejet quand un champ est mal orthographié.
# Détails d'une CRDkubectl describe crd certificates.cert-manager.io
# Structure YAML de la CRDkubectl get crd certificates.cert-manager.io -o yamlDécouvrir les API groups
Section intitulée « Découvrir les API groups »kubectl api-resources liste tout ce que l'API server sait servir, ressources natives et custom confondues. La colonne NAMESPACED indique s'il faut préciser un namespace, et APIVERSION donne exactement la valeur à recopier dans le champ apiVersion de votre manifest.
# Tous les types de ressources disponibles (natifs + custom)kubectl api-resources
# Filtrer par API groupkubectl api-resources --api-group=cert-manager.io
# Exemple de sortie :# NAME SHORTNAMES APIVERSION NAMESPACED KIND# certificates cert cert-manager.io/v1 true Certificate# issuers cert-manager.io/v1 true IssuerLister les ressources custom
Section intitulée « Lister les ressources custom »Une fois le type connu, les CRs se listent comme n'importe quel objet Kubernetes. L'option -A balaie tous les namespaces, réflexe utile quand vous ignorez où la ressource a été créée ; -o wide révèle les colonnes supplémentaires définies par la CRD elle-même, souvent l'état de la ressource.
# Lister les instances d'une CRkubectl get certificates -n mon-namespace
# Dans tous les namespaceskubectl get certificates -A
# Avec plus de détailskubectl get certificates -o wideInteragir avec des ressources custom
Section intitulée « Interagir avec des ressources custom »Une CR se manipule avec les verbes habituels : apply, get, describe, edit, patch, delete. La différence tient au partage du contenu : vous écrivez la spec, l'opérateur écrit le status, et toute modification de la spec relance sa boucle de réconciliation.
Créer une ressource custom
Section intitulée « Créer une ressource custom »Le format est identique aux ressources natives. Exemple avec cert-manager :
apiVersion: cert-manager.io/v1kind: Certificatemetadata: name: mon-app-tls namespace: productionspec: secretName: mon-app-tls-secret issuerRef: name: letsencrypt-prod kind: ClusterIssuer dnsNames: - mon-app.example.com - www.mon-app.example.comkubectl apply -f certificate.yamlInspecter une ressource custom
Section intitulée « Inspecter une ressource custom »describe reste le point d'entrée : il regroupe la spec, le status et les événements émis par l'opérateur, qui portent le motif exact d'un échec. Le JSONPath sert quand vous cherchez un champ précis, par exemple dans un script qui attend qu'une condition passe à True.
# Détails completskubectl describe certificate mon-app-tls -n production
# YAML brutkubectl get certificate mon-app-tls -n production -o yaml
# JSONPath pour extraire un champkubectl get certificate mon-app-tls -n production \ -o jsonpath='{.status.conditions[0].status}'Comprendre le champ status
Section intitulée « Comprendre le champ status »Les CRs bien conçues exposent un champ .status mis à jour par l'opérateur :
status: conditions: - type: Ready status: "True" reason: CertificateIssued message: Certificate is up to date and has been issued lastTransitionTime: "2026-03-25T10:30:00Z" notAfter: "2026-06-25T10:30:00Z" notBefore: "2026-03-25T10:30:00Z" renewalTime: "2026-05-25T10:30:00Z"Modifier une ressource custom
Section intitulée « Modifier une ressource custom »edit ouvre le manifest dans votre éditeur et applique le résultat à la fermeture. patch --type=merge fait la même chose sans interaction, donc en script ; attention, sur une liste comme dnsNames, la fusion remplace le tableau entier au lieu d'y ajouter une entrée.
# Édition interactivekubectl edit certificate mon-app-tls -n production
# Patch (modifier un champ)kubectl patch certificate mon-app-tls -n production \ --type=merge \ -p '{"spec":{"dnsNames":["mon-app.example.com","api.example.com"]}}'Supprimer une ressource custom
Section intitulée « Supprimer une ressource custom »La commande rend la main aussitôt, mais l'objet peut rester en Terminating le temps que l'opérateur achève le nettoyage des ressources qu'il avait créées.
kubectl delete certificate mon-app-tls -n productionExemples de CRDs courantes
Section intitulée « Exemples de CRDs courantes »Les quatre extensions ci-dessous couvrent des besoins que Kubernetes ne traite pas nativement : certificats TLS, collecte de métriques, déploiement continu et récupération de secrets externes. Toutes suivent la même grammaire, un bloc spec déclaratif que l'opérateur traduit en objets natifs.
cert-manager : Certificats TLS
Section intitulée « cert-manager : Certificats TLS »L'objet Certificate décrit le certificat voulu, pas la façon de l'obtenir. issuerRef désigne l'autorité qui le délivrera, dnsNames les noms à couvrir, et secretName le Secret dans lequel cert-manager déposera la clé privée et le certificat une fois la validation aboutie.
apiVersion: cert-manager.io/v1kind: Certificatemetadata: name: api-tls namespace: productionspec: secretName: api-tls-secret issuerRef: name: letsencrypt-prod kind: ClusterIssuer dnsNames: - api.example.comPrometheus : ServiceMonitor
Section intitulée « Prometheus : ServiceMonitor »Un ServiceMonitor ne collecte rien par lui-même : il indique au Prometheus Operator quels Services interroger. Le selector cible ces Services par label, port reprend le nom du port déclaré dans le Service et non son numéro, ce qui est la cause d'erreur la plus fréquente sur cette ressource.
apiVersion: monitoring.coreos.com/v1kind: ServiceMonitormetadata: name: mon-app namespace: monitoringspec: selector: matchLabels: app: mon-app endpoints: - port: metrics interval: 30sArgo CD : Application
Section intitulée « Argo CD : Application »L'objet Application relie un dépôt Git à un namespace de destination. Les deux options de syncPolicy.automated sont les plus lourdes de conséquences : prune autorise Argo CD à supprimer les objets retirés du dépôt, selfHeal annule toute modification faite directement sur le cluster.
apiVersion: argoproj.io/v1alpha1kind: Applicationmetadata: name: mon-app namespace: argocdspec: project: default source: repoURL: https://github.com/mon-org/mon-app path: k8s targetRevision: HEAD destination: server: https://kubernetes.default.svc namespace: production syncPolicy: automated: prune: true selfHeal: trueExternal Secrets : Intégration vault
Section intitulée « External Secrets : Intégration vault »Un ExternalSecret décrit une correspondance entre des chemins d'un coffre externe et les clés d'un Secret Kubernetes. L'opérateur relit la source à chaque refreshInterval et met à jour le Secret cible : la valeur sensible ne figure jamais dans le manifest, seul son emplacement y apparaît.
apiVersion: external-secrets.io/v1beta1kind: ExternalSecretmetadata: name: db-credentials namespace: productionspec: refreshInterval: 1h secretStoreRef: name: vault-backend kind: ClusterSecretStore target: name: db-credentials data: - secretKey: username remoteRef: key: secret/data/database property: username - secretKey: password remoteRef: key: secret/data/database property: passwordInstaller un opérateur
Section intitulée « Installer un opérateur »Installer un opérateur revient à poser deux choses : ses CRDs et le Deployment du controller, avec les droits RBAC qui vont avec. Les trois méthodes ci-dessous se distinguent surtout sur la mise à jour et sur le sort des CRDs à la désinstallation, car supprimer une CRD détruit au passage toutes les CRs de ce type.
Option 1 : Helm (recommandé)
Section intitulée « Option 1 : Helm (recommandé) »La plupart des opérateurs sont distribués via Helm :
# Exemple : cert-managerhelm repo add jetstack https://charts.jetstack.iohelm repo update
helm install cert-manager jetstack/cert-manager \ --namespace cert-manager \ --create-namespace \ --set crds.enabled=trueOption 2 : kubectl apply
Section intitulée « Option 2 : kubectl apply »Certains opérateurs fournissent un manifest unique :
# Exemple : metrics-serverkubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yamlOption 3 : OperatorHub (OpenShift / OLM)
Section intitulée « Option 3 : OperatorHub (OpenShift / OLM) »Si votre cluster utilise Operator Lifecycle Manager :
# Installer OLM (si pas déjà présent) : télécharger le script, l'inspecter, puis l'exécutercurl -sL https://github.com/operator-framework/operator-lifecycle-manager/releases/download/v0.28.0/install.sh -o olm-install.shless olm-install.shbash olm-install.sh v0.28.0
# Installer un opérateur depuis OperatorHubkubectl create -f https://operatorhub.io/install/prometheus.yamlDiagnostiquer les problèmes
Section intitulée « Diagnostiquer les problèmes »Quand une CR ne produit pas l'effet attendu, le manifest est rarement en cause : l'API server l'aurait rejeté à l'apply si sa structure était invalide. Trois pistes couvrent la majorité des cas, l'opérateur ne tourne pas, la CRD n'est pas installée, ou les permissions RBAC du controller sont insuffisantes.
La CR reste en état Pending/Unknown
Section intitulée « La CR reste en état Pending/Unknown »Un objet accepté mais jamais traité signale que personne ne l'écoute. Regardez d'abord les événements de la CR, puis l'état du Pod de l'opérateur, enfin ses logs : c'est là qu'apparaissent les erreurs de validation métier ou d'accès à un service externe.
# 1. Vérifier les événements de la CRkubectl describe <kind> <name> -n <namespace>
# 2. Vérifier que l'opérateur tournekubectl get pods -n <operator-namespace>
# 3. Lire les logs de l'opérateurkubectl logs -n <operator-namespace> deployment/<operator-name>Erreur "no matches for kind" lors du kubectl apply
Section intitulée « Erreur "no matches for kind" lors du kubectl apply »Ce message vient de l'API server : le kind demandé n'est enregistré nulle part. Soit la CRD n'est pas installée, soit vous visez une version d'API que le cluster ne sert plus, cas courant après le passage d'un groupe de v1beta1 à v1.
# Le CRD n'est pas installékubectl get crd | grep <kind>
# Solution : installer l'opérateur d'abordLa CR est bloquée en Terminating
Section intitulée « La CR est bloquée en Terminating »Un finalizer suspend la suppression tant que l'opérateur n'a pas confirmé son nettoyage. Si le controller a été désinstallé avant ses ressources, plus personne ne retire ce marqueur et l'objet reste indéfiniment en Terminating, y compris son namespace s'il en contient d'autres.
# Vérifier les finalizerskubectl get <kind> <name> -o jsonpath='{.metadata.finalizers}'
# Si l'opérateur ne tourne plus, retirer le finalizer manuellementkubectl patch <kind> <name> \ --type=json \ -p='[{"op": "remove", "path": "/metadata/finalizers"}]'Problème de permissions
Section intitulée « Problème de permissions »L'opérateur n'a pas les droits nécessaires :
# Vérifier les logs pour des erreurs RBACkubectl logs -n <operator-namespace> deployment/<operator-name> | grep -i forbidden
# Vérifier les Roles/ClusterRoles de l'opérateurkubectl get clusterrole | grep <operator-name>kubectl describe clusterrole <operator-role>Utiliser kubectl explain
Section intitulée « Utiliser kubectl explain »La commande kubectl explain fonctionne aussi avec les CRDs :
# Structure généralekubectl explain certificate
# Champ spécifiquekubectl explain certificate.spec.issuerRef
# Liste des champs disponibleskubectl explain certificate.spec --recursiveBonnes pratiques développeur
Section intitulée « Bonnes pratiques développeur »Les trois listes suivantes évitent les allers-retours les plus coûteux : un manifest rejeté faute de CRD, une ressource introuvable faute de convention de nommage, et une CR en échec silencieux parce que personne ne surveille son status.
Avant de créer une CR
Section intitulée « Avant de créer une CR »Ces quatre vérifications prennent moins d'une minute. Notez la limite de --dry-run=client : il contrôle la syntaxe YAML localement, sans jamais confronter le manifest au schéma OpenAPI de la CRD. Pour cette validation-là, il faut --dry-run=server, qui envoie l'objet à l'API server sans le persister.
- Vérifiez que la CRD existe :
kubectl get crd <name> - Lisez la documentation : Les CRDs ont souvent des exemples
- Utilisez kubectl explain : Pour comprendre les champs disponibles
- Validez avec
--dry-run:kubectl apply -f cr.yaml --dry-run=client
Nommage et organisation
Section intitulée « Nommage et organisation »Les CRs s'accumulent dans un namespace partagé sans le regroupement visuel qu'offre un Deployment avec ses Pods : rien n'indique quelle application a créé quel objet. Un préfixe applicatif et des labels cohérents rendent le filtrage possible, y compris pour les suppressions groupées.
- Préfixez par application :
mon-app-certificateplutôt quecertificate-1 - Utilisez des labels : Facilitez le filtrage et le monitoring
- Documentez : Ajoutez des annotations expliquant le but
Surveillance
Section intitulée « Surveillance »Une CR peut rester en échec sans que rien ne le signale : elle ne redémarre pas comme un Pod et n'apparaît dans aucun kubectl get pods. Suivre status.conditions est le seul moyen fiable de détecter un certificat non renouvelé ou une synchronisation qui échoue depuis des semaines.
- Surveillez les status : Les CRs exposent leur état dans
.status - Alertez sur les échecs : Conditions
Ready=FalseouFailed=True - Tracez les changements : Activez l'audit logging pour les CRs sensibles
À retenir
Section intitulée « À retenir »Le tableau condense le vocabulaire du modèle. Un point revient dans presque tous les incidents : une CR acceptée par l'API server ne signifie pas qu'elle a été traitée. Seul le status écrit par l'opérateur en atteste, et c'est lui qu'il faut lire avant de conclure que la ressource fonctionne.
| Concept | Ce qu'il faut retenir |
|---|---|
| CRD | Nouveau type de ressource Kubernetes |
| CR (Custom Resource) | Instance d'une CRD |
| Operator | Controller qui gère les CRs |
kubectl api-resources | Découvrir les types disponibles |
kubectl explain | Comprendre la structure d'une CR |
.status.conditions | État de la ressource |
| Finalizers | Retardent la suppression pour nettoyage |
Règle d'or : En tant que développeur, vous utilisez les CRs, vous n'avez pas besoin de comprendre le code de l'opérateur, seulement la spec que vous fournissez et le status qu'il retourne.
Testez vos connaissances
Section intitulée « Testez vos connaissances »Dix questions tirées de la banque CKAD portent sur la découverte des types, la lecture du status et le déblocage d'une ressource en Terminating. Comptez huit minutes et 70 % de bonnes réponses pour valider.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Profil de compétences
Quoi faire maintenant
Ressources pour progresser
Des indices pour retenter votre chance ?
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications
Prochaines étapes
Section intitulée « Prochaines étapes »Si consommer des CRs ne suffit plus et que vous voulez produire les vôtres, le guide dédié aux opérateurs aborde la boucle de réconciliation côté code. Les deux autres liens complètent le sujet par l'installation via Helm et par les permissions des ServiceAccounts que réclament ces controllers.