
Votre application a besoin de télécharger une config avant de démarrer ? Ou de collecter ses logs vers un système centralisé ? Les init containers et les sidecars répondent à ces besoins sans modifier votre code applicatif.
Ce guide vous montre comment utiliser ces deux patterns, quand les choisir, et comment éviter les erreurs courantes.
Prérequis : concepts des Pods Kubernetes et un cluster fonctionnel.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Créer un init container qui prépare des données avant le démarrage
- Configurer un sidecar qui tourne en parallèle de votre application
- Distinguer le pattern sidecar du sidecar natif Kubernetes
- Comprendre quand utiliser (et quand éviter) chaque approche
- Diagnostiquer les problèmes avec les bonnes commandes
Ce que partagent les conteneurs d'un Pod
Section intitulée « Ce que partagent les conteneurs d'un Pod »Avant d'entrer dans les détails, rappelons pourquoi init containers et sidecars sont utiles : tous les conteneurs d'un même Pod partagent :
| Ressource | Ce qui est partagé |
|---|---|
| Réseau | Même adresse IP, même espace réseau (localhost fonctionne entre conteneurs) |
| Volumes | Mêmes volumes montés selon la configuration |
| Scheduling | Même nœud, même unité de déploiement |
| Cycle de vie | Démarrent et s'arrêtent ensemble |
C'est ce partage qui rend les patterns init container et sidecar possibles et puissants.
Comprendre les init containers
Section intitulée « Comprendre les init containers »Un init container est un conteneur qui s'exécute avant les conteneurs principaux du Pod. Il doit se terminer avec succès pour que l'application démarre.
Comportement des init containers
Section intitulée « Comportement des init containers »Les init containers ont un comportement strict :
- Ils s'exécutent séquentiellement, dans l'ordre de déclaration
- Chaque init container doit réussir (exit code 0) avant le suivant
- En cas d'échec, le kubelet relance l'init container selon la
restartPolicy - Les conteneurs applicatifs ne démarrent qu'après la réussite de tous les init containers
Cas d'usage des init containers
Section intitulée « Cas d'usage des init containers »| Cas d'usage | Exemple concret |
|---|---|
| Télécharger des fichiers | Récupérer une config depuis S3 ou un dépôt Git |
| Attendre un service | Vérifier que MySQL répond avant de lancer l'app |
| Initialiser des données | Appliquer des migrations de base de données |
| Préparer le filesystem | Créer des répertoires, décompresser des archives |
Créer un init container
Section intitulée « Créer un init container »Exemple : préparer une configuration
Section intitulée « Exemple : préparer une configuration »Cet init container écrit un fichier de configuration que le conteneur principal utilise :
apiVersion: v1kind: Podmetadata: name: init-demospec: initContainers: - name: init-download image: busybox:1.36 command: ['sh', '-c', 'echo "Config chargée à $(date)" > /data/config.txt && sleep 2'] volumeMounts: - name: shared-data mountPath: /data containers: - name: app image: busybox:1.36 command: ['sh', '-c', 'cat /data/config.txt && sleep 3600'] volumeMounts: - name: shared-data mountPath: /data volumes: - name: shared-data emptyDir: {}kubectl apply -f init-container-demo.yamlObserver le démarrage
Section intitulée « Observer le démarrage »kubectl get pod init-demo -wSortie pendant l'initialisation :
NAME READY STATUS RESTARTS AGEinit-demo 0/1 Init:0/1 0 2sinit-demo 0/1 PodInitializing 0 4sinit-demo 1/1 Running 0 5sLe statut Init:0/1 indique que l'init container n'est pas encore terminé.
Vérifier que l'init a fonctionné
Section intitulée « Vérifier que l'init a fonctionné »kubectl logs init-demo -c appSortie attendue :
Config chargée à Sun Mar 22 08:44:45 UTC 2026Le conteneur principal a bien lu le fichier créé par l'init container.
Init container : attendre un service
Section intitulée « Init container : attendre un service »Un cas très courant est d'attendre qu'un service soit disponible :
apiVersion: v1kind: Podmetadata: name: webappspec: initContainers: - name: wait-for-db image: busybox:1.36 command: ['sh', '-c', 'until nc -z mysql 3306; do echo "Attente MySQL..."; sleep 2; done'] containers: - name: app image: nginx:1.31.3-alpineL'init container boucle jusqu'à ce que MySQL réponde sur le port 3306.
Ajouter un timeout
Section intitulée « Ajouter un timeout »Sans limite de temps, un init container peut bloquer indéfiniment :
command: ['sh', '-c', 'timeout 60 sh -c "until nc -z mysql 3306; do sleep 2; done"']Deux façons de parler de sidecar
Section intitulée « Deux façons de parler de sidecar »Il existe deux réalités qu'il faut distinguer :
Pattern sidecar (conceptuel)
Section intitulée « Pattern sidecar (conceptuel) »Historiquement, un sidecar désigne simplement un second conteneur dans
spec.containers qui accompagne le conteneur principal. C'est un pattern
d'architecture, pas une fonctionnalité Kubernetes.
spec: containers: - name: app image: myapp:1.0 - name: log-collector # Sidecar "classique" image: fluent/fluent-bit:2.0@sha256:ed49fc97830a302c5ae8dfe6dc5758afa3d6bf4b4a172de21256292faf121e7cLes deux conteneurs démarrent ensemble, sans ordre garanti.
Sidecar natif (fonctionnalité Kubernetes)
Section intitulée « Sidecar natif (fonctionnalité Kubernetes) »Depuis Kubernetes v1.29, une fonctionnalité dédiée permet de déclarer
des sidecars avec un cycle de vie contrôlé. Un sidecar natif est un
init container avec restartPolicy: Always.
spec: initContainers: - name: log-agent image: fluent/fluent-bit:2.0@sha256:ed49fc97830a302c5ae8dfe6dc5758afa3d6bf4b4a172de21256292faf121e7c restartPolicy: Always # C'est un sidecar natif !Différences entre les deux approches
Section intitulée « Différences entre les deux approches »Les deux premières lignes du tableau expliquent à elles seules pourquoi le
sidecar natif a été ajouté au projet. Avec le pattern classique, rien ne
garantit que le proxy ou l'agent de logs soit opérationnel quand l'application
émet sa première requête : le kubelet démarre tous les conteneurs de
spec.containers en parallèle. La ligne Arrêt est tout aussi importante
pour les traitements par lots : un log-collector déclaré dans
spec.containers continue de tourner après la fin du conteneur principal, ce
qui empêche un Job d'atteindre l'état Completed et le laisse en
Running indéfiniment.
| Aspect | Pattern classique | Sidecar natif |
|---|---|---|
| Déclaration | spec.containers | spec.initContainers avec restartPolicy: Always |
| Ordre de démarrage | Pas garanti | Démarre avant le conteneur principal |
| Arrêt | Pas d'ordre | S'arrête après le conteneur principal |
| Redémarrage | Peut crasher le Pod | Redémarre indépendamment |
Créer un sidecar classique
Section intitulée « Créer un sidecar classique »Exemple : collecteur de logs
Section intitulée « Exemple : collecteur de logs »Le sidecar lit les logs écrits par l'application principale dans un fichier partagé :
apiVersion: v1kind: Podmetadata: name: sidecar-demospec: containers: - name: app image: busybox:1.36 command: ['sh', '-c', 'while true; do echo "$(date) - Requête traitée" >> /var/log/app.log; sleep 5; done'] volumeMounts: - name: logs mountPath: /var/log - name: log-collector image: busybox:1.36 command: ['sh', '-c', 'tail -f /var/log/app.log'] volumeMounts: - name: logs mountPath: /var/log volumes: - name: logs emptyDir: {}kubectl apply -f sidecar-demo.yamlVérifier le sidecar
Section intitulée « Vérifier le sidecar »kubectl get pod sidecar-demoSortie :
NAME READY STATUS RESTARTS AGEsidecar-demo 2/2 Running 0 15s2/2 Running confirme que les deux conteneurs tournent.
kubectl logs sidecar-demo -c log-collectorSortie :
Sun Mar 22 08:45:07 UTC 2026 - Requête traitéeSun Mar 22 08:45:12 UTC 2026 - Requête traitéeCréer un sidecar natif (v1.29+)
Section intitulée « Créer un sidecar natif (v1.29+) »Les sidecars natifs offrent un meilleur contrôle du cycle de vie :
apiVersion: v1kind: Podmetadata: name: native-sidecarspec: initContainers: - name: log-agent image: busybox:1.36 restartPolicy: Always # Sidecar natif ! command: ['sh', '-c', 'tail -f /var/log/app.log 2>/dev/null || sleep infinity'] volumeMounts: - name: logs mountPath: /var/log containers: - name: app image: busybox:1.36 command: ['sh', '-c', 'while true; do echo "$(date) - Log" >> /var/log/app.log; sleep 5; done'] volumeMounts: - name: logs mountPath: /var/log volumes: - name: logs emptyDir: {}Avantages du sidecar natif :
- Démarre avant le conteneur principal (comme un init container)
- Tourne pendant toute la vie du Pod (comme un sidecar classique)
- S'arrête proprement après le conteneur principal
- Peut redémarrer sans faire crasher le Pod entier
Après kubectl apply, kubectl get pod native-sidecar affiche bien 2/2 Running : le sidecar natif est compté dans les conteneurs prêts, alors qu'un
init container ordinaire ne l'est pas. En revanche kubectl logs native-sidecar -c log-agent ne renvoie rien ici, et c'est précisément la
démonstration du mécanisme : log-agent démarre avant le conteneur app,
donc /var/log/app.log n'existe pas encore quand tail -f s'exécute, la
commande bascule sur sleep infinity. Un vrai agent de logs gère ce cas
(Fluent Bit surveille le répertoire et attend l'apparition du fichier).
Quand choisir init container ou sidecar
Section intitulée « Quand choisir init container ou sidecar »Tableau de décision
Section intitulée « Tableau de décision »Le critère de tri est la durée de vie du besoin, pas sa nature. Une tâche
qui a une fin (télécharger un fichier, appliquer une migration) va dans un
init container ; une tâche qui doit accompagner l'application tant qu'elle
tourne (collecter, exporter, relayer) va dans un sidecar. La ligne
« Attendre une dépendance » porte un ⚠️ volontaire : elle fonctionne aussi en
sidecar, mais l'application démarrerait alors avant que la dépendance soit
disponible, ce qui déplace le problème au lieu de le régler.
| Besoin | Init container | Sidecar |
|---|---|---|
| Préparer des fichiers avant démarrage | ✅ Oui | ❌ Non |
| Attendre une dépendance | ✅ Oui (avec timeout) | ⚠️ Rarement |
| Collecter des logs pendant la vie du Pod | ❌ Non | ✅ Oui |
| Proxy réseau local au Pod | ❌ Non | ✅ Oui |
| Exécuter une migration ponctuelle | ✅ Oui | ❌ Non |
| Synchroniser des fichiers en continu | ❌ Non | ✅ Oui |
| Exporter des métriques | ❌ Non | ✅ Oui |
Cas d'usage des sidecars
Section intitulée « Cas d'usage des sidecars »Ces quatre familles couvrent la quasi-totalité des sidecars rencontrés en
production. Le point commun qui les justifie est l'accès au contexte local du
Pod : le localhost partagé pour un proxy Envoy, un volume emptyDir
commun pour Fluent Bit ou git-sync. Si votre besoin ne réclame ni le
réseau ni les volumes du Pod, la section suivante montre pourquoi un sidecar
est alors le mauvais outil.
| Pattern | Exemple |
|---|---|
| Log collector | Fluent Bit, Filebeat → Elasticsearch/Loki |
| Proxy | Envoy, Istio pour le service mesh |
| Sync | Git-sync pour fichiers de config |
| Monitoring | Exporter des métriques Prometheus |
Quand éviter un sidecar
Section intitulée « Quand éviter un sidecar »Un sidecar n'est pas toujours la bonne solution :
| Situation | Pourquoi éviter | Alternative |
|---|---|---|
| Fonction mutualisable | Un sidecar par Pod = N instances | DaemonSet (1 par nœud) |
| Besoin uniquement au build | Pas besoin en runtime | Job CI/CD |
| Fonction indépendante du Pod | Couplage inutile | Deployment séparé |
| Logs vers stdout | Le nœud collecte déjà | Aucun sidecar nécessaire |
| Proxy cluster-wide | Duplication massive | Ingress ou service mesh |
Impact sur les ressources
Section intitulée « Impact sur les ressources »Chaque conteneur supplémentaire consomme des ressources :
- CPU et mémoire : l'init container allonge le démarrage, le sidecar consomme en continu
- I/O disque : si le sidecar écrit beaucoup (logs, métriques)
- Bande passante : si le sidecar envoie des données vers l'extérieur
Bonnes pratiques
Section intitulée « Bonnes pratiques »initContainers:- name: init-download image: busybox:1.36 resources: requests: cpu: "50m" memory: "32Mi" limits: cpu: "100m" memory: "64Mi"Déclarez aussi les resources de vos sidecars pour éviter les surprises en
production.
Combiner init containers et sidecars
Section intitulée « Combiner init containers et sidecars »Un Pod peut avoir les deux :
apiVersion: v1kind: Podmetadata: name: full-stackspec: initContainers: - name: download-config image: busybox:1.36 command: ['sh', '-c', 'echo "DB_HOST=mysql" > /config/env'] volumeMounts: - name: config mountPath: /config containers: - name: app image: busybox:1.36 command: ['sh', '-c', 'cat /config/env && while true; do echo "$(date) - Request" >> /logs/app.log; sleep 5; done'] volumeMounts: - name: config mountPath: /config - name: logs mountPath: /logs - name: log-shipper image: busybox:1.36 command: ['sh', '-c', 'tail -f /logs/app.log'] volumeMounts: - name: logs mountPath: /logs volumes: - name: config emptyDir: {} - name: logs emptyDir: {}Flux d'exécution :
download-config(init) prépare la configurationappetlog-shipperdémarrent ensemblelog-shippertransmet les logs en continu
Anti-patterns à éviter
Section intitulée « Anti-patterns à éviter »Sept erreurs récurrentes, classées de la plus fréquente à la plus subtile. Les deux premières lignes causent des incidents visibles et faciles à relier à leur origine. Les suivantes coûtent surtout du gaspillage de ressources et de la dette de maintenance, qui ne se remarquent qu'au moment où la facture ou la complexité deviennent gênantes. Relisez ce tableau après avoir écrit un manifeste multi-conteneurs, pas avant : plusieurs lignes ne parlent que si vous avez déjà le YAML sous les yeux.
| Anti-pattern | Conséquence | Solution |
|---|---|---|
| Attendre sans timeout | Pod bloqué indéfiniment | Ajouter timeout à la commande |
| Logique métier lourde en init | Démarrage très long | Externaliser dans un Job |
| Port ouvert = service prêt | Faux positifs | Test fonctionnel léger |
| Sidecar pour fonction mutualisable | Gaspillage de ressources | DaemonSet |
| chmod/chown en init container | Symptôme de mauvaise config | Utiliser securityContext |
Oublier resources sur les sidecars | Consommation non contrôlée | Déclarer requests/limits |
| Plusieurs conteneurs = plus de couplage | Maintenance complexe | Évaluer si vraiment nécessaire |
Dépannage
Section intitulée « Dépannage »Commandes essentielles
Section intitulée « Commandes essentielles »Cinq commandes suffisent, à lancer dans cet ordre. La difficulté propre aux
Pods multi-conteneurs est que kubectl logs mon-pod sans -c échoue ou choisit
un conteneur au hasard : le drapeau -c devient obligatoire dès qu'il y a
plus d'un conteneur. Notez aussi --previous à l'étape 3 : sans lui, vous lisez
les logs de l'instance en cours, pas ceux de celle qui a planté, et un
CrashLoopBackOff reste incompréhensible.
-
Voir l'état du Pod et des conteneurs
Fenêtre de terminal kubectl get pod mon-pod -o widekubectl get pod mon-pod -o yaml | grep -A 30 "containerStatuses" -
Examiner les détails des init containers
Fenêtre de terminal kubectl describe pod mon-pod | grep -A 30 "Init Containers" -
Lire les logs d'un init container
Fenêtre de terminal kubectl logs mon-pod -c nom-init-containerkubectl logs mon-pod -c nom-init-container --previous # Si redémarré -
Lire les logs d'un sidecar
Fenêtre de terminal kubectl logs mon-pod -c nom-sidecar -
Voir les événements récents
Fenêtre de terminal kubectl get events --sort-by=.lastTimestamp | grep mon-pod
Problèmes courants
Section intitulée « Problèmes courants »La colonne « Symptôme » se lit dans la sortie de kubectl get pods, colonne
STATUS. Le préfixe Init: est votre point de repère : il indique que le
Pod est encore dans sa phase d'initialisation, et donc que l'application n'a
même pas été lancée. Inutile de chercher du côté du conteneur applicatif tant
que ce préfixe est présent. Le chiffre qui suit (Init:0/1) compte les init
containers terminés sur le total déclaré.
| Symptôme | Cause probable | Solution |
|---|---|---|
Init:0/1 qui persiste | Init container bloqué ou en échec | Vérifier les logs : kubectl logs mon-pod -c init-xxx |
Init:CrashLoopBackOff | Commande qui échoue (exit code ≠ 0) | Corriger la commande ou l'image |
Init:ImagePullBackOff | Image introuvable | Vérifier le nom et le registry |
READY 1/2 | Un des conteneurs ne démarre pas | kubectl describe pod pour les événements |
| Sidecar natif qui ne tourne pas | restartPolicy: Always oublié | Ajouter le champ dans l'init container |
Exemple de diagnostic
Section intitulée « Exemple de diagnostic »La section Events de kubectl describe pod raconte le démarrage dans
l'ordre chronologique. L'élément le plus utile est le préfixe
spec.initContainers{...} ou spec.containers{...} devant chaque message :
il dit sans ambiguïté quel conteneur a produit l'événement, ce que la seule
colonne Reason ne permet pas de deviner quand plusieurs conteneurs tirent la
même image.
kubectl describe pod init-demoEvents: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 12s default-scheduler Successfully assigned default/init-demo to k3d-doc-vague8-server-0 Normal Pulling 12s kubelet spec.initContainers{init-download}: Pulling image "busybox:1.36" Normal Pulled 8s kubelet spec.initContainers{init-download}: Successfully pulled image "busybox:1.36" in 3.524s (3.524s including waiting). Image size: 2217006 bytes. Normal Created 8s kubelet spec.initContainers{init-download}: Created container init-download Normal Started 8s kubelet spec.initContainers{init-download}: Started container init-download Normal Pulled 6s kubelet spec.containers{app}: Container image "busybox:1.36" already present on machine Normal Created 6s kubelet spec.containers{app}: Created container app Normal Started 6s kubelet spec.containers{app}: Started container appIl n'existe pas d'événement signalant la fin réussie d'un init container :
la réussite se déduit du fait que les événements passent aux
spec.containers{...}. Un enchaînement qui s'arrête après le Started de
l'init container signifie que celui-ci tourne encore, ou qu'il boucle.
Réflexes CKAD
Section intitulée « Réflexes CKAD »En examen, voici le workflow efficace :
# 1. Créer le manifestkubectl run mypod --image=nginx --dry-run=client -o yaml > pod.yaml
# 2. Éditer pour ajouter initContainers (même niveau que containers)vim pod.yaml
# 3. Appliquerkubectl apply -f pod.yaml
# 4. Vérifier l'étatkubectl get pod mypod -w
# 5. Voir les logs de l'init containerkubectl logs mypod -c init-container-name
# 6. Voir les logs du conteneur principalkubectl logs mypod -c nginxStructure YAML minimale
Section intitulée « Structure YAML minimale »Ce squelette est le plus rentable à mémoriser pour l'examen, parce qu'il condense
les trois pièges d'indentation qui coûtent des points. initContainers est au
même niveau que containers, tous deux sous spec : les décaler d'un cran est
l'erreur la plus fréquente et elle passe le kubectl apply sans broncher avant
d'échouer plus loin. La section volumes se place également sous spec, et
chaque conteneur qui veut y accéder doit répéter son volumeMounts avec le même
name. Un montage déclaré côté init mais oublié côté app donne un fichier
préparé que l'application ne voit jamais.
apiVersion: v1kind: Podmetadata: name: mypodspec: initContainers: # Même niveau que containers - name: init-xxx image: busybox:1.36@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662 command: ['sh', '-c', 'echo done'] volumeMounts: - name: data mountPath: /data containers: - name: app image: nginx volumeMounts: - name: data mountPath: /data volumes: # Partagé entre tous les conteneurs - name: data emptyDir: {}À retenir
Section intitulée « À retenir »- Init container : s'exécute et se termine AVANT le conteneur principal
- Sidecar classique : conteneur dans
containers, tourne EN PARALLÈLE - Sidecar natif : init container avec
restartPolicy: Always(stable v1.33) - Les init containers s'exécutent séquentiellement, chacun doit réussir
- Les init containers ne supportent pas les probes ni lifecycle hooks
- Un port TCP ouvert ne garantit pas qu'un service est prêt
- Les conteneurs d'un Pod partagent réseau et volumes
- Chaque conteneur supplémentaire consomme des ressources
- Un sidecar qui peut être mutualisé devrait être un DaemonSet
- Commandes clés :
kubectl logs -c,kubectl describe,kubectl get events
Testez vos connaissances
Section intitulée « Testez vos connaissances »Ce quiz reprend les distinctions qui piègent le plus : ordre de démarrage, différence entre pattern classique et sidecar natif, absence de probes sur les init containers. Comptez cinq minutes et visez 80 % avant de passer à la suite ; en dessous, relisez la section « Différences entre les deux approches », c'est là que se concentrent les confusions.
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
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Volumes applicatifs : Le partage de données entre init container et conteneur principal.
- Définir les Probes : Les health checks à poser sur un sidecar pour qu'il ne bloque pas le Pod.
- Débugger une application : Le diagnostic d'un Pod figé sur un init container qui ne se termine jamais.