Introduction
Les ReplicaSets sont un contrôleur Kubernetes essentiel qui garantit qu'un nombre spécifié de réplicas de pods identiques fonctionnent à tout moment. Lorsque des pods ne démarrent pas, évoluent de manière inattendue ou entrent dans des boucles de crash, un ReplicaSet est souvent impliqué. Le dépannage de ces problèmes nécessite une approche systématique : observer l'état actuel, inspecter les événements et les journaux, identifier le composant défaillant, appliquer une correction minimale et vérifier la récupération.
Cet article s'adresse aux développeurs, consultants DevOps et équipes techniques de startups qui doivent diagnostiquer et résoudre des problèmes liés aux ReplicaSets dans de vrais clusters. Il se concentre sur les commandes pratiques, les sorties attendues, les signaux de défaillance et les décisions de récupération nécessaires lorsqu'un ReplicaSet se comporte mal. À la fin, vous saurez comment inspecter les ReplicaSets et leurs pods, interpréter les conditions clés, corriger les problèmes courants comme les échecs de tirage d'image, les boucles de crash et les incohérences de sélecteur, et prévenir les récidives.
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 les résultats et documenter les étapes de récupération. Chaque commande de dépannage dans ce guide est en lecture seule, sauf indication explicite de modification.
Inventaire de la version et de l'environnement
Avant de toucher à quoi que ce soit, confirmez avec quoi vous travaillez. Le comportement d'un ReplicaSet dépend de la version de Kubernetes, du groupe d'API et du contexte de l'espace de noms. Vérifiez d'abord ces éléments.
Vérifier la version de Kubernetes et la disponibilité de l'API
kubectl version --short
Exemple de sortie :
Client Version: v1.28.2
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.28.2
Les ReplicaSets sont stables depuis Kubernetes 1.9 (apps/v1). Si vous utilisez un cluster plus ancien (avant la version 1.9), vous devrez peut-être utiliser extensions/v1beta1 ou apps/v1beta1. À partir de Kubernetes 1.16, les anciennes versions d'API ont été supprimées. Vérifiez avec :
kubectl api-resources | grep replicaset
Résultat attendu :
replicasets rs apps/v1 true ReplicaSet
Notez le groupe d'API (apps/v1) et si la ressource est liée à un espace de noms (true). Toutes les opérations ReplicaSet sont limitées à un espace de noms.
Inventorier les ReplicaSets existants
Listez tous les ReplicaSets dans l'espace de noms actuel :
kubectl get rs
Exemple de sortie :
NAME DESIRED CURRENT READY AGE
frontend-rs 3 3 3 10m
backend-rs 2 2 1 2h
Les colonnes :
DESIRED: nombre de réplicas souhaités par le ReplicaSet.CURRENT: nombre de réplicas qui ont été créés.READY: nombre de réplicas prêts à servir le trafic.AGE: durée d'existence du ReplicaSet.
Un premier signal courant est une incohérence entre DESIRED et READY. Par exemple, backend-rs ci-dessus veut 2 réplicas mais seulement 1 est prêt. Nous allons creuser la raison dans un instant.
Pour voir les ReplicaSets dans tous les espaces de noms :
kubectl get rs -A
Consultez les détails d'un ReplicaSet spécifique :
kubectl describe rs frontend-rs
Recherchez les Events en bas, qui montrent les actions récentes du contrôleur comme la création ou la suppression de pods. Notez également le Selector et le Pod Template ; ils doivent correspondre aux pods qu'il gère.
Prérequis pour le dépannage
Vous avez besoin de :
kubectlconfiguré avec un accès au cluster.jqouyqpour analyser la sortie JSON/YAML (facultatif mais utile).- Un accès aux journaux des conteneurs, soit directement, soit via une plateforme de journalisation.
- Des autorisations pour lire les ressources ReplicaSet, Pod et Event dans l'espace de noms cible. La lecture seule suffit pour le diagnostic.
- Aucun secret dans vos lignes de commande ; utilisez des variables d'environnement ou des fichiers temporaires pour les données sensibles.
Une commande d'inventaire initiale sûre est :
kubectl get rs,po -o wide
Cela affiche les ReplicaSets et leurs pods avec le placement des nœuds, les adresses IP et l'état. Observez avant de modifier quoi que ce soit.
Chemin de configuration sûr
Lorsqu'un ReplicaSet se comporte mal, l'impulsion naturelle est de le supprimer et de le recréer. Cela peut provoquer une panne, surtout si le ReplicaSet est géré par un déploiement (Deployment). Au lieu de cela, suivez un chemin sûr : comprenez la configuration actuelle, identifiez l'incohérence exacte et apportez le plus petit changement possible avec un retour en arrière connu.
Lire le manifeste actuel
Exportez le manifeste en direct d'un ReplicaSet :
kubectl get rs frontend-rs -o yaml > frontend-rs-live.yaml
Examinez-le attentivement. Recherchez :
spec.replicas: le nombre souhaité.spec.selector: le sélecteur d'étiquettes utilisé pour trouver les pods à gérer.spec.template.metadata.labels: les étiquettes appliquées aux nouveaux pods. Elles doivent correspondre au sélecteur.spec.template.spec.containers[].image: les images et étiquettes des conteneurs.spec.template.spec.containers[].resources: les demandes et limites de CPU/mémoire.spec.template.spec.containers[].env: les variables d'environnement (vérifiez les fautes de frappe ou les valeurs manquantes).
Une erreur courante est une incohérence de sélecteur. Par exemple, si le sélecteur est app: frontend mais que les étiquettes du modèle de pod sont app: web, les pods sont créés mais jamais adoptés, ce qui entraîne des pods orphelins et un ReplicaSet qui signale 0 prêt. Voici un extrait défectueux :
spec:
replicas: 3
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: web
Pour corriger cela, mettez à jour l'étiquette du modèle vers app: frontend ou mettez à jour le sélecteur. Comme les sélecteurs sont immuables après création, vous devrez peut-être supprimer et recréer le ReplicaSet, mais seulement après avoir confirmé qu'il n'est pas géré par un déploiement (voir section suivante).
Vérifier si le ReplicaSet appartient à un déploiement
Les déploiements créent automatiquement des ReplicaSets et gèrent leur cycle de vie. Si vous modifiez ou supprimez directement un ReplicaSet appartenant à un déploiement, le contrôleur du déploiement le recréera ou le réajustera. Pour trouver le propriétaire :
kubectl get rs frontend-rs -o jsonpath='{.metadata.ownerReferences}' | jq
S'il existe une référence de propriétaire vers un déploiement (kind : Deployment), apportez les modifications au niveau du déploiement :
kubectl edit deployment frontend-deployment
Cette méthode garantit que l'historique de déploiement est préservé et vous pouvez revenir en arrière avec kubectl rollout undo deployment frontend-deployment.
Apporter un changement petit et testable
Lors de l'ajustement de la configuration, ne modifiez qu'un seul champ à la fois. Par exemple, si vous devez mettre à jour l'étiquette d'image, faites-le seul, puis vérifiez l'état du pod. Voici un exemple utilisant un patch pour mettre à jour l'image d'un ReplicaSet autonome :
kubectl patch rs frontend-rs -p '{"spec":{"template":{"spec":{"containers":[{"name":"web","image":"nginx:1.25.3"}]}}}}'
Si le ReplicaSet est géré par un déploiement, patchez plutôt le déploiement :
kubectl set image deployment/frontend-deployment web=nginx:1.25.3
Ensuite, surveillez le déploiement :
kubectl rollout status deployment/frontend-deployment
Sortie attendue en cas de succès :
deployment "frontend-deployment" successfully rolled out
Si le déploiement se bloque, examinez le nouveau ReplicaSet et les pods comme décrit dans la section Modes de défaillance.
Garder les tests locaux petits
Avant d'appliquer un changement à un cluster de production, testez-le dans un espace de noms local ou de développement. Par exemple, créez un manifeste de ReplicaSet minimal et appliquez-le à un espace de noms de test :
cat <<EOF | kubectl apply -n test -f -
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: test-rs
spec:
replicas: 1
selector:
matchLabels:
app: test
template:
metadata:
labels:
app: test
spec:
containers:
- name: nginx
image: nginx:1.25.3
ports:
- containerPort: 80
EOF
Ensuite, vérifiez avec kubectl get rs,pods -n test. Si cela fonctionne, vous pouvez appliquer en toute confiance le changement équivalent à la production. Pour accéder au pod localement, utilisez kubectl port-forward pour vérifier qu'il sert le trafic :
kubectl port-forward rs/test-rs 8080:80
Ensuite, curl localhost:8080 devrait renvoyer la page d'accueil de nginx.
Vérification et diagnostics
Après avoir apporté un changement, ou lorsque vous remarquez un problème pour la première fois, vous devez vérifier l'état réel du ReplicaSet et de ses pods. Cette section fournit un flux de diagnostic systématique avec des commandes concrètes et des sorties attendues.
Étape 1 : Vérifier les détails de l'état du ReplicaSet
Utilisez kubectl describe pour voir les conditions et les événements :
kubectl describe rs frontend-rs
Recherchez une section Conditions (présente dans les versions plus récentes de Kubernetes) et la liste Events. Exemple d'extrait :
Conditions:
Type Status Reason
---- ------ ------
ReplicaFailure True FailedCreate
FailedCreate signifie généralement que le contrôleur ReplicaSet n'a pas pu créer un pod. Les événements afficheront l'erreur, comme un quota dépassé ou un nom d'image invalide.
Si les conditions ne sont pas affichées, vérifiez directement les événements :
kubectl get events --field-selector involvedObject.name=frontend-rs --sort-by=.lastTimestamp
Étape 2 : Inspecter les pods appartenant au ReplicaSet
Listez les pods avec leurs références de propriétaire :
kubectl get pods -l app=frontend -o wide
Notez la colonne STATUS : Pending, Running, CrashLoopBackOff, ImagePullBackOff, ErrImagePull, etc. Si les pods sont manquants, vérifiez si le ReplicaSet en a créé :
kubectl get pods --selector=app=frontend
Si aucun pod n'apparaît mais que le DESIRED du ReplicaSet est supérieur à 0, examinez les événements du ReplicaSet pour en connaître les raisons (par exemple, FailedCreate en raison d'un quota ou d'une autorisation).
Pour un pod qui n'est pas prêt, inspectez les détails :
kubectl describe pod <pod-name>
Concentrez-vous sur :
Conditions:PodScheduled,Initialized,ContainersReady,Ready.Events: messages sur le tirage d'image, les échecs de démarrage du conteneur, les échecs de sonde, etc.
Étape 3 : Afficher les journaux du conteneur
Pour un pod en cours d'exécution, obtenez les journaux :
kubectl logs <pod-name> -c <container-name>
Si le conteneur a planté et redémarré, utilisez --previous pour voir les journaux de la dernière instance terminée :
kubectl logs <pod-name> -c <container-name> --previous
Exemple de sortie indiquant un plantage dû à une configuration manquante :
panic: unable to open config file: /etc/app/config.yaml
Pour les pods en CrashLoopBackOff, les journaux révèlent souvent la cause première. Si le conteneur se termine immédiatement sans journaux, vérifiez le code de sortie :
kubectl get pod <pod-name> -o jsonpath='{.status.containerStatuses[0].state.terminated.exitCode}'
Codes de sortie courants : 1 (erreur d'application), 2 (mauvais usage des commandes shell intégrées), 137 (SIGKILL, souvent OOM), 143 (SIGTERM, arrêt gracieux).
Étape 4 : Vérifier l'utilisation des ressources et les conditions du nœud
Les pods peuvent ne pas démarrer en raison de ressources insuffisantes. Vérifiez la capacité du nœud et les demandes :
kubectl top nodes
Et l'utilisation des ressources par les pods :
kubectl top pods
Si vous soupçonnez un problème de planification, décrivez le pod et recherchez des événements comme :
Warning FailedScheduling 0/3 nodes are available: 3 Insufficient cpu.
Ensuite, réduisez les réplicas ou les demandes de ressources, ou faites évoluer les nœuds.
Étape 5 : Valider les sélecteurs et les étiquettes
Un mode de défaillance silencieux est un ReplicaSet qui signale READY=0 parce que les pods ne correspondent pas au sélecteur. Vérifiez les étiquettes des pods :
kubectl get pods -l app=frontend --show-labels
Comparez avec le sélecteur du ReplicaSet :
kubectl get rs frontend-rs -o jsonpath='{.spec.selector}'
Si les étiquettes ne correspondent pas, les pods peuvent être orphelins. Vous pouvez les adopter en mettant à jour leurs étiquettes (si approprié) ou corriger le modèle du ReplicaSet et déclencher un déploiement.
Modes de défaillance et récupération
Cette section couvre les modes de défaillance les plus courants des ReplicaSets avec les symptômes, le diagnostic et les étapes de récupération. Vérifiez toujours la correction et documentez ce que vous avez fait.
1. ImagePullBackOff ou ErrImagePull
Symptôme : Les pods restent en Pending ou ContainerCreating, puis affichent ImagePullBackOff ou ErrImagePull.
Diagnostic :
kubectl describe pod <pod-name>
Recherchez des événements comme :
Warning Failed 2m (x4 over 5m) kubelet Failed to pull image "nginx:1.25.3": rpc error: code = NotFound desc = failed to pull and unpack image ... manifest for nginx:1.25.3 not found: manifest unknown
Cela signifie que l'étiquette d'image n'existe pas ou que le registre est inaccessible. Vérifiez également les erreurs d'authentification si vous utilisez un registre privé : no basic auth credentials ou unauthorized: authentication required.
Récupération
- Vérifiez le nom et l'étiquette de l'image. Utilisez une étiquette connue et fiable, par exemple
nginx:1.25.3-alpine. - Si vous utilisez un registre privé, assurez-vous que le pod dispose d'un
imagePullSecret:
spec:
template:
spec:
imagePullSecrets:
- name: regcred
Créez le secret si nécessaire :
kubectl create secret docker-registry regcred \
--docker-server=myregistry.example.com \
--docker-username=myuser \
--docker-password=mypassword \
[email protected]
Ensuite, mettez à jour le ReplicaSet ou le déploiement. Pour un déploiement, le déploiement créera un nouveau ReplicaSet avec le modèle corrigé.
Vérification : Surveillez les pods jusqu'à ce qu'ils deviennent Running et prêts :
kubectl get pods -w
Ensuite, vérifiez l'état du ReplicaSet :
kubectl get rs frontend-rs
Attendez-vous à DESIRED == CURRENT == READY.
2. CrashLoopBackOff
Symptôme : Les pods démarrent mais se terminent immédiatement, et le nombre de redémarrages augmente. L'état affiche CrashLoopBackOff.
Diagnostic :
kubectl logs <pod-name> --previous
Examinez l'erreur de l'application. Vérifiez également le code de sortie :
kubectl get pod <pod-name> -o jsonpath='{.status.containerStatuses[*].lastState.terminated.exitCode}'
Causes courantes :
- Fichier de configuration ou variable d'environnement manquant.
- Bug de l'application provoquant une panique.
- Sonde de vivacité qui échoue parce que l'application n'est pas prête à temps.
- Limite de ressources trop basse provoquant une mise à mort OOM.
Récupération :
- Corrigez le problème sous-jacent (mettez à jour la carte de configuration, le secret, l'image ou les limites de ressources).
- Pour les problèmes de sonde, ajustez le délai initial ou le seuil d'échec. Par exemple, augmentez
initialDelaySecondsde 0 à 10 pour une application à démarrage lent. - Si l'application est sans état, supprimez le pod pour forcer un redémarrage :
kubectl delete pod <pod-name>(le ReplicaSet le recréera). Mais c'est une solution temporaire ; traitez la cause première.
Vérification : Après la correction, surveillez la stabilisation du nombre de redémarrages :
kubectl get pods -w
Si les redémarrages s'arrêtent, le problème est résolu.
3. Le ReplicaSet ne crée pas de pods (FailedCreate)
Symptôme : Le DESIRED du ReplicaSet est supérieur au CURRENT, et les événements affichent FailedCreate.
Diagnostic :
kubectl describe rs <rs-name>
Recherchez les événements indiquant les raisons :
exceeded quota: limites de quota de ressources dans l'espace de noms.forbidden: autorisations RBAC manquantes.cannot set blockOwnerDeletion: problème de référence de propriétaire.invalid pod spec: mauvaise configuration.
Récupération :
- Si le quota est dépassé, augmentez le quota de l'espace de noms ou réduisez les demandes de ressources/réplicas.
- Si RBAC interdit, accordez les autorisations nécessaires au compte de service du contrôleur.
- Si la spécification du pod est invalide, corrigez le modèle (par exemple, mauvais nom de champ, champ requis manquant).
Vérification : Surveillez les événements et le nombre de pods :
kubectl get events --sort-by=.lastTimestamp | tail -20
kubectl get rs <rs-name>
4. Les pods sont créés mais ne deviennent jamais prêts
Symptôme : La colonne READY affiche une fraction ou 0, par exemple 0/1.
Diagnostic :
kubectl describe pod <pod-name>
Vérifiez les Conditions pour Ready et ContainersReady. Les événements peuvent montrer des échecs de sonde de préparation. Vérifiez également les journaux pour les erreurs de démarrage de l'application.
Récupération :
- Si la sonde de préparation est mal configurée (mauvais chemin, port ou délai initial), corrigez-la.
- Si l'application prend plus de temps à démarrer, augmentez
initialDelaySecondsoufailureThreshold. - Si une dépendance est manquante (base de données, service), assurez-vous qu'elle est disponible.
Vérification : Après avoir appliqué la correction, surveillez :
kubectl rollout status deployment/<deployment-name> # si géré par un déploiement
ou pour un ReplicaSet autonome :
kubectl get rs <rs-name> -w
5. Incohérence de sélecteur du ReplicaSet menant à des pods orphelins
Symptôme : Le ReplicaSet pense qu'il n'a pas de pods (READY=0), mais vous voyez des pods avec des étiquettes similaires en cours d'exécution. De plus, kubectl get rs peut afficher CURRENT=0 alors que DESIRED=3.
Diagnostic :
kubectl get rs <rs-name> -o jsonpath='{.spec.selector}'
kubectl get pods --show-labels
Comparez les étiquettes. Si les pods ont des étiquettes différentes, ils ne sont pas sélectionnés.
Récupération :
- Si le ReplicaSet est autonome, vous pouvez soit mettre à jour les étiquettes des pods pour qu'elles correspondent au sélecteur (si vous voulez les adopter), soit supprimer le ReplicaSet et le recréer avec le bon sélecteur/modèle.
- Si le ReplicaSet appartient à un déploiement, mettez à jour les étiquettes du modèle de pod du déploiement. Le déploiement créera un nouveau ReplicaSet avec un sélecteur correspondant et réduira progressivement l'ancien.
- Soyez prudent : changer les sélecteurs peut provoquer des pods en double temporaires. Utilisez
kubectl get pods -wpour surveiller.
Vérification : Assurez-vous que le ReplicaSet affiche maintenant READY == DESIRED.
Principes généraux de récupération
- Prenez toujours un instantané avant les changements :
kubectl get rs <name> -o yaml > rs-backup.yaml. - Pour les déploiements, utilisez le retour en arrière :
kubectl rollout undo deployment/<name>pour revenir à une révision précédente fonctionnelle. - Documentez chaque changement et sa vérification dans un journal d'incident.
- Si un ReplicaSet est bloqué et non géré par un déploiement, vous pouvez le supprimer, mais seulement après vous être assuré que ses pods sont en sécurité ou seront recréés par un autre contrôleur.
Liste de contrôle des opérations
Utilisez cette liste de contrôle lors du dépannage de tout problème de ReplicaSet. Elle consolide les actions clés en un flux de travail reproductible.
1. Observer sans changements
- [ ] Exécutez
kubectl get rs -n <namespace>pour voir les ReplicaSets et leurs nombres souhaités/actuels/prêts. - [ ] Exécutez
kubectl get pods -n <namespace> -o widepour voir l'état des pods et la distribution des nœuds. - [ ] Exécutez
kubectl describe rs <rs-name>pour afficher les conditions et les événements. - [ ] Pour tout pod défaillant, exécutez
kubectl describe pod <pod-name>etkubectl logs <pod-name> --previoussi nécessaire.
2. Identifier le mode de défaillance
- [ ] Vérifiez
ImagePullBackOff: erreurs de nom/étiquette d'image, authentification du registre. - [ ] Vérifiez
CrashLoopBackOff: erreurs d'application, codes de sortie, mauvaises configurations de sonde. - [ ] Vérifiez
FailedCreate: quota, RBAC, spécification invalide. - [ ] Vérifiez les échecs de préparation : paramètres de sonde, disponibilité des dépendances.
- [ ] Vérifiez les incohérences de sélecteur : étiquettes des pods par rapport au sélecteur.
3. Planifier une correction minimale
- [ ] Sauvegardez le manifeste actuel :
kubectl get rs <rs-name> -o yaml > rs-backup.yaml. - [ ] Si géré par un déploiement, modifiez le déploiement, pas le ReplicaSet.
- [ ] Modifiez un champ à la fois (image, environnement, ressources, sonde, étiquettes).
- [ ] Utilisez
kubectl applyoukubectl patchavec un changement limité.
4. Appliquer et vérifier
- [ ] Pour les déploiements, exécutez
kubectl apply -f deployment.yamletkubectl rollout status deployment/<name>. - [ ] Pour les ReplicaSets autonomes, exécutez
kubectl apply -f rs.yamlpuiskubectl get pods -wpour surveiller les pods. - [ ] Vérifiez les journaux des nouveaux pods :
kubectl logs <pod-name>. - [ ] Confirmez que le nombre
READYdu ReplicaSet correspond auDESIRED.
5. Documenter et surveiller
- [ ] Enregistrez l'erreur d'origine, le changement apporté et le résultat de la vérification.
- [ ] Mettez en place des alertes sur l'état des ReplicaSets si possible (par exemple,
kubectl get rsvia un outil de surveillance). - [ ] Examinez les quotas de ressources et la capacité du cluster si le problème était lié aux ressources.
- [ ] Envisagez d'ajouter des sondes de préparation/vivacité avec des délais appropriés pour prévenir les futures boucles de crash.
Exemple d'entrée de liste de contrôle pour un incident réel
Contexte : backend-rs avait READY = 1 mais DESIRED = 2. Un pod était en CrashLoopBackOff.
- Observé avec
kubectl get rs backend-rsetkubectl describe pod backend-rs-abcde. - Journaux trouvés :
Error: unable to connect to database at 10.96.0.10:5432. - Diagnostic : l'adresse IP du service de base de données a changé ; la variable d'environnement dans le pod était obsolète.
- Correction : mise à jour de la ConfigMap
backend-configavec le bon hôte de base de données, puis redémarrage des pods viakubectl rollout restart deployment backend-deployment. - Vérifié :
kubectl rollout status deployment backend-deploymenta réussi ;kubectl get rs backend-rsa montréREADY = 2.
Conclusion
Le dépannage des ReplicaSets est une compétence fondamentale pour quiconque exploite Kubernetes. En suivant une approche structurée, vous pouvez rapidement passer du symptôme à la résolution tout en minimisant les risques. Rappelez-vous ces principes :
- Observer d'abord : utilisez des commandes en lecture seule (
get,describe,logs) pour recueillir les faits. - Isoler la panne : déterminez si elle est liée au tirage d'image, au plantage du conteneur, à la planification ou au sélecteur.
- Appliquer des changements minimaux : corrigez une chose à la fois, et sauvegardez toujours l'état actuel.
- Vérifier la récupération : assurez-vous que le nombre de prêts du ReplicaSet correspond au souhaité et que les pods sont stables.
- Documenter et améliorer : enregistrez ce qui s'est passé et ajustez les sondes, les demandes de ressources ou les stratégies de déploiement pour prévenir les récidives.
Comme prochaine étape, choisissez un ReplicaSet dans votre cluster et exécutez la liste de contrôle de diagnostic. Entraînez-vous d'abord sur un espace de noms non productif. Par exemple, créez un ReplicaSet avec une étiquette d'image volontairement erronée, puis travaillez sur le mode de défaillance et les étapes de récupération. Cette expérience pratique renforcera votre confiance pour les incidents réels.
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 la récupération avant qu'un incident ne force la décision.