Docker « OCI runtime create failed » : déchiffrez et corrigez la cause réelle

Cet article vous a aidé ?

Vous tapez docker run. Docker réfléchit une demi-seconde. Puis il renvoie :
OCI runtime create failed et un mur de texte vaguement accusateur. Rien ne démarre. Votre pager sonne.
La cause racine n’est généralement pas « OCI ». C’est presque toujours une défaillance très spécifique liée au noyau, au système de fichiers, à la sécurité ou à la configuration
que Docker se contente de rapporter—mal.

Ceci est un guide de terrain pour la production : comment lire l’erreur comme une trace de pile, localiser la couche en échec et corriger le
vrai problème sans redémarrages rituels. Nous irons de « que fait réellement OCI ici ? » à des commandes concrètes,
sorties attendues et décisions à prendre.

Déchiffrer l’erreur : ce que « OCI runtime create failed » signifie vraiment

Le titre est trompeur. « OCI runtime create failed » n’est pas une erreur unique. C’est une catégorie. Docker vous dit :
« J’ai demandé à l’exécuteur OCI de créer un conteneur, et quelque chose a explosé pendant la phase d’initialisation du runtime. »

Cette « phase d’initialisation » inclut :

  • la création des namespaces (pid, mount, network, user)
  • la configuration des cgroups
  • la préparation du système de fichiers racine (montages overlay, bind mounts, tmpfs)
  • l’application des politiques de sécurité (seccomp, AppArmor/SELinux)
  • la mise en place du processus init et l’exec de votre point d’entrée

Quand l’une de ces étapes échoue, Docker affiche souvent un message qui commence par :
docker: Error response from daemon: OCI runtime create failed: ...
puis une chaîne imbriquée comme container_linux.go, process_linux.go,
failed to create shim task, permission denied, invalid argument, ou no space left on device.

Votre travail est d’ignorer le préfixe générique et de vous concentrer sur la dernière plainte spécifique, proche d’un syscall.
Cette dernière partie est généralement la vérité.

Une règle sèche : traitez cette erreur comme une erreur du noyau déguisée en message Docker. Corrigez le problème côté noyau, pas le déguisement.

Blague n°1 (courte, pertinente) : les erreurs OCI sont comme le témoin « check engine »—précises pour dire qu’il y a un souci, inutiles pour indiquer quel cylindre brûle.

Faits et historique : pourquoi cette erreur existe

Un peu de contexte aide, car les erreurs OCI sont façonnées par l’évolution des conteneurs : couches de standards, runtimes et daemons
qui communiquent entre eux via des API. Voici quelques faits concrets qui expliquent les bizarreries.

  1. Les conteneurs Linux précèdent Docker. Les cgroups sont apparus autour de 2007–2008 ; les namespaces ont mûri durant les années 2000. Docker a popularisé l’empaquetage.
  2. Docker utilisait LXC au départ. Les premières versions de Docker utilisaient LXC ; plus tard il est passé à libcontainer (Go) puis s’est standardisé sur runc.
  3. OCI (Open Container Initiative) a été créé en 2015. Le but : normaliser le format d’image et le runtime pour que « conteneur » soit portable.
  4. runc est issu de libcontainer de Docker. runc est le runtime de référence OCI ; plusieurs runtimes implémentent la même spécification.
  5. containerd a été extrait pour réduire le couplage. Docker délègue plus à containerd ; vous verrez des erreurs mentionnant “shim” parce que containerd utilise des shims pour gérer les processus de conteneurs.
  6. La phase « create » d’OCI n’est pas « démarrer votre app ». « Create » signifie préparer l’état et l’environnement du conteneur ; l’exec de l’application arrive tard et peut échouer pour des raisons totalement différentes.
  7. cgroup v2 a changé des comportements et des hypothèses. Certaines distributions ont changé la hiérarchie par défaut ; des configurations Docker ont cassé jusqu’à être alignées avec les cgroups systemd et les pilotes compatibles.
  8. Les modules de sécurité ont évolué. Les politiques SELinux et AppArmor peuvent transformer un conteneur précédemment fonctionnel en une panne soudaine « permission denied ».
  9. OverlayFS a des exigences liées au noyau. Certains modes d’overlay (comme metacopy, redirect_dir, montages idmapped) dépendent de versions du noyau et peuvent échouer de façon étrange quand on les active.

Plan de diagnostic rapide (faire dans cet ordre)

Quand la production brûle, il vous faut un algorithme du plus court chemin, pas un cours de philosophie. Voici l’ordre qui permet
généralement de trouver rapidement le goulot d’étranglement.

1) Capturer la chaîne d’erreur complète

  • Relancez la commande avec le maximum de contexte du démon (logs + events).
  • Extrayez l’échec final : permission denied, no space left on device, invalid argument, exec format error, operation not permitted.

2) Vérifier les « mensonges évidents » au niveau hôte : disque, inodes, mémoire, logs du noyau

  • Disque/inodes sur la racine Docker (/var/lib/docker ou chemin personnalisé).
  • dmesg/journal pour des refus AppArmor/SELinux ou des échecs de montage.
  • Mémoire/pression cgroup si la chaîne d’erreur suggère des échecs fork/exec.

3) Identifier le sous-système en échec selon l’erreur finale

  • Mount/rootfs : erreurs overlay2, « unknown filesystem », « invalid argument », « permission denied ».
  • Sécurité : AVC/denied AppArmor/SELinux ; seccomp « operation not permitted ».
  • cgroups : erreurs mentionnant des chemins cgroup, des contrôleurs ou systemd.
  • Entrypoint : « exec format error », « no such file or directory » (souvent interpréteur manquant), « text file busy ».

4) Reproduire avec le conteneur le plus petit possible

  • Essayez une image connue bonne et une commande triviale (comme busybox true).
  • Si même cela échoue, c’est l’hôte/runtime. Si une seule image échoue, c’est la config image, l’entrypoint ou les montages.

5) Corriger une chose, puis retester

Ne lancez pas une séquence « redémarrer Docker, rebooter le nœud, désactiver la sécurité ». Faites un changement, validez, puis continuez.
Vous déboguez, vous n’exécutez pas un rituel.

Cartographier la défaillance par couche : Docker → containerd → runc → noyau

Si vous voulez être rapide, pensez en couches et allez chercher le bon journal.

  • Docker CLI affiche l’erreur résumée. Utile pour la chaîne finale, pas pour les détails.
  • dockerd logs montrent ce que Docker a demandé à containerd et ce qui est revenu.
  • containerd logs montrent les appels du shim et du runtime. « failed to create shim task » apparaît généralement ici.
  • runc exécute les appels système vers le noyau. Ses erreurs sont celles qui comptent le plus.
  • noyau logs (dmesg/journal) contiennent souvent le refus réel ou le rejet de montage, surtout pour les LSM.

« OCI runtime create failed » signifie généralement que runc a retourné un code non nul pendant create.
L’étape create inclut le montage de votre rootfs et des bind mounts. Donc stockage et sécurité dominent les causes.

Citation (idée paraphrasée) : L’idée paraphrasée de Werner Vogels : tout échoue, tout le temps—votre travail est de construire des systèmes qui s’y attendent et les gèrent.

Tâches pratiques : 12+ commandes avec sorties et décisions

Ci-dessous des tâches pratiques à exécuter sur un hôte Linux avec Docker Engine. Chacune inclut :
la commande, ce qu’une sortie typique signifie, et la décision à prendre. Exécutez-les dans l’ordre qui correspond à vos symptômes,
pas forcément du haut vers le bas.

Task 1: Re-run the failing container with maximum clarity

cr0x@server:~$ docker run --rm --name oci-test alpine:3.20 true
docker: Error response from daemon: OCI runtime create failed: runc create failed: unable to start container process: error during container init: open /proc/self/fd: permission denied: unknown.

Ce que cela signifie : La dernière clause (open /proc/self/fd: permission denied) est votre indice. Elle pointe vers une politique de sécurité (SELinux/AppArmor/seccomp) ou un comportement durci du montage /proc.

Décision : Allez d’abord aux logs noyau/LSM (Tâches 4–6) avant de toucher au stockage.

Task 2: Verify whether the problem is global or image-specific

cr0x@server:~$ docker run --rm busybox:1.36 true
Unable to find image 'busybox:1.36' locally
1.36: Pulling from library/busybox
Digest: sha256:...
Status: Downloaded newer image for busybox:1.36
docker: Error response from daemon: OCI runtime create failed: runc create failed: unable to start container process: error during container init: open /proc/self/fd: permission denied: unknown.

Ce que cela signifie : Si même BusyBox échoue, votre environnement hôte/runtime est cassé, pas votre image applicative.

Décision : Concentrez-vous sur la config du démon, les fonctionnalités du noyau, la politique LSM, les cgroups et la santé du driver de stockage.

Task 3: Read Docker daemon logs around the failure

cr0x@server:~$ sudo journalctl -u docker --since "10 min ago" --no-pager
Jan 03 09:41:18 server dockerd[1327]: time="2026-01-03T09:41:18.912345678Z" level=error msg="Handler for POST /v1.45/containers/create returned error: OCI runtime create failed: runc create failed: unable to start container process: error during container init: open /proc/self/fd: permission denied: unknown"
Jan 03 09:41:18 server dockerd[1327]: time="2026-01-03T09:41:18.913456789Z" level=info msg="Attempting next endpoint for containerd"

Ce que cela signifie : dockerd répète l’erreur du runtime, mais confirme la timeline et que ce n’est pas un bug côté client.

Décision : Si les logs dockerd montrent « permission denied », « invalid argument », « no space », etc., suivez exactement cette phrase en aval.

Task 4: Read containerd logs (where shim/runc errors show up)

cr0x@server:~$ sudo journalctl -u containerd --since "10 min ago" --no-pager
Jan 03 09:41:18 server containerd[1189]: time="2026-01-03T09:41:18.905432198Z" level=error msg="RunPodSandbox for "..." failed" error="failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: open /proc/self/fd: permission denied: unknown"

Ce que cela signifie : « failed to create shim task » est la façon dont containerd dit que le runtime n’a pas pu préparer le conteneur. La dernière clause reste la clé.

Décision : Si vous voyez des erreurs liées aux montages ici, passez aux vérifications du stockage. Si vous voyez des refus/permission, foncez sur les vérifications LSM.

Task 5: Check kernel logs for AppArmor denials

cr0x@server:~$ sudo dmesg -T | tail -n 20
[Fri Jan  3 09:41:18 2026] audit: type=1400 audit(1735897278.912:312): apparmor="DENIED" operation="open" profile="docker-default" name="/proc/self/fd/" pid=24310 comm="runc:[2:INIT]" requested_mask="r" denied_mask="r" fsuid=0 ouid=0

Ce que cela signifie : C’est un indice probant. AppArmor a bloqué le processus init de runc qui essayait de lire /proc/self/fd.

Décision : Corrigez le profil AppArmor ou lancez les conteneurs avec un override de profil adapté (voir Erreurs courantes et checklist). Ne désactivez pas AppArmor globalement sauf si vous aimez vivre dangereusement.

Task 6: Check SELinux denials (RHEL/Fedora/CentOS derivatives)

cr0x@server:~$ sudo ausearch -m avc -ts recent | tail -n 5
type=AVC msg=audit(1735897278.912:312): avc:  denied  { mounton } for  pid=24310 comm="runc:[2:INIT]" path="/var/lib/docker/overlay2/..." scontext=system_u:system_r:container_runtime_t:s0 tcontext=system_u:object_r:default_t:s0 tclass=dir permissive=0

Ce que cela signifie : SELinux a bloqué une opération de montage. Le tcontext égal à default_t est suspect ; les étiquettes sont incorrectes ou le chemin de stockage n’est pas labellisé pour les conteneurs.

Décision : Restaurer les contextes corrects sur les chemins de stockage Docker, ou ajuster la politique proprement. Évitez de mettre SELinux en permissive comme « correctif » ; c’est au mieux un pas de diagnostic.

Task 7: Check Docker’s storage driver and root directory

cr0x@server:~$ docker info --format 'Driver={{.Driver}} RootDir={{.DockerRootDir}} CgroupDriver={{.CgroupDriver}}'
Driver=overlay2 RootDir=/var/lib/docker CgroupDriver=systemd

Ce que cela signifie : Vous savez maintenant où sont les données et quel driver est utilisé. Overlay2 est normal ; cela signifie aussi que les montages et le support kernel overlay comptent.

Décision : Si RootDir est sur un système de fichiers étrange (NFS, eCryptfs, ancien XFS sans ftype), attendez-vous à des problèmes. Validez le système de fichiers supportant la couche suivante.

Task 8: Check disk space and inodes on Docker RootDir filesystem

cr0x@server:~$ df -h /var/lib/docker
Filesystem      Size  Used Avail Use% Mounted on
/dev/nvme0n1p3  200G  198G  2.0G  99% /
cr0x@server:~$ df -i /var/lib/docker
Filesystem       Inodes   IUsed    IFree IUse% Mounted on
/dev/nvme0n1p3  13107200 13090000  17200   100% /

Ce que cela signifie : « No space left on device » peut venir des blocs disque ou des inodes. Overlay2 consomme beaucoup d’inodes.

Décision : Si l’un ou l’autre est presque plein, arrêtez de déboguer des trucs sophistiqués. Libérez de l’espace (Tâche 9) ou étendez le stockage. Les conteneurs ne peuvent pas monter les couches si le système de fichiers ne peut pas créer de métadonnées.

Task 9: Reclaim Docker space safely (and understand what you’re deleting)

cr0x@server:~$ docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          54        12        38.6GB    22.4GB (58%)
Containers      17        2         1.1GB     1.0GB (91%)
Local Volumes   31        10        96.2GB    40.5GB (42%)
Build Cache     0         0         0B        0B
cr0x@server:~$ docker system prune -f
Deleted Containers:
...
Deleted Images:
...
Total reclaimed space: 12.3GB

Ce que cela signifie : docker system df montre où se situe l’espace. Prune supprime les conteneurs arrêtés, images pendantes et réseaux non utilisés. Les volumes ne sont supprimés qu’avec --volumes.

Décision : En production, prune est acceptable si vous comprenez votre stratégie de cache d’images et que vous ne comptez pas sur des conteneurs arrêtés comme preuve. Pour des nœuds qui se reconstruisent souvent, planifiez des prune proactifs avec garde-fous.

Task 10: Validate the backing filesystem for overlay2 (XFS ftype)

cr0x@server:~$ findmnt -no FSTYPE,OPTIONS /var/lib/docker
xfs rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota
cr0x@server:~$ sudo xfs_info /dev/nvme0n1p3 | grep ftype
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1

Ce que cela signifie : Overlay2 sur XFS nécessite ftype=1. Si c’est ftype=0, vous aurez des comportements overlay étranges et des échecs de démarrage de conteneurs.

Décision : Si ftype=0, la bonne correction est de migrer Docker RootDir vers un système de fichiers correctement formaté. Il n’y a pas de bascule sûre en place.

Task 11: Check mount propagation / shared mounts (common in Kubernetes hosts too)

cr0x@server:~$ findmnt -o TARGET,PROPAGATION /var/lib/docker
TARGET          PROPAGATION
/var/lib/docker shared

Ce que cela signifie : Certains workloads conteneurisés exigent la propagation de montage partagée ; d’autres échouent si la topologie de montages hôte est inhabituelle. Si c’est private dans un environnement qui attend shared, vous pouvez rencontrer des échecs OCI liés aux montages.

Décision : Si vous suspectez un problème de propagation, comparez avec un nœud connu bon et alignez les unités systemd de montage. Évitez un mount --make-rshared / aléatoire en production sans comprendre l’étendue des risques.

Task 12: Inspect seccomp status and test with an unconfined profile (diagnostic only)

cr0x@server:~$ docker info --format 'SecurityOptions={{json .SecurityOptions}}'
SecurityOptions=["name=seccomp,profile=default","name=apparmor"]
cr0x@server:~$ docker run --rm --security-opt seccomp=unconfined alpine:3.20 true
docker: Error response from daemon: OCI runtime create failed: runc create failed: unable to start container process: error during container init: open /proc/self/fd: permission denied: unknown.

Ce que cela signifie : Seccomp unconfined n’a rien changé. Cela suggère que seccomp n’est pas la cause (dans cet exemple) ; AppArmor est probablement en cause.

Décision : Utilisez les basculements unconfined comme expériences contrôlées. Si unconfined « corrige » le problème, élaborez un profil adapté plutôt que de laisser tout grand ouvert.

Task 13: Validate cgroup mode and hierarchy (common with cgroup v2)

cr0x@server:~$ stat -fc %T /sys/fs/cgroup
cgroup2fs
cr0x@server:~$ docker info --format 'CgroupVersion={{.CgroupVersion}} CgroupDriver={{.CgroupDriver}}'
CgroupVersion=2 CgroupDriver=systemd

Ce que cela signifie : Vous êtes sur cgroup v2 et Docker utilise le driver systemd (généralement correct pour les distributions modernes). Si vous voyez un mismatch (cgroup v2 avec driver cgroupfs dans certains environnements), vous pouvez avoir des échecs de create.

Décision : Alignez le driver cgroup de Docker avec systemd sur les hôtes systemd. Si vous êtes dans un coin legacy, testez sur un nœud connu bon avant de changer toute la flotte.

Task 14: Confirm the entrypoint binary is executable and matches architecture

cr0x@server:~$ docker run --rm --entrypoint /bin/sh alpine:3.20 -c 'uname -m; file /bin/busybox'
x86_64
/bin/busybox: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-x86_64.so.1, stripped

Ce que cela signifie : Si votre image défaillante contient un binaire ARM sur un hôte x86_64, vous verrez exec format error lors du create/start. Cette vérification prouve ce que « normal » devrait être.

Décision : En cas d’incompatibilité d’architecture, corrigez la construction de l’image ou utilisez des manifests multi-arch correctement. N’« ajustez » pas en installant qemu sur des nœuds prod à moins d’en comprendre les implications de performance.

Task 15: Validate bind mounts exist and have correct permissions

cr0x@server:~$ docker run --rm -v /does-not-exist:/data alpine:3.20 true
docker: Error response from daemon: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error mounting "/does-not-exist" to rootfs at "/data": mount /does-not-exist:/data, flags: 0x5000: no such file or directory: unknown.

Ce que cela signifie : Un chemin hôte manquant provoque un échec OCI create parce que la configuration des montages a lieu avant le démarrage du processus.

Décision : Créez le chemin hôte avec la bonne propriété, ou utilisez des volumes gérés par Docker au lieu de chemins hôtes fragiles.

Task 16: Spot overlay2 mount errors explicitly

cr0x@server:~$ sudo grep -R "overlay" -n /var/log/syslog | tail -n 5
Jan 03 09:41:18 server kernel: [Fri Jan  3 09:41:18 2026] overlayfs: upper fs does not support tmpfile.
Jan 03 09:41:18 server kernel: [Fri Jan  3 09:41:18 2026] overlayfs: failed to mount overlay: invalid argument

Ce que cela signifie : Le système de fichiers support n’a pas les fonctionnalités attendues par overlay. Cela peut venir de systèmes exotiques, d’options de montage particulières ou d’un noyau ancien.

Décision : Déplacez Docker RootDir vers un FS local supporté (ext4 ou XFS correctement configuré), ou mettez à jour le noyau/la configuration de stockage pour satisfaire les exigences d’overlay.

Blague n°2 (courte, pertinente) : désactiver SELinux pour « réparer Docker » revient à enlever votre détecteur de fumée parce qu’il est bruyant.

Trois mini-récits d’entreprise depuis le terrain

Mini-récit 1 : L’incident causé par une mauvaise hypothèse

Une entreprise de taille moyenne faisait tourner Docker sur une flotte de VMs généralistes. Une équipe possédait « l’image de base », une autre l’« infrastructure ».
L’équipe plateforme a déployé un durcissement : nouveaux profils AppArmor et une mise à jour du noyau. L’hypothèse était simple et fausse :
« Les conteneurs sont isolés ; un profil hôte plus strict ne les affectera pas. »

Lundi matin, un sous-ensemble de services a cessé de se déployer. Le symptôme était identique partout :
OCI runtime create failed avec open /proc/self/fd: permission denied.
Les équipes ont initialement accusé l’image parce que la panne apparaissait au démarrage du conteneur. Quelques ingénieurs ont passé des heures à reconstruire des images
et à rouler des tags, parce que bien sûr c’était forcément « l’app ».

La percée est venue de quelqu’un qui a lu dmesg au lieu de Slack.
Les logs d’audit noyau montraient des refus AppArmor contre docker-default.
La mise à jour de la politique avait restreint l’accès à des chemins /proc d’une manière que le processus init de runc n’aimait pas.
Docker n’était pas cassé. La posture de sécurité de l’hôte l’était, par rapport à leur runtime.

Le correctif a été chirurgical : ajuster le profil AppArmor utilisé par ces workloads, et le déployer sur la flotte avec un canari.
Ils ont aussi rédigé une fiche : « Si l’erreur se termine par permission denied, vérifiez d’abord les logs LSM. »
Le temps total d’incident aurait pu être 20 minutes. Il a été plus proche d’une demi-journée à cause de la mauvaise hypothèse initiale.

Mini-récit 2 : L’optimisation qui s’est retournée contre eux

Une autre organisation a voulu optimiser la vitesse de build et déploiement sur des runners CI. Ils ont configuré Docker RootDir sur un système de fichiers en réseau
car c’était « un stockage rapide » et facilitait le nettoyage. Aussi, cela évitait des upgrades disque locaux. Qui n’aime pas un projet qui
semble économiser de l’argent en déplaçant la complexité ailleurs.

Ça a marché un temps. Puis des jobs ont commencé à échouer aléatoirement avec OCI runtime create failed,
souvent formulé comme des échecs de montage ou « invalid argument ». C’était intermittent. C’était le pire.
Les pannes intermittentes consument silencieusement le temps d’ingénierie.

Le vrai problème : overlay2 sur un système de fichiers non local est un champ de mines de compatibilité. Même si ça « marche », vous pouvez rencontrer des cas limites :
sémantiques de verrouillage de fichiers, support de d_type, support tmpfile, pics de latence lors des opérations de montage, et courses sensibles au timing
quand des milliers de couches tournent quotidiennement.

Le rollback fut peu glorieux : remettre Docker RootDir sur un SSD local, appliquer des quotas de pruning, et accepter que le cache de build soit une
fonctionnalité de performance—not une stratégie de rétention. Les échecs de create ont cessé immédiatement. Le design « optimisé »
optimisait la mauvaise chose : la commodité du stockage, pas la correction du runtime.

Mini-récit 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise

Une grande entreprise gérait une flotte mixte : différentes versions du noyau, différentes distros, différents régimes de conformité.
Pour éviter les incidents, elle a fait quelque chose de profondément peu à la mode : standardiser le baseline des hôtes conteneurs.
Même type et options de système de fichiers pour Docker RootDir, même driver cgroup, même configuration du module de sécurité,
et un ensemble restreint de versions du noyau testées.

Un jour un nouveau service a commencé à échouer sur un seul cluster avec OCI runtime create failed et invalid argument.
L’ingénieur on-call a comparé le nœud au baseline connu bon avec une petite checklist :
docker info, type de FS, version du noyau, et un scan rapide des logs noyau.

L’élément fautif est apparu rapidement : un petit sous-ensemble de nœuds avait été provisionné avec un volume XFS ancien où ftype=0
à cause d’un script d’image obsolète. Ça ne cassait pas tout immédiatement ; ça cassait juste assez pour être ennuyeux, et seulement sous certains motifs de couches.

Parce qu’ils avaient un baseline, la correction n’a pas été discutée. Ils ont drainé ces nœuds, reconstruit avec les bons paramètres FS,
et rendu la capacité. Pas d’héroïsme, pas de « désactiver la sécurité », pas de flags expérimentaux nocturnes. L’ennuyeux a gagné, encore.

Erreurs courantes : symptômes → cause racine → correctif

Les échecs de create OCI semblent répétitifs, mais les causes racines ne le sont pas. Voici les patrons qui reviennent le plus souvent en production,
cartographiés comme vous les déboguez réellement.

1) « permission denied » lors de l’initialisation du conteneur

Symptôme : L’erreur se termine par permission denied, souvent en mentionnant /proc, des montages, ou des fichiers sous /var/lib/docker.

Cause racine : Refus AppArmor/SELinux, mauvais labels sur les répertoires Docker, ou options de montage trop restrictives.

Correctif : Consultez dmesg et les logs d’audit. Restaurez les contexts SELinux sur Docker RootDir ; ajustez le profil AppArmor. Utilisez --security-opt uniquement pour diagnostiquer, puis implémentez une politique correcte.

2) « no space left on device » alors que vous avez des Go libres

Symptôme : OCI create échoue avec ENOSPC alors que df -h montre de l’espace libre.

Cause racine : Inodes épuisés (df -i) ou Docker RootDir situé sur un filesystem plus petit que prévu (bind-monté ailleurs).

Correctif : Vérifiez df -i et la RootDir via docker info. Purgez les couches inutiles ; étendez le FS ; envisagez de déplacer RootDir sur un volume dédié.

3) « invalid argument » autour des montages overlay

Symptôme : failed to mount overlay: invalid argument ou similaire dans les logs noyau.

Cause racine : Système de fichiers support non compatible (NFS, XFS ancien sans ftype, options de montage incompatibles) ou mismatch features noyau/overlay.

Correctif : Placez Docker RootDir sur un FS local supporté ; vérifiez XFS ftype=1 ; mettez à jour le noyau si nécessaire ; arrêtez d’exécuter overlay2 sur des stockages « créatifs ».

4) « exec format error » ou « no such file or directory » au démarrage

Symptôme : Le conteneur échoue immédiatement ; la chaîne d’erreur se termine par des échecs d’exec.

Cause racine : Binaire d’architecture incorrecte ; interpréteur manquant (ex. script avec #!/bin/bash mais pas bash) ; fins de ligne CRLF dans des scripts d’entrypoint peuvent aussi perturber.

Correctif : Vérifiez l’architecture de l’image et l’entrypoint. Assurez-vous que les interpréteurs existent. Construisez des images multi-arch correctement.

5) Échecs de bind mount

Symptôme : L’erreur mentionne « error mounting » chemin hôte, « no such file », ou « not a directory ».

Cause racine : Chemin hôte manquant, mauvais type (fichier vs répertoire), ou permissions/labels empêchant le montage.

Correctif : Créez le chemin, corrigez permissions et contexts SELinux, ou basculez vers des volumes nommés.

6) Erreurs cgroup (surtout après des mises à jour OS)

Symptôme : OCI create échoue en mentionnant cgroups, contrôleurs, ou systemd.

Cause racine : Problèmes de transition cgroup v2, driver cgroup Docker non aligné, ou contrôleurs verrouillés.

Correctif : Alignez le driver cgroup sur systemd sur les hôtes systemd ; assurez-vous que les contrôleurs requis sont activés ; validez avec docker info et stat -fc %T /sys/fs/cgroup.

Listes de contrôle / plan pas-à-pas

Checklist incident : restaurer le service d’abord, puis réparer correctement

  1. Obtenir la chaîne finale exacte de l’erreur.
    Relancez un conteneur minimal et capturez la sortie.
    Décidez si cela sent le stockage, la sécurité, les cgroups ou l’entrypoint.
  2. Confirmer que ce n’est pas spécifique à l’image.
    Lancez busybox true.
    Si cela échoue, arrêtez de blâmer l’app.
  3. Vérifier la capacité hôte (blocs + inodes) sur Docker RootDir.
    Si plein, prune ou étendez. Ne compliquez pas la situation.
  4. Vérifier les logs noyau pour refus et erreurs de montage.
    Si vous voyez des refus AppArmor/SELinux, vous avez votre catégorie racine.
  5. Comparer un nœud cassé à un nœud bon.
    Même noyau ? même FS ? même config Docker ? mêmes options de sécurité ?
    Les différences expliquent généralement tout.
  6. Appliquer la plus petite mitigation sûre.
    Exemples : libérer de l’espace, restaurer labels, ajuster un profil, corriger un chemin de montage.
    Évitez de « désactiver tout le module de sécurité » à moins que ce soit un diagnostic court avec plan de rollback.
  7. Retester avec un conteneur minimal, puis la charge réelle.
    Si le minimal fonctionne mais que l’app échoue, vous êtes passé du niveau hôte au niveau application (entrypoint, montages, permissions utilisateur).

Checklist prévention : éviter que le vous futur ne rencontre le vous présent

  1. Placez Docker RootDir sur un FS local supporté. ext4 ou XFS correctement configuré. Évitez le stockage réseau pour les chemins runtime overlay2.
  2. Surveillez à la fois l’usage disque et l’usage d’inodes. Alertez avant 85–90% pour les deux, pas seulement les Go.
  3. Standardisez le driver et la hiérarchie cgroup. Si vous êtes sur systemd, utilisez systemd cgroups sauf raison impérieuse.
  4. Centralisez les logs de refus LSM. Les refus AppArmor et SELinux doivent remonter dans votre pipeline de logs avec des filtres, sinon vous déboguerez à l’aveugle.
  5. Baseliner la config hôte et suivez les diffs. Version noyau, driver de stockage, options de montage, daemon.json. Rendre la dérive visible.
  6. Gardez un test « conteneur minimal » d’urgence dans le runbook. Le test BusyBox/Alpine indique si l’hôte est fondamentalement cassé.
  7. Documentez les exceptions approuvées de security-opt. Si certains workloads nécessitent des réglages unconfined, traitez cela comme une décision de risque, pas un caprice développeur.

FAQ

1) Qu’est-ce que OCI dans les erreurs Docker ?

OCI est la spécification Open Container Initiative. En pratique, Docker utilise un runtime OCI (souvent runc) pour préparer les namespaces,
cgroups, montages, puis exécuter votre processus. L’erreur signifie que la préparation a échoué.

2) Pourquoi l’erreur mentionne runc ou le shim containerd ?

Docker délègue les opérations runtime à containerd, qui utilise un shim pour gérer les processus de conteneurs. runc réalise les opérations bas niveau
de create/start. Les échecs remontent à travers ces couches, d’où l’apparition de leurs noms dans la chaîne.

3) “OCI runtime create failed” se résout-il parfois en redémarrant Docker ?

Occasionnellement—si le démon est bloqué ou containerd est en mauvaise santé. Mais la plupart du temps c’est un vrai problème hôte (espace, montages,
politique, cgroups). Redémarrer peut effacer des symptômes temporairement alors que la cause sous-jacente persiste.

4) Comment savoir si c’est un problème d’image ou d’hôte ?

Lancez un petit conteneur connu bon. Si docker run --rm busybox true échoue, c’est l’hôte/runtime. Si BusyBox fonctionne mais
votre image échoue, c’est probablement l’entrypoint, l’architecture, un interpréteur manquant, des montages, ou des permissions dans l’image.

5) Pourquoi j’obtiens « no such file or directory » alors que le fichier existe ?

Souvent l’entrypoint est un script avec un shebang pointant vers un interpréteur absent dans l’image (ex. /bin/bash).
Une autre cause fréquente est l’incompatibilité d’architecture qui produit des erreurs d’exec confuses.

6) Comment l’épuisement d’inodes provoque-t-il des échecs OCI create ?

Overlay2 crée beaucoup de petits fichiers et répertoires pour les métadonnées de couches. Si les inodes atteignent 100%, le runtime ne peut plus créer
les répertoires requis lors du montage/initialisation, donc le create échoue même s’il reste des Go libres.

7) SELinux/AppArmor peuvent-ils vraiment empêcher les conteneurs de démarrer ?

Oui. Le runtime lui-même (runc) est un processus de l’hôte soumis à la politique de sécurité hôte. Si la politique bloque des montages, accès fichiers
ou certaines opérations, la création du conteneur échoue avant que votre application ne s’exécute.

8) Quelle est la manière la plus sûre de « tester si la sécurité est le problème » ?

Utilisez des diagnostics ciblés : vérifiez d’abord les logs noyau/audit. Si vous devez expérimenter, lancez un conteneur de test unique avec un override
spécifique (comme un profil seccomp non confiné) et revenez-en immédiatement. Ne basculez pas les paramètres globaux comme test casual.

9) cgroup v2 cause-t-il « OCI runtime create failed » ?

Cela peut, surtout avec une configuration Docker non alignée ou des composants runtime anciens. Validez la version de cgroup et le driver via
docker info et assurez-vous que l’hôte active les contrôleurs nécessaires.

10) Si overlay2 est cassé, puis-je changer de driver de stockage sur le même RootDir ?

Considérez cela comme un travail de migration, pas un simple toggle. Changer de driver nécessite généralement de déplacer ou reconstruire l’état Docker. Faites-le délibérément :
drainer les workloads, sauvegarder les volumes importants, et reconstruire les nœuds si possible.

Conclusion : quoi faire la prochaine fois

« OCI runtime create failed » signifie que Docker dit « le noyau a dit non », avec des étapes intermédiaires. Le chemin le plus rapide est :
capturez la clause finale de l’erreur, classez-la (sécurité/stockage/cgroups/entrypoint), et consultez les logs qui peuvent réellement le confirmer.

Étapes suivantes qui rapportent immédiatement :

  • Rédigez un petit runbook : test BusyBox, docker info RootDir/Driver, df -h et df -i, puis dmesg/journalctl.
  • Baselinez vos hôtes conteneurs : type/options FS, XFS ftype, mode cgroup, modules de sécurité. La dérive est le tueur silencieux.
  • Cessez de stocker les couches runtime Docker sur des stockages « intelligents ». Utilisez des disques locaux pour overlay2 ; réservez les systèmes de stockage adaptés aux données persistantes.
  • Quand l’erreur dit « permission denied », croyez-la. Allez directement aux logs AppArmor/SELinux/audit et corrigez la politique ou les labels.
← Précédent
MySQL vs OpenSearch pour la recherche auto-hébergée : utile ou se faire du mal sur un VPS ?
Suivant →
Greylisting des e-mails : quand il aide et quand il ne fait que retarder le courrier réel

Laisser un commentaire