Introduction
Les politiques de redémarrage Docker contrôlent si les conteneurs redémarrent automatiquement après leur arrêt. Elles sont essentielles pour maintenir les services en fonctionnement et récupérer après une défaillance. Mais les politiques de redémarrage ne garantissent pas à elles seules la disponibilité d'une application. Il faut aussi penser à la capacité : combien de conteneurs, quelle quantité de CPU et de mémoire, combien de tentatives de redémarrage et comment éviter les boucles de redémarrage qui gaspillent les ressources.
Cet article combine la configuration des politiques de redémarrage avec la planification de capacité. Vous verrez des commandes concrètes, des extraits de configuration et des exemples détaillés. L'objectif est la sécurité opérationnelle : observer avant de changer, limiter le rayon d'impact, utiliser des espaces réservés plutôt que des secrets, vérifier le résultat et documenter comment récupérer si l'état attendu n'est pas atteint.
Ce guide s'adresse aux développeurs, ingénieurs DevOps et équipes techniques de startups qui exécutent Docker en production ou dans des environnements de type production. À la fin, vous saurez configurer des politiques de redémarrage adaptées à votre charge de travail, définir des limites de ressources pour éviter les voisins bruyants et planifier les pannes sans surprovisionner.
Inventaire des versions et de l'environnement
Avant de toucher aux politiques de redémarrage ou à la capacité, établissez une base de référence. Sachez quelle version de Docker vous utilisez, quels conteneurs existent et quelles ressources ils consomment. Cela évite les surprises et vous donne un point de restauration.
Commencez par des commandes en lecture seule :
docker version
La sortie attendue montre les versions client et serveur. Notez la version de l'API ; le comportement des politiques de redémarrage est stable dans les versions récentes, mais le mode swarm et les versions de fichier compose sont importants.
Listez les conteneurs en cours d'exécution :
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
La colonne statut montre les compteurs de redémarrage, par exemple « Up 2 hours (restarting 3 times) ». C'est un signal d'alarme.
Inspectez un conteneur spécifique pour voir sa politique de redémarrage actuelle et ses limites de ressources :
docker inspect <conteneur> --format '{{.HostConfig.RestartPolicy}} {{.HostConfig.Memory}} {{.HostConfig.NanoCpus}}'
Sortie attendue : {no 0 0} si aucune politique, ou {always 1073741824 500000000} signifiant redémarrage toujours, 1 Go de mémoire, 0,5 CPU.
Pour les projets Docker Compose, utilisez :
docker compose ps
docker compose logs -f <service>
docker compose exec <service> sh
Vérifiez aussi où les fichiers sont stockés. Les volumes nommés (par exemple, app_data:/var/lib/app) sont gérés par Docker et plus faciles à réutiliser lors des reconstructions de conteneurs. Les montages bind (par exemple, ./data:/var/lib/app) mappent directement vers un chemin hôte, utiles en développement mais pouvant causer des problèmes de permissions et de portabilité. Confirmez la persistance des données avec un test de redémarrage : arrêtez le conteneur, recréez-le et assurez-vous que l'application voit toujours les fichiers attendus. Si les données disparaissent, le service écrivait dans le système de fichiers du conteneur plutôt que dans un volume ou un montage.
Exécutez un petit test local de type production pour vérifier la persistance avant de déployer les changements en staging ou en production.
Chemin de configuration sûr
Modifier les politiques de redémarrage et les limites de ressources exige une démarche réfléchie. D'abord, capturez l'état actuel. Ensuite, faites un changement ciblé, vérifiez-le et documentez la récupération.
Choisir une politique de redémarrage
Docker prend en charge quatre valeurs de politique de redémarrage :
no: ne pas redémarrer automatiquement le conteneur (par défaut).on-failure[:max-retries]: redémarrer seulement si le conteneur se termine avec un code de sortie non nul. Possibilité de limiter le nombre de tentatives. Par exemple,on-failure:5redémarre au maximum 5 fois.always: toujours redémarrer le conteneur quel que soit le code de sortie. S'il est arrêté manuellement, il ne redémarre que lorsque le démon Docker redémarre ou que le conteneur est démarré manuellement.unless-stopped: similaire àalways, mais si le conteneur a été arrêté manuellement avant le redémarrage du démon, il ne sera pas redémarré.
Utilisez unless-stopped pour la plupart des services de longue durée. Cela évite de redémarrer de manière inattendue des conteneurs intentionnellement arrêtés pour maintenance. Utilisez on-failure pour les travaux par lots ou les tâches ponctuelles où des redémarrages infinis pourraient boucler. Évitez always sauf raison spécifique, car cela peut masquer des erreurs de configuration en redémarrant sans cesse un conteneur cassé.
Exemple : exécutez un serveur web avec unless-stopped et limitez les redémarrages :
docker run -d --name web \
--restart unless-stopped \
--memory 512m \
--cpus 0.5 \
nginx:alpine
Pour une base de données qui ne doit pas redémarrer automatiquement en cas de corruption de données, utilisez on-failure:3 :
docker run -d --name db \
--restart on-failure:3 \
-e POSTGRES_PASSWORD=secret \
postgres:15
Dans Docker Compose, déclarez les politiques sous le service :
services:
web:
image: nginx:alpine
restart: unless-stopped
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
Note : restart est ignoré en mode swarm ; utilisez plutôt deploy.restart_policy.
Bases de la planification de capacité
La planification de capacité ne se limite pas aux politiques de redémarrage ; elle vise à garantir que les conteneurs disposent de suffisamment de ressources pour fonctionner et que l'hôte peut supporter la charge. Définissez des limites de mémoire et de CPU sur chaque conteneur pour éviter qu'un seul conteneur n'épuise l'hôte.
Limites de mémoire : utilisez --memory et --memory-swap. Si un conteneur dépasse sa limite de mémoire, le noyau peut tuer le processus (OOM). Exemple :
docker run -d --name app --memory 1g --memory-swap 2g myapp
Limites CPU : utilisez --cpus pour limiter le nombre de cœurs CPU. Exemple : --cpus 1.5 autorise 1,5 cœur. Vous pouvez aussi utiliser les parts CPU pour une pondération relative.
Surveillez l'utilisation réelle avec docker stats :
docker stats --no-stream
La sortie montre le pourcentage CPU, l'utilisation mémoire et la limite. Utilisez-la pour ajuster les limites.
Pensez aux boucles de redémarrage : si un conteneur sort et redémarre de façon répétée, il peut consommer des cycles CPU. Configurez on-failure avec un nombre maximal de tentatives et combinez avec un healthcheck pour éviter les boucles infinies.
Mise en œuvre sûre des changements
Pour modifier les politiques, procédez dans cet ordre :
- Enregistrez l'état actuel :
docker inspect <conteneur> > avant.json - Faites le changement : recréez le conteneur ou mettez à jour le fichier compose puis
docker compose up -d - Vérifiez : contrôlez la politique de redémarrage et les limites de ressources avec
docker inspect - Testez la panne : arrêtez manuellement le conteneur et observez s'il redémarre comme prévu
- Retour arrière : si nécessaire, utilisez le fichier
avant.jsonsauvegardé pour recréer la configuration d'origine
Ne modifiez jamais un conteneur en cours d'exécution directement. Recréez toujours à partir d'une configuration connue (Dockerfile, fichier compose ou commande run).
Vérification et diagnostic
Après avoir configuré les politiques de redémarrage et les limites de ressources, vérifiez qu'elles fonctionnent comme prévu. Utilisez une combinaison de commandes pour observer le comportement.
Simuler une panne
Pour tester une politique de redémarrage, arrêtez le conteneur et observez :
docker stop web
docker ps -a
Si la politique est unless-stopped, le conteneur ne redémarre pas immédiatement car il a été arrêté manuellement. Pour tester le redémarrage sur panne, tuez le processus principal :
docker exec web kill 1
Puis vérifiez docker ps après quelques secondes : le conteneur devrait être de nouveau en cours d'exécution.
Pour on-failure, simulez une sortie non nulle en exécutant un conteneur qui se termine avec une erreur :
docker run --name failtest --restart on-failure:2 alpine sh -c 'exit 1'
Vérifiez le compteur de redémarrages :
docker inspect failtest --format '{{.RestartCount}}'
Il devrait être de 2 (exécution initiale plus un redémarrage) puis cesser de réessayer.
Diagnostiquer les boucles de redémarrage
Un conteneur bloqué dans une boucle de redémarrage montre un compteur de redémarrages qui augmente rapidement. Causes courantes :
- Configuration cassée (par exemple, mauvaise variable d'environnement)
- Dépendances manquantes (base de données pas prête)
- OOM kills car limite de mémoire trop basse
- Plantage applicatif dû à un bug
Utilisez les journaux pour trouver la raison :
docker logs web --tail 100
Vérifiez docker inspect pour les OOM kills :
docker inspect web --format '{{.State.OOMKilled}}'
Si vrai, augmentez la limite de mémoire ou corrigez la fuite mémoire.
Utilisez des healthchecks pour empêcher le routage du trafic vers un conteneur en mauvaise santé. Exemple de Dockerfile :
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost/ || exit 1
Dans Compose :
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/"]
interval: 30s
timeout: 3s
retries: 3
Un conteneur sain avec une politique de redémarrage est plus résilient.
Observer l'utilisation des ressources
Pour planifier la capacité, surveillez l'utilisation réelle au fil du temps. Utilisez docker stats périodiquement ou intégrez des outils de surveillance comme Prometheus et cAdvisor. Pour un instantané rapide :
docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}"
Notez le pourcentage de mémoire par rapport à la limite. S'il est constamment supérieur à 80 %, envisagez d'augmenter la limite ou d'optimiser l'application.
Modes de défaillance et récupération
Même avec de bonnes politiques de redémarrage, des pannes surviennent. Comprenez les modes de défaillance courants et comment récupérer.
Pièges des politiques de redémarrage
- Boucles de redémarrage infinies : sans nombre maximal de tentatives, un conteneur cassé peut redémarrer pour toujours, consommant du CPU et remplissant les journaux. Utilisez
on-failureavec une limite pour les tâches qui doivent finir par abandonner. - Masquage des erreurs de configuration :
alwaysouunless-stoppedpeuvent garder un conteneur en cours d'exécution mais dans un mauvais état. Surveillez les journaux et les healthchecks pour les détecter. - Conteneurs avec état : redémarrer un conteneur de base de données sans persistance de données appropriée peut entraîner une perte de données. Utilisez toujours des volumes et testez la persistance.
- Ordre des dépendances : si un conteneur redémarre avant que sa dépendance soit prête, il peut échouer à nouveau. Utilisez
depends_onavec condition dans Compose (dans les versions récentes) ou un conteneur d'initialisation.
Procédures de récupération
Si un conteneur est dans une boucle de redémarrage :
- Arrêtez le conteneur pour briser la boucle :
docker stop <conteneur> - Inspectez les journaux pour trouver la cause racine :
docker logs <conteneur> - Corrigez le problème : mettez à jour la configuration, augmentez la mémoire, corrigez le code ou attendez la dépendance
- Démarrez le conteneur manuellement :
docker start <conteneur> - Vérifiez qu'il reste en fonctionnement et en bonne santé.
Si l'hôte est à court de ressources (OOM), identifiez le coupable avec docker stats et docker events --filter event=oom. Réduisez les limites sur d'autres conteneurs ou ajoutez de la capacité.
Pour les services avec état, entraînez-vous à la récupération : simulez la perte d'un conteneur et restaurez à partir d'une sauvegarde. Assurez-vous que les sauvegardes sont testées régulièrement.
Liste de contrôle des opérations
Utilisez cette liste de contrôle avant et après avoir modifié les politiques de redémarrage et les paramètres de capacité. Attribuez un responsable à chaque élément et révisez au moins mensuellement.
| Élément | Responsable | Fréquence |
|---|---|---|
| Examiner les politiques de redémarrage de tous les conteneurs de production | Responsable DevOps (par ex., Priya Shah) | Mensuelle |
| Vérifier les compteurs de redémarrage et identifier les boucles | Ingénieur d'astreinte | Quotidienne via surveillance |
| Valider les limites de mémoire et CPU par rapport à l'utilisation réelle | Planificateur de capacité | Hebdomadaire |
| Tester la persistance des données et la restauration des sauvegardes | Administrateur de base de données | Trimestrielle |
| Simuler une panne de conteneur et vérifier le redémarrage automatique | Ingénieur QA | Après chaque version |
| Mettre à jour les procédures avec les étapes de récupération | Rédacteur technique ou responsable DevOps | Lors de changements |
Pour chaque élément, documentez l'état actuel, l'état attendu et la commande de vérification. Tenez un journal des changements avec horodatages et responsables.
Pièges courants et comment les éviter
Les pièges proviennent souvent de mauvaises configurations ou de malentendus sur les politiques de redémarrage et les limites de ressources.
1. Ignorer les boucles de redémarrage
Pourquoi cela arrive : les développeurs définissent always sans backoff ni surveillance. Un conteneur plante au démarrage à cause d'une configuration manquante et boucle pour toujours, consommant du CPU et remplissant les journaux.
Comment éviter : utilisez on-failure avec un nombre maximal de tentatives pour les services non critiques. Pour les services critiques, utilisez des healthchecks et des alertes sur les compteurs de redémarrage. Configurez la rotation des journaux pour éviter l'épuisement du disque.
2. Ne pas limiter la mémoire et le CPU
Pourquoi cela arrive : les équipes oublient de définir des limites ou supposent que l'hôte a assez de ressources. Un conteneur avec une fuite mémoire peut amener le noyau à tuer d'autres processus.
Comment éviter : définissez toujours --memory et --cpus pour les conteneurs de production. Utilisez docker stats pour surveiller l'utilisation et ajuster les limites. Envisagez une plateforme d'orchestration de conteneurs (Kubernetes, Swarm) qui applique des quotas de ressources.
3. Mal comprendre always vs unless-stopped
Pourquoi cela arrive : les utilisateurs pensent que always convient à tous les services, mais il redémarre les conteneurs même après un arrêt manuel. Cela peut interférer avec les fenêtres de maintenance.
Comment éviter : utilisez unless-stopped pour les services qui doivent fonctionner jusqu'à un arrêt intentionnel. Utilisez always seulement si vous voulez toujours que le conteneur soit en cours d'exécution, même après un redémarrage du démon et indépendamment des arrêts manuels.
4. Être bloqué avec les tentatives on-failure
Pourquoi cela arrive : définir on-failure:10 sur un conteneur qui a une erreur persistante entraîne 10 redémarrages puis l'arrêt du conteneur. Si personne ne le remarque, le service reste hors ligne.
Comment éviter : combinez on-failure avec des alertes. Surveillez l'état des conteneurs et envoyez des notifications lorsqu'un conteneur entre dans un état arrêté après des tentatives. Envisagez unless-stopped avec un healthcheck pour l'auto-réparation.
Conclusion
Les politiques de redémarrage Docker sont un élément clé de la résilience des conteneurs, mais elles doivent être configurées en tenant compte de la planification de capacité. Sans limites, les conteneurs peuvent consommer des ressources excessives et provoquer une instabilité de l'hôte. Sans politiques appropriées, un conteneur cassé peut boucler indéfiniment ou échouer silencieusement.
En suivant les pratiques de cet article—établir une base de référence, choisir la bonne politique de redémarrage, définir des limites de ressources, vérifier le comportement et planifier la récupération—vous pouvez maintenir un environnement de conteneurs stable et efficace.
Comme prochaine étape, choisissez un conteneur dans votre environnement, examinez sa politique de redémarrage et ses limites de ressources, et exécutez une simulation de panne. Documentez les résultats et partagez-les avec votre équipe. Faites-en un processus d'examen régulier pour détecter les problèmes avant qu'ils ne provoquent des temps d'arrêt.
Rappelez-vous : un flux de travail fiable rend la panne visible, protège les valeurs sensibles, limite les changements et définit la vérification de la récupération à l'avance.
À vous de jouer : utilisez les listes de contrôle, les commandes et les exemples pour renforcer vos conteneurs.