
Les API Kubernetes évoluent : certaines versions sont dépréciées puis supprimées lors des mises à jour. Si vos manifests utilisent une API supprimée, vos déploiements échoueront après la mise à jour du cluster. Ce guide vous explique le cycle de vie des API, comment détecter les versions obsolètes, et comment migrer vos ressources avant qu'il ne soit trop tard.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Comprendre le cycle de vie des API Kubernetes (alpha → beta → stable)
- Distinguer une API dépréciée (avertissement) d'une API supprimée (erreur)
- Détecter les API obsolètes dans vos fichiers YAML, charts Helm et cluster
- Migrer vos ressources avec
kubectl convertet les outils appropriés - Automatiser la détection dans votre pipeline CI/CD
Prérequis : savoir écrire des manifests Kubernetes et comprendre le versioning sémantique.
Pourquoi les API changent-elles ?
Section intitulée « Pourquoi les API changent-elles ? »Kubernetes suit un processus rigoureux pour faire évoluer ses API sans casser brutalement les utilisateurs. Chaque nouvelle fonctionnalité passe par plusieurs phases de maturité avant d'être stabilisée, ou abandonnée.
Le cycle de vie d'une API
Section intitulée « Le cycle de vie d'une API »Une API Kubernetes ne disparaît jamais du jour au lendemain : elle traverse cinq
états, et le nom de la version (v1alpha1, v1beta1, v1) suffit à savoir où
elle en est. La colonne à surveiller dans le tableau ci-dessous est la
durée typique : c'est elle qui vous dit combien de temps vous avez pour
migrer une fois l'avertissement apparu. Le piège classique consiste à croire
qu'une API beta est sûre parce qu'elle est activée par défaut, alors que
sa fenêtre de suppression est deux fois plus courte que celle d'une API stable.
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌────────────┐ ┌─────────┐│ Alpha │ ──▶ │ Beta │ ──▶ │ Stable │ ──▶ │ Deprecated │ ──▶ │ Removed ││ v1alpha1│ │ v1beta1 │ │ v1 │ │ v1 │ │ - │└─────────┘ └─────────┘ └─────────┘ └────────────┘ └─────────┘ Expérimental Pré-stable Stable Obsolète Supprimé| Phase | Caractéristiques | Durée typique |
|---|---|---|
Alpha (v1alpha1) | Désactivé par défaut, peut changer ou disparaître sans préavis | Variable |
Beta (v1beta1) | Activé par défaut, testé mais peut encore évoluer | 9+ mois minimum |
Stable (v1) | Garanti compatible, pas de changements cassants | Indéfini |
| Deprecated | Toujours fonctionnel mais marqué obsolète, warnings dans les logs | 12+ mois |
| Removed | Supprimé, les manifests échouent | - |
Impact concret sur vos déploiements
Section intitulée « Impact concret sur vos déploiements »La différence entre dépréciation et suppression se voit à l'exécution. Une API
dépréciée applique la ressource et écrit un avertissement que personne ne
lit dans les journaux de CI. Une API supprimée renvoie une erreur bloquante,
et le message ci-dessous est trompeur : il parle de CRD alors que le vrai
problème est un apiVersion que le cluster ne sert plus.
Quand une API est supprimée :
kubectl apply -f deployment-old.yamlerror: resource mapping not found for name: "my-app" namespace: ""from "deployment-old.yaml": no matches for kind "Deployment" in version "extensions/v1beta1"ensure CRDs are installed firstVotre manifest devient inapplicable. Le cluster ne reconnaît plus cette combinaison apiVersion + kind.
Exemples historiques de suppressions majeures
Section intitulée « Exemples historiques de suppressions majeures »Ces suppressions ont cassé des milliers de déploiements. Apprenez de l'histoire pour ne pas la répéter.
Kubernetes 1.16, Le grand nettoyage
Section intitulée « Kubernetes 1.16, Le grand nettoyage »Les API extensions/v1beta1 et apps/v1beta1 ont été supprimées après des années de dépréciation. La migration était mécanique, un simple changement d'apiVersion dans quatre lignes de YAML, mais un détail a piégé beaucoup d'équipes : apps/v1 rend le champ spec.selector obligatoire et immuable, alors que extensions/v1beta1 le déduisait des labels du template. Un kubectl apply sur un Deployment existant échouait donc même après correction de l'apiVersion.
| Ressource | Ancienne API (supprimée) | Nouvelle API |
|---|---|---|
| Deployment | extensions/v1beta1 | apps/v1 |
| DaemonSet | extensions/v1beta1 | apps/v1 |
| ReplicaSet | extensions/v1beta1 | apps/v1 |
| StatefulSet | apps/v1beta1 | apps/v1 |
Kubernetes 1.22, Ingress et autres
Section intitulée « Kubernetes 1.22, Ingress et autres »La vague 1.22 a été plus douloureuse que celle de 1.16 parce qu'elle ne se
limitait pas à un changement d'apiVersion. L'Ingress en networking.k8s.io/v1
impose une structure différente pour le backend et un champ pathType
obligatoire, ce qui casse les charts Helm dont les templates n'ont pas été
adaptés. Notez la double ligne du tableau : les manifests écrits avant 1.14
pointaient sur extensions/v1beta1, ceux écrits ensuite sur
networking.k8s.io/v1beta1, et les deux sont tombés dans la même version.
| Ressource | Ancienne API (supprimée) | Nouvelle API |
|---|---|---|
| Ingress | extensions/v1beta1 | networking.k8s.io/v1 |
| Ingress | networking.k8s.io/v1beta1 | networking.k8s.io/v1 |
| CertificateSigningRequest | certificates.k8s.io/v1beta1 | certificates.k8s.io/v1 |
| ValidatingWebhookConfiguration | admissionregistration.k8s.io/v1beta1 | admissionregistration.k8s.io/v1 |
Kubernetes 1.25, PodSecurityPolicy
Section intitulée « Kubernetes 1.25, PodSecurityPolicy »Deux des trois lignes du tableau se traitent par un remplacement d'apiVersion.
La troisième, PodSecurityPolicy, n'a pas d'équivalent : c'est le seul cas de
cette page où l'outillage automatique ne peut rien pour vous, parce que le
modèle de sécurité change complètement. Une organisation qui avait construit une
douzaine de PSP finement découpées par équipe a dû choisir entre les trois
profils standards des Pod Security Standards et l'écriture de politiques
dans un moteur d'admission tiers.
| Ressource | Ancienne API (supprimée) | Remplacement |
|---|---|---|
| PodSecurityPolicy | policy/v1beta1 | Pod Security Standards (PSS) |
| PodDisruptionBudget | policy/v1beta1 | policy/v1 |
| EndpointSlice | discovery.k8s.io/v1beta1 | discovery.k8s.io/v1 |
Détecter les API obsolètes
Section intitulée « Détecter les API obsolètes »Méthode 1 : kubectl avec warnings
Section intitulée « Méthode 1 : kubectl avec warnings »Depuis Kubernetes 1.19, kubectl affiche des warnings pour les API dépréciées :
kubectl apply -f old-ingress.yamlWarning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+;use networking.k8s.io/v1 Ingressingress.extensions/my-ingress createdLimitation : Vous ne voyez le warning qu'au moment de l'apply. Pas pratique pour auditer tous vos manifests.
Méthode 2 : API resources du cluster
Section intitulée « Méthode 2 : API resources du cluster »Listez les versions d'API supportées par votre cluster :
# Toutes les API disponibleskubectl api-versions
# Vérifier si une API existekubectl api-versions | grep networking.k8s.ioPour voir quelle version est préférée pour une ressource :
kubectl api-resources | grep -i ingressMéthode 3 : Audit avec Pluto
Section intitulée « Méthode 3 : Audit avec Pluto »Pluto est un outil CLI dédié à la détection des API obsolètes. Contrairement aux deux méthodes précédentes, il travaille sur des fichiers, ce qui permet de l'exécuter avant tout contact avec un cluster, donc dans une pull request. Il embarque sa propre base de versions Kubernetes et sait aussi lire les releases Helm stockées dans le cluster.
-
Installer Pluto
Le projet publie un fichier
checksums.txtà côté de chaque archive. Vérifiez l'empreinte avant d'extraire le binaire : c'est ce contrôle qui distingue une installation reproductible d'un téléchargement aveugle.Fenêtre de terminal brew install FairwindsOps/tap/plutoFenêtre de terminal PLUTO_VERSION=5.24.1BASE="https://github.com/FairwindsOps/pluto/releases/download/v${PLUTO_VERSION}"curl -sSLO "${BASE}/pluto_${PLUTO_VERSION}_linux_amd64.tar.gz"curl -sSLO "${BASE}/checksums.txt"grep "pluto_${PLUTO_VERSION}_linux_amd64.tar.gz" checksums.txt | sha256sum --check -tar xzf "pluto_${PLUTO_VERSION}_linux_amd64.tar.gz" plutosudo install -m 0755 pluto /usr/local/bin/plutoLa vérification doit afficher
pluto_5.24.1_linux_amd64.tar.gz: OK. Toute autre sortie signifie que l'archive est corrompue ou altérée, n'extrayez pas. -
Scanner un répertoire de manifests
Fenêtre de terminal pluto detect-files -d ./manifests/Sortie :
NAME KIND VERSION REPLACEMENT REMOVED DEPRECATED REPL AVAILmy-ingress Ingress extensions/v1beta1 networking.k8s.io/v1 true true truerestricted PodSecurityPolicy policy/v1beta1 true true falseLa colonne
REPL AVAILest celle qui décide de votre charge de travail : àtrue, un remplacement existe et la migration se résume à changer l'apiVersion. Àfalse, comme pour la PodSecurityPolicy ci-dessus, il n'y a pas de ressource équivalente et il faut repenser la configuration. -
Scanner les releases Helm déployées
Les charts installés dans le cluster échappent aux scans de fichiers, puisque le YAML rendu n'existe nulle part sur disque. Pluto va le lire dans les secrets de release Helm.
Fenêtre de terminal pluto detect-helm -owide -
Cibler une version Kubernetes spécifique
Par défaut, Pluto compare aux versions de sa base interne. En fixant la version cible, vous obtenez la liste exacte de ce qui cassera lors de la montée de version prévue, sans bruit sur les API encore valides.
Fenêtre de terminal pluto detect-files -d ./manifests/ --target-versions k8s=v1.29.0
Méthode 4 : kubent (Kube No Trouble)
Section intitulée « Méthode 4 : kubent (Kube No Trouble) »kubent prend le problème par l'autre bout : au lieu de lire vos fichiers, il interroge le cluster et énumère les objets réellement stockés dans etcd. C'est le seul moyen de repérer les ressources créées à la main, par un opérateur ou par un ancien pipeline, dont le YAML n'est plus dans aucun dépôt Git.
Le projet ne publie pas de fichier de sommes de contrôle pour ses archives, mais il fournit une image de conteneur. L'épingler par digest garantit que vous exécutez exactement le binaire vérifié :
# kubent 0.7.3, image épinglée par digestdocker run --rm \ -v "$HOME/.kube/config:/.kube/config:ro" \ ghcr.io/doitintl/kube-no-trouble@sha256:33016a690ca145963a0689cbe00a8499e1ba4d33c43629f9140d52e1ba698a2b \ --kubeconfig /.kube/configSur un poste où kubent est déjà installé, la commande se réduit à kubent. La sortie regroupe les objets par version de Kubernetes qui les supprimera :
>>> Deprecated APIs removed in 1.25 <<<-----------------------------------------KIND NAMESPACE NAME API_VERSIONPodSecurityPolicy <cluster> restricted policy/v1beta1Migrer vers les nouvelles API
Section intitulée « Migrer vers les nouvelles API »Méthode 1 : kubectl convert
Section intitulée « Méthode 1 : kubectl convert »Le plugin kubectl convert transforme les manifests vers une nouvelle API. Ce n'est pas une sous-commande native de kubectl : c'est un binaire séparé que la documentation Kubernetes distribue à part et que kubectl découvre grâce à son nom kubectl-convert. Le projet publie une empreinte SHA-256 à côté de chaque binaire ; le contrôle ci-dessous prend dix secondes et évite d'exécuter un fichier altéré en transit.
-
Installer le plugin
Fenêtre de terminal K8S_VERSION="$(curl -sSL https://dl.k8s.io/release/stable.txt)"BASE="https://dl.k8s.io/release/${K8S_VERSION}/bin/linux/amd64"curl -sSLO "${BASE}/kubectl-convert"curl -sSLO "${BASE}/kubectl-convert.sha256"echo "$(cat kubectl-convert.sha256) kubectl-convert" | sha256sum --check -sudo install -m 0755 kubectl-convert /usr/local/bin/kubectl-convertLa commande de vérification doit afficher
kubectl-convert: OK. Contrôlez ensuite quekubectlreconnaît le plugin aveckubectl convert --help. -
Convertir un manifest
Fenêtre de terminal kubectl convert -f old-ingress.yaml --output-version networking.k8s.io/v1 > new-ingress.yaml -
Vérifier le résultat
Le fichier converti peut nécessiter des ajustements manuels. Par exemple, l'Ingress v1 exige le champ
pathType:# Avant (v1beta1) - pas de pathType- path: /api# Après (v1) - pathType obligatoire- path: /apipathType: Prefix # ou Exact, ImplementationSpecific
Méthode 2 : Migration manuelle
Section intitulée « Méthode 2 : Migration manuelle »Dès qu'un champ change de forme, comme le backend d'un Ingress qui passe d'une paire de clés plates à un objet imbriqué, la conversion automatique atteint ses limites. Le processus ci-dessous ajoute deux garde-fous que kubectl convert n'offre pas : une sauvegarde de l'objet vivant avant modification, et une lecture du guide de migration officiel, qui documente les champs sans équivalent.
-
Sauvegarder la ressource actuelle
Fenêtre de terminal kubectl get ingress my-ingress -o yaml > backup-ingress.yaml -
Consulter la documentation de migration
Kubernetes publie des guides de migration pour chaque version majeure :
-
Adapter le manifest
Exemple pour Ingress v1beta1 → v1 :
# AvantapiVersion: networking.k8s.io/v1beta1kind: Ingressmetadata:name: my-ingressspec:rules:- host: example.comhttp:paths:- path: /apibackend:serviceName: api-serviceservicePort: 80# AprèsapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: my-ingressspec:rules:- host: example.comhttp:paths:- path: /apipathType: Prefix # NOUVEAU: obligatoirebackend:service: # NOUVEAU: structure imbriquéename: api-serviceport:number: 80 -
Appliquer et valider
Fenêtre de terminal kubectl apply -f new-ingress.yamlkubectl describe ingress my-ingress
Automatiser la détection en CI/CD
Section intitulée « Automatiser la détection en CI/CD »GitHub Actions avec Pluto
Section intitulée « GitHub Actions avec Pluto »Le déclencheur pull_request filtré sur manifests/** et charts/** évite de faire tourner le scan à chaque commit de documentation. Deux points de ce workflow méritent attention : la version de Pluto est figée avec vérification d'empreinte, pour qu'une mise à jour amont ne change pas silencieusement le verdict de la CI, et --target-versions désigne la version de cluster que vous visez, pas celle que vous exécutez aujourd'hui.
name: Check Kubernetes API deprecations
on: pull_request: paths: - 'manifests/**' - 'charts/**'
permissions: {}
jobs: pluto: runs-on: ubuntu-24.04 permissions: contents: read
env: PLUTO_VERSION: "5.24.1"
steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false
- name: Install Pluto run: | base="https://github.com/FairwindsOps/pluto/releases/download/v${PLUTO_VERSION}" curl -sSLO "${base}/pluto_${PLUTO_VERSION}_linux_amd64.tar.gz" curl -sSLO "${base}/checksums.txt" grep "pluto_${PLUTO_VERSION}_linux_amd64.tar.gz" checksums.txt | sha256sum --check - tar xzf "pluto_${PLUTO_VERSION}_linux_amd64.tar.gz" pluto sudo install -m 0755 pluto /usr/local/bin/pluto
- name: Check manifests run: pluto detect-files -d ./manifests/ --target-versions k8s=v1.30.0
- name: Check Helm charts run: | for chart in ./charts/*/; do helm template test "$chart" | pluto detect - doneCodes de sortie Pluto
Section intitulée « Codes de sortie Pluto »Pluto ne se contente pas d'afficher un rapport, il traduit la gravité dans son code de sortie. C'est ce qui permet de bloquer une pull request sans analyser la sortie texte. Un quatrième code existe en plus des trois du tableau : 4 signifie qu'une API supprimée n'a aucun remplacement disponible, le cas de la PodSecurityPolicy. Les options --ignore-deprecations, --ignore-removals et --ignore-unavailable-replacements neutralisent chacune le code correspondant.
| Code | Signification | Action CI/CD |
|---|---|---|
| 0 | Aucune API obsolète | Continuer |
| 2 | API dépréciées trouvées | Avertir (optionnel) |
| 3 | API supprimées trouvées | Bloquer le merge |
Le piège, dans une étape GitHub Actions, est que le shell tourne avec set -e : si Pluto sort en 3, l'étape s'arrête avant même d'atteindre la ligne qui lit $?. Il faut donc capturer le code dans la même commande.
- name: Check and fail on removed APIs run: | exit_code=0 pluto detect-files -d ./manifests/ --target-versions k8s=v1.30.0 || exit_code=$? if [ "$exit_code" -ge 3 ]; then echo "::error::API supprimées détectées, migration requise." exit 1 fi if [ "$exit_code" -eq 2 ]; then echo "::warning::API dépréciées détectées." fiGitLab CI
Section intitulée « GitLab CI »La logique est la même côté GitLab, avec une différence utile : le format de sortie markdown produit un rapport lisible que vous conservez en artefact. Le when: always est indispensable, sans lui l'artefact disparaît précisément dans le cas qui vous intéresse, celui où le job échoue parce que des API supprimées ont été trouvées.
api-deprecation-check: stage: validate image: alpine:3.22 variables: PLUTO_VERSION: "5.24.1" before_script: - apk add --no-cache curl tar - base="https://github.com/FairwindsOps/pluto/releases/download/v${PLUTO_VERSION}" - curl -sSLO "${base}/pluto_${PLUTO_VERSION}_linux_amd64.tar.gz" - curl -sSLO "${base}/checksums.txt" - grep "pluto_${PLUTO_VERSION}_linux_amd64.tar.gz" checksums.txt | sha256sum -c - - tar xzf "pluto_${PLUTO_VERSION}_linux_amd64.tar.gz" pluto - install -m 0755 pluto /usr/local/bin/pluto script: - pluto detect-files -d ./manifests/ --target-versions k8s=v1.30.0 -o markdown > deprecation-report.md artifacts: paths: - deprecation-report.md when: always allow_failure: falseBonnes pratiques
Section intitulée « Bonnes pratiques »Avant une mise à jour de cluster
Section intitulée « Avant une mise à jour de cluster »L'ordre de ces cinq étapes n'est pas négociable, et c'est le point que les
équipes inversent le plus souvent : on met à jour le cluster, puis on découvre
les manifests cassés. La migration doit précéder la montée de version, parce
qu'un manifest écrit dans la nouvelle apiVersion fonctionne déjà sur l'ancien
cluster, alors que l'inverse est faux.
- Scanner tous les manifests avec Pluto ou kubent
- Cibler la version cible :
--target-versions k8s=v1.X.0 - Migrer et tester en environnement staging
- Mettre à jour les charts Helm si vous en utilisez
- Mettre à jour le cluster seulement après migration
Maintenance continue
Section intitulée « Maintenance continue »Scanner uniquement au moment de l'upgrade transforme la montée de version en chantier. Le rythme ci-dessous répartit l'effort : le contrôle en pull request empêche l'arrivée de nouvelles dettes, et le scan mensuel ciblant la version actuelle plus deux vous donne l'avance nécessaire pour migrer sans urgence, puisque Kubernetes publie environ trois versions mineures par an.
| Fréquence | Action |
|---|---|
| À chaque PR | Scanner les manifests modifiés |
| Mensuel | Scanner tout le repo avec la version K8s actuelle + 2 |
| Avant upgrade | Rapport complet sur la version cible |
Référence de compatibilité
Section intitulée « Référence de compatibilité »Les outils embarquent une base de versions figée au moment de leur compilation :
sur une version de Kubernetes récente, ils peuvent ignorer une dépréciation
annoncée après leur dernière release. Les trois pages ci-dessous font autorité.
La première explique les règles du jeu, la deuxième donne le tableau
exhaustif API par API, et la troisième précise l'écart de version toléré
entre kubectl, le plan de contrôle et les kubelets.
À retenir
Section intitulée « À retenir »- Les API Kubernetes suivent un cycle : alpha → beta → stable → deprecated → removed
- Une API dépréciée fonctionne encore (avec warnings), une API supprimée casse vos déploiements
- Kubernetes garantit 12 mois minimum entre dépréciation et suppression pour les API stables
- Utilisez Pluto ou kubent pour détecter les API obsolètes dans vos manifests et votre cluster
- kubectl convert migre les manifests simples, mais les changements structurels nécessitent une réécriture manuelle
- Automatisez la détection dans votre CI/CD pour bloquer les PR avec des API supprimées
- Scannez avant chaque upgrade de cluster avec la version cible
Testez vos Connaissances
Section intitulée « Testez vos Connaissances »Dix questions pour vérifier que vous distinguez bien une API dépréciée d'une API supprimée, et que vous savez quel outil sortir selon que la ressource vit dans un fichier ou dans le cluster.
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