Introduction
Quand un conteneur plante en production à 3 h du matin, la différence entre un incident mineur et une panne complète tient souvent à un seul paramètre : la politique de redémarrage. Les politiques de redémarrage Docker déterminent si un conteneur redémarre automatiquement après sa sortie, et dans quelles conditions. Si vous les configurez mal, vous aurez soit des services qui restent silencieusement arrêtés, soit des conteneurs qui redémarrent sans fin, masquant des problèmes plus profonds.
Cet article constitue une liste de contrôle opérationnelle pratique pour utiliser les politiques de redémarrage Docker en production. Il s'adresse aux développeurs, consultants DevOps et équipes de startup qui doivent passer d'un problème observé à un résultat vérifié. Vous y trouverez des commandes concrètes, des sorties attendues, des extraits de configuration et des conseils de récupération. L'objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des variables fictives plutôt que des secrets, vérifier le résultat et documenter la façon de récupérer si l'état attendu n'est pas atteint.
Nous aborderons les quatre politiques de redémarrage (no, on-failure, unless-stopped, always), montrerons comment les définir via la CLI Docker et Docker Compose, expliquerons comment les inspecter et les tester, soulignerons les erreurs courantes et fournirons une liste de contrôle utilisable en production.
Comprendre les politiques de redémarrage Docker
Les politiques de redémarrage Docker contrôlent si un conteneur est automatiquement redémarré après son arrêt ou sa sortie. La politique est attachée au conteneur au moment de sa création et s'applique à la fois aux sorties normales et aux plantages, selon la politique.
Les quatre politiques intégrées sont :
| Politique | Comportement | Cas d'utilisation typique |
|---|---|---|
no | Ne jamais redémarrer automatiquement. | Tâches ponctuelles, conteneurs de débogage. |
on-failure[:max-retries] | Redémarrer uniquement si le conteneur sort avec un code non nul. Limite éventuelle du nombre de tentatives. | Services susceptibles de planter mais qui ne doivent pas réessayer indéfiniment. |
always | Toujours redémarrer, même si le conteneur s'arrête proprement. Redémarre aussi au démarrage du démon. | Services à longue durée de vie qui doivent toujours être actifs. |
unless-stopped | Toujours redémarrer, sauf si le conteneur a été arrêté manuellement par un opérateur. Redémarre au démarrage du démon s'il était en cours d'exécution auparavant. | Services qui doivent rester actifs, sauf arrêt délibéré. |
Comprendre ces politiques est la base. Les sections suivantes vous donnent un moyen systématique de les inspecter, de les définir et de les vérifier dans votre environnement.
Inventaire des versions et de l'environnement
Avant de toucher à une politique de redémarrage, vous devez savoir avec quoi vous travaillez. Un inventaire des versions et de l'environnement est la première étape de toute opération sûre. Il nomme le composant concerné, la plage de versions prises en charge, les prérequis et une observation en lecture seule.
Vérifier la version de Docker. Les politiques de redémarrage existent depuis des années, mais la syntaxe et le comportement peuvent varier légèrement. Exécutez :
docker version --format '{{.Server.Version}}'
Exemple de sortie attendue :
24.0.5
Vérifiez aussi la version de l'API si vous utilisez une bibliothèque cliente :
docker version --format '{{.Server.APIVersion}}'
Lister les conteneurs en cours d'exécution et leur statut. Utilisez une sortie formatée pour voir les noms, statuts et ports :
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
Exemple de sortie :
NAMES STATUS PORTS
web Up 3 hours 0.0.0.0:80->80/tcp
api Restarting (1) 2 seconds ago 0.0.0.0:8080->8080/tcp
Remarquez que le conteneur api affiche Restarting (1) 2 seconds ago. Cela indique qu'il a planté une fois et qu'il est redémarré par une politique. C'est une observation clé.
Inspecter la politique de redémarrage d'un conteneur. Utilisez docker inspect pour voir la politique actuelle et d'autres détails :
docker inspect <nom-du-conteneur> --format '{{.HostConfig.RestartPolicy.Name}} {{.HostConfig.RestartPolicy.MaximumRetryCount}}'
Pour un conteneur avec on-failure:5, la sortie serait :
on-failure 5
Vérifier les journaux pour détecter des schémas de plantage. Lisez les journaux récents pour comprendre pourquoi un conteneur redémarre :
docker logs <nom-du-conteneur> --tail 100
Pour les projets Docker Compose, utilisez docker compose ps et docker compose logs de manière similaire. Les services Compose peuvent avoir des politiques de redémarrage définies dans le fichier compose, qui remplacent les valeurs par défaut.
Vérification de la persistance des données. Lorsque vous modifiez les politiques de redémarrage ou recréez des conteneurs, assurez-vous que les données persistent. Confirmez où les fichiers sont stockés :
docker inspect <nom-du-conteneur> --format '{{json .Mounts}}'
Recherchez Type: volume (volume nommé) ou Type: bind (chemin hôte). Un volume nommé comme app_data:/var/lib/app est géré par Docker et survit à la recréation du conteneur. Un montage bind comme ./data:/var/lib/app mappe directement un répertoire hôte, ce qui est utile pour le développement mais peut causer des problèmes de permissions ou de portabilité si le chemin diffère d'une machine à l'autre.
Test pratique : Arrêtez le conteneur, recréez-le sans changer l'image et vérifiez que l'application voit toujours les fichiers attendus. Si les données disparaissent, le service écrivait dans la couche inscriptible du conteneur au lieu d'un volume. C'est un problème distinct à corriger avant de dépendre des politiques de redémarrage.
Avec cet inventaire, vous connaissez vos versions, les politiques actuelles et la disposition des données. Vous pouvez maintenant configurer les politiques en toute sécurité.
Chemin de configuration sûr
Modifier une politique de redémarrage est généralement peu risqué, mais le faire négligemment peut entraîner un comportement inattendu. Le chemin de configuration sûr implique de choisir la bonne politique, de l'appliquer de manière idempotente et de vérifier le changement.
Choisir la bonne politique
Posez deux questions :
- Le conteneur doit-il redémarrer tout seul ?
- Doit-il redémarrer même après un arrêt propre ?
Utilisez ce guide de décision :
| Situation | Politique recommandée |
|---|---|
| Tâche batch ponctuelle ou shell interactif | no |
| Conteneur cron-like avec nouvelle tentative interne | no ou on-failure |
| Serveur web ou API qui doit toujours fonctionner | always ou unless-stopped |
| Service qui ne doit pas redémarrer après un arrêt délibéré (par exemple, maintenance) | unless-stopped |
| Service qui doit réessayer uniquement en cas de plantage, avec une limite pour éviter les boucles de plantage | on-failure:5 |
Appliquer une politique via la CLI Docker
Pour un conteneur existant, vous ne pouvez pas modifier directement la politique de redémarrage. Vous devez recréer le conteneur avec la nouvelle politique. Utilisez docker update pour certaines limites de ressources, mais la politique de redémarrage n'en fait pas partie.
Exemple : recréer un conteneur nommé web avec unless-stopped :
# Arrêter et supprimer le conteneur existant (attention : assurez-vous que les données sont sur un volume)
docker rm -f web
# Exécuter un nouveau conteneur avec la politique
docker run -d --name web --restart unless-stopped -p 80:80 nginx:alpine
Vérifiez :
docker inspect web --format '{{.HostConfig.RestartPolicy.Name}}'
Sortie :
unless-stopped
Appliquer une politique via Docker Compose
Dans un fichier docker-compose.yml, définissez la clé restart sous un service :
services:
web:
image: nginx:alpine
restart: unless-stopped
ports:
- "80:80"
Appliquez avec :
docker compose up -d
Compose recréera les conteneurs qui nécessitent la nouvelle politique. Pour forcer la recréation :
docker compose up -d --force-recreate
Tester la politique localement
Ne déployez pas une politique non testée. Simulez un plantage et observez le comportement.
Pour on-failure, créez un conteneur qui sort avec une erreur après quelques secondes :
docker run -d --name test-fail --restart on-failure:2 alpine sh -c "sleep 5; exit 1"
Surveillez le statut avec :
docker ps -a --filter name=test-fail
Après environ 15 secondes, vous devriez voir :
CONTAINER ID STATUS NAMES
abc123 Exited (1) 2 minutes ago test-fail
Le conteneur a tenté de redémarrer deux fois (à cause de :2) puis s'est arrêté définitivement. Vérifiez les journaux pour confirmer :
docker logs test-fail
Pour always, créez un conteneur qui sort immédiatement :
docker run -d --name test-always --restart always alpine sh -c "exit 0"
En quelques secondes, docker ps -a le montrera dans une boucle de redémarrage :
CONTAINER ID STATUS NAMES
abc456 Restarting (0) 1 second ago test-always
Arrêtez-le manuellement :
docker stop test-always
Vérifiez ensuite : il ne doit pas être redémarré car le démon le considère comme arrêté manuellement. Mais si vous redémarrez le démon Docker, always le redémarrera, tandis que unless-stopped ne le fera pas (car il a été arrêté manuellement avant le redémarrage du démon).
Testez unless-stopped en arrêtant un conteneur, en redémarrant le démon Docker et en confirmant que le conteneur reste arrêté.
Ces tests vous donnent confiance dans le comportement de la politique avant la production.
Vérification et diagnostic
Après avoir défini une politique, vous devez vérifier qu'elle fonctionne comme prévu. Cette section donne un moyen systématique d'observer, diagnostiquer et confirmer le comportement de redémarrage.
Observer l'état actuel du redémarrage
Utilisez docker ps pour voir si un conteneur est en cours de redémarrage :
docker ps --filter "status=restarting"
Vérifiez aussi le nombre de redémarrages d'un conteneur :
docker inspect <nom-du-conteneur> --format '{{.RestartCount}}'
Par exemple, si un conteneur a redémarré 12 fois en une heure, quelque chose ne va pas. Comparez avec les journaux :
docker logs --tail 50 <nom-du-conteneur>
Diagnostiquer les boucles de plantage
Un conteneur dans une boucle de redémarrage (par exemple, Restarting (1) 5 seconds ago) indique que la politique fait son travail mais que l'application échoue de manière répétée. Pour interrompre temporairement la boucle et enquêter :
- Arrêtez le conteneur (cela outrepasse
alwaysetunless-stoppedjusqu'au redémarrage du démon) :
docker stop <nom-du-conteneur>
- Inspectez le système de fichiers du conteneur ou exécutez une commande ponctuelle pour déboguer. Par exemple, lancez un shell interactif dans la même image :
docker run -it --rm --entrypoint sh <image>
- Vérifiez les journaux du conteneur arrêté sans le redémarrer :
docker logs <nom-du-conteneur>
- Une fois corrigé, redémarrez le conteneur :
docker start <nom-du-conteneur>
Vérifier la persistance de la politique lors des redémarrages du démon
Les politiques de redémarrage interagissent avec le démon Docker. Après un redémarrage du démon, les conteneurs avec always sont démarrés quel que soit leur état avant l'arrêt du démon. Les conteneurs avec unless-stopped ne sont démarrés que s'ils étaient en cours d'exécution avant l'arrêt du démon.
Pour tester cela de manière contrôlée :
- Créez deux conteneurs : l'un avec
always, l'autre avecunless-stopped. - Arrêtez manuellement les deux.
- Redémarrez le démon Docker (
sudo systemctl restart dockersur Linux). - Vérifiez
docker ps -a:
- Le conteneur
alwayssera en cours d'exécution. - Le conteneur
unless-stoppedrestera arrêté.
Sortie attendue après le redémarrage du démon :
CONTAINER ID STATUS NAMES
def789 Up 10 seconds test-always
ghi012 Exited (0) test-unless-stopped
C'est une distinction opérationnelle importante.
Surveiller les événements de redémarrage
Pour la production, vous devez surveiller le nombre de redémarrages et les événements. Docker émet des événements que vous pouvez observer :
docker events --filter container=<nom-du-conteneur> --filter event=die
Cela diffuse des événements comme :
2023-09-01T10:00:00.123456789Z container die abc123 (exitCode=1, image=nginx:alpine, name=web)
Vous pouvez également utiliser docker inspect --format dans un script cron ou de surveillance pour alerter lorsque le nombre de redémarrages augmente rapidement.
Modes de défaillance et récupération
Même avec des politiques correctes, des défaillances surviennent. Cette section couvre les modes de défaillance courants avec les politiques de redémarrage et comment récupérer.
Boucle de plantage due à un bug applicatif. La politique redémarre le conteneur, mais il continue de planter. Cela n'est pas résolu par la politique seule ; vous devez corriger l'application. Récupération : arrêtez le conteneur pour interrompre la boucle, déboguez avec les journaux et un shell, corrigez le code ou la configuration, et redéployez. Utilisez on-failure avec une limite de tentatives pour éviter des boucles sans fin qui consomment du CPU et masquent les problèmes.
Perte de données causée par la recréation du conteneur. Si vous recréez un conteneur pour modifier sa politique de redémarrage sans volumes appropriés, vous pouvez perdre des données écrites à l'intérieur du conteneur. Récupération : mettez en place un volume ou un montage bind avant la recréation, et testez la persistance des données comme décrit précédemment. Si les données sont déjà perdues, restaurez à partir d'une sauvegarde si disponible.
Politique de redémarrage trop agressive. Une politique always sur un conteneur qui sort immédiatement peut provoquer une boucle de redémarrage serrée, remplissant les journaux et consommant des ressources. Récupération : arrêtez le conteneur, modifiez la commande pour le maintenir en cours d'exécution ou corrigez la raison de la sortie, puis redémarrez. Envisagez on-failure avec une limite de tentatives.
Politique de redémarrage non appliquée comme prévu. Vous pensez avoir modifié la politique, mais le conteneur affiche toujours l'ancienne. Cela arrive souvent parce que vous avez utilisé docker update (qui ne prend pas en charge la politique de redémarrage) ou modifié un fichier compose sans recréer le conteneur. Récupération : vérifiez la politique réelle avec docker inspect, puis recréez le conteneur avec la bonne politique.
Redémarrage du démon provoquant des démarrages de conteneurs inattendus. Si vous avez des conteneurs avec always, un redémarrage planifié du démon les démarrera même s'ils ont été intentionnellement arrêtés. Cela peut surprendre les opérateurs. Récupération : utilisez unless-stopped pour les conteneurs qui doivent respecter les arrêts manuels.
La politique de redémarrage interfère avec l'orchestration. Dans Docker Swarm ou Kubernetes, la politique de redémarrage des conteneurs est gérée par l'orchestrateur ; définir restart dans la spécification du conteneur peut entrer en conflit. Récupération : utilisez le mécanisme de redémarrage de l'orchestrateur (par exemple, restart_policy de Swarm sous la spécification de service, restartPolicy de pod Kubernetes). Ne définissez pas de politiques au niveau des conteneurs pour les charges de travail orchestrées.
Chaque mode de défaillance doit être documenté dans votre runbook avec des symptômes spécifiques et des étapes de récupération.
Liste de contrôle opérationnelle
Voici une liste de contrôle axée sur la production pour gérer les politiques de redémarrage Docker. Chaque élément inclut le rôle responsable et la fréquence de révision.
1. Inventaire et audit (Propriétaire : ingénieur plateforme, révisé trimestriellement)
- [ ] Lister tous les conteneurs en cours d'exécution et leurs politiques de redémarrage :
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.HostConfig.RestartPolicy.Name}}"
Remarque : {{.HostConfig.RestartPolicy.Name}} peut ne pas être directement disponible dans docker ps ; utilisez docker inspect dans une boucle :
for c in $(docker ps -q); do echo -n "$c "; docker inspect $c --format '{{.Name}} {{.HostConfig.RestartPolicy.Name}}'; done
- [ ] Vérifier que chaque service critique a une politique appropriée (par exemple,
unless-stoppedpour les services à longue durée de vie,on-failure:5pour les services sujets aux plantages mais récupérables). - [ ] Vérifier les compteurs de redémarrage pour des valeurs anormales :
docker inspect <conteneur> --format '{{.RestartCount}}'
Si le compteur est supérieur à 10 en 24 heures, enquêter.
2. Sélection de la politique (Propriétaire : propriétaire de l'application, révisé à chaque déploiement)
- [ ] Pour chaque service, décider entre
no,on-failure,always,unless-stoppeden fonction du cycle de vie attendu. - [ ] Documenter la justification dans le runbook du service.
- [ ] Pour
on-failure, définir une limite de tentatives raisonnable pour éviter les boucles sans fin.
3. Implémentation (Propriétaire : ingénieur DevOps, exécuté à chaque changement)
- [ ] Pour la CLI Docker, recréer le conteneur avec
--restart <politique>. - [ ] Pour Compose, ajouter
restart:à la définition du service et exécuterdocker compose up -d. - [ ] Utiliser
docker inspectpour confirmer que la politique est appliquée.
4. Tests (Propriétaire : responsable QA/release, exécuté à chaque release)
- [ ] Effectuer un test de redémarrage local : créer un conteneur avec la politique, simuler une défaillance ou un arrêt manuel, observer le comportement.
- [ ] Tester l'interaction avec le redémarrage du démon pour
alwaysetunless-stopped. - [ ] Vérifier la persistance des données lors de la recréation du conteneur.
5. Surveillance (Propriétaire : SRE/astreinte, continu)
- [ ] Mettre en place des alertes pour une augmentation rapide du nombre de redémarrages (par exemple, via le flux
docker eventsou un outil de surveillance). - [ ] Journaliser tous les événements de redémarrage pour l'analyse post-incident.
- [ ] Inclure les vérifications de politique de redémarrage dans les contrôles de santé réguliers.
6. Runbook de récupération (Propriétaire : commandant d'incident, révisé mensuellement)
- [ ] Documenter les étapes pour arrêter une boucle de plantage.
- [ ] Documenter les étapes pour récupérer d'une perte de données accidentelle.
- [ ] Documenter comment modifier une politique sur un service en cours d'exécution sans provoquer d'indisponibilité.
Cette liste de contrôle doit être intégrée à vos flux de travail opérationnels existants.
Pièges courants et comment les éviter
Même les utilisateurs Docker expérimentés commettent des erreurs avec les politiques de redémarrage. Voici les plus courantes et comment les éviter.
Piège 1 : Utiliser always pour des tâches de courte durée. Une tâche batch qui se termine avec succès sera redémarrée indéfiniment, consommant des ressources. Utilisez no ou on-failure pour de tels conteneurs. Si vous avez besoin d'une tâche périodique, utilisez un planificateur externe (par exemple, cron sur l'hôte) pour exécuter un nouveau conteneur à chaque fois.
Piège 2 : Oublier que always outrepasse les arrêts manuels lors du redémarrage du démon. Vous arrêtez un conteneur pour maintenance, puis redémarrez Docker, et il revient. Utilisez unless-stopped si vous voulez que les arrêts manuels persistent lors des redémarrages du démon.
Piège 3 : Ne pas définir de limite de tentatives pour on-failure. Sans limite, un conteneur peut redémarrer éternellement, masquant la cause racine. Définissez on-failure:5 ou similaire pour abandonner après quelques tentatives, forçant une enquête.
Piège 4 : Essayer de modifier la politique de redémarrage avec docker update. docker update peut modifier les limites de ressources mais pas la politique de redémarrage. Vous devez recréer le conteneur. Vérifiez toujours avec docker inspect.
Piège 5 : Ignorer les pics du compteur de redémarrages. Un compteur de redémarrages élevé est un symptôme d'un service instable. Surveillez-le et alertez en cas d'augmentation anormale.
Piège 6 : Appliquer des politiques de redémarrage au niveau des conteneurs dans des environnements orchestrés. Dans Docker Swarm ou Kubernetes, l'orchestrateur gère les redémarrages. Définir des politiques au niveau des conteneurs peut entrer en conflit. Utilisez les spécifications de redémarrage de l'orchestrateur.
Piège 7 : Ne pas tester la persistance des données avant de modifier la politique de redémarrage. Si vous recréez un conteneur pour modifier la politique et n'avez pas configuré de volumes, vous pouvez perdre des données. Testez toujours avec des volumes.
En étant conscient de ces pièges, vous pouvez éviter la plupart des problèmes liés aux politiques de redémarrage.
Conclusion
Les politiques de redémarrage Docker sont une partie petite mais critique des opérations de conteneurs en production. Une politique bien configurée garantit que vos services récupèrent automatiquement des plantages sans masquer des problèmes plus profonds. Cet article a fourni une liste de contrôle pratique et des exemples pour définir, vérifier et dépanner les politiques de redémarrage.
Rappelez-vous les principes de sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des variables fictives plutôt que des secrets, vérifier le résultat et documenter les étapes de récupération. Appliquez la liste de contrôle à votre environnement, adaptez-la à vos services et révisez-la régulièrement.
Comme prochaine étape, choisissez un conteneur dans votre environnement de production, vérifiez sa politique de redémarrage par rapport aux directives de cet article et exécutez un test local pour confirmer le comportement attendu. Ensuite, étendez l'audit à tous les services critiques.
Avec ces pratiques, vous serez mieux préparé pour ces plantages de 3 h du matin.