Ви вводите docker run. Docker задумується півсекунди. Потім виводить:
OCI runtime create failed і стіну не дуже інформативного тексту, який ніби звинувачує щось. Нічого не запускається. Система оповіщення спрацьовує.
Корінна причина зазвичай не в «OCI». Майже завжди це дуже конкретна помилка ядра, файлової системи, безпеки або конфігурації,
про яку Docker лише повідомляє—погано.
Це путівник для продакшену: як читати цю помилку як стек-трейс, знайти шар, що падає, і виправити реальну проблему без ритуальних перезапусків.
Ми пройдемо від «що взагалі робить OCI тут?» до конкретних команд, очікуваних результатів і рішень, які варто прийняти.
Розшифровка помилки: що насправді означає «OCI runtime create failed»
Заголовок вводить в оману. «OCI runtime create failed» — це не одинична помилка. Це категорія. Docker каже:
«Я попросив OCI runtime створити контейнер, і щось на етапі налаштування у рантаймі вибухнуло».
Цей «етап налаштування» включає:
- створення неймспейсів (pid, mount, network, user)
- налаштування cgroups
- підготовку кореневої файлової системи (overlay mounts, bind mounts, tmpfs)
- застосування політик безпеки (seccomp, AppArmor/SELinux)
- налаштування init-процесу і виклик вашого entrypoint
Коли будь-хто з цих кроків зазнає невдачі, Docker часто виводить повідомлення, що починається з:
docker: Error response from daemon: OCI runtime create failed: ...
і потім вкладений ланцюжок на кшталт container_linux.go, process_linux.go,
failed to create shim task, permission denied, invalid argument або no space left on device.
Ваше завдання — ігнорувати загальний префікс і зосередитися на останньому конкретному скриптовому/системному повідомленні.
Це останнє повідомлення зазвичай і є правдою.
Одне суворе правило: ставтеся до цієї помилки як до помилки ядра в одязі Docker. Виправляйте проблему, що стосується ядра, а не «одяг».
Жарт №1 (короткий, по темі): помилки OCI — це як індикатор «check engine» — вказує, що щось не так, але не каже, який циліндр палає.
Факти та історія: чому ця помилка існує
Трохи контексту допомагає, бо помилки OCI сформовані тим, як розвивалися контейнери: шарами стандартів, рантаймів і демонів,
що спілкуються через API. Ось кілька конкретних фактів, які пояснюють дивні симптоми.
- Linux-контейнери існували до Docker. cgroups з’явилися в Linux близько 2007–2008; неймспейси дозріли в 2000-х. Docker популяризував пакування.
- Спочатку Docker використовував LXC за замовчуванням. Ранні версії Docker використовували LXC; пізніше перейшли на libcontainer (Go), а потім стандартизувалися на runc.
- OCI (Open Container Initiative) створено 2015 року. Мета: стандартизувати образи та рантайми, щоб «контейнер» мав переносиме значення.
- runc походить із Docker libcontainer. runc — референсний OCI runtime; багато рантаймів реалізують той самий специфікаційний API.
- containerd був винесений, щоб зменшити зв’язність. Docker делегував більше функцій containerd; ви побачите помилки щодо «shim», бо containerd використовує шими для керування процесами контейнерів.
- Крок OCI «create» — це не «запустити ваш додаток». «Create» означає налаштувати стан та оточення контейнера; exec вашого додатка відбувається пізніше і може падати з іншої причини.
- cgroup v2 змінив стандартні налаштування і припущення. Дистрибутиви поміняли ієрархію за замовчуванням; деякі Docker-конфіги зламалися, поки їх не налаштували для systemd cgroups і сумісних драйверів.
- Модулі безпеки змінювалися з часом. Політики SELinux і AppArmor могли еволюціонувати так, що раніше робочі контейнери раптово починали отримувати «permission denied».
- OverlayFS має вимоги до функцій ядра. Деякі режими overlay (наприклад, metacopy, redirect_dir, idmapped mounts) залежать від версії ядра і можуть дивно падати при їх зміні.
Швидкий план діагностики (робіть у вказаному порядку)
Коли продакшен горить, вам потрібен алгоритм найкоротшого шляху, а не філософський курс. Ось порядок дій, що часто швидко знаходить вузьке місце.
1) Зібрати повний ланцюжок помилки
- Перезапустіть команду з максимальною контекстною інформацією демона (логи + події).
- Витягніть останню помилку:
permission denied,no space left on device,invalid argument,exec format error,operation not permitted.
2) Перевірте очевидні проблеми хоста: диск, inode, пам’ять, логи ядра
- Диск/inode на Docker root (
/var/lib/dockerабо кастомний шлях). - dmesg/journal на предмет відмов AppArmor/SELinux або помилок маунта.
- Пам’ять/тиск cgroup, якщо ланцюжок помилок натякає на збої fork/exec.
3) Визначте підсистему, що не пройшла, за останньою помилкою
- Mount/rootfs: помилки overlay2, «unknown filesystem», «invalid argument», «permission denied».
- Безпека: AppArmor/SELinux AVC/denied у логах; seccomp «operation not permitted».
- cgroups: помилки з шляхами cgroup, контролерами або systemd.
- Entrypoint: «exec format error», «no such file or directory» (часто відсутній інтерпретатор), «text file busy».
4) Відтворіть проблему з найменшим можливим контейнером
- Спробуйте відомий робочий образ і тривіальну команду (наприклад,
busybox true). - Якщо навіть це падає — проблема хоста/рантайму. Якщо лише один образ падає — проблема конфігурації образу, entrypoint або маунтів.
5) Виправляйте по одному і тестуйте
Не робіть «перезавантаж Docker, перезавантаж вузол, вимкни безпеку» послідовно. Зробіть одну зміну, перевірте, переходьте далі.
Ви налагоджуєте, а не виконуєте ритуал.
Співставлення відмови по шарах: Docker → containerd → runc → kernel
Якщо хочете працювати швидко, думайте шарами та вибирайте потрібний лог.
- Docker CLI виводить зведену помилку. Корисний для фінального рядка, але не для деталей.
- dockerd логи показують, що Docker попросив containerd і що повернулося.
- containerd логи показують виклики shim та runtime. «failed to create shim task» зазвичай тут.
- runc виконує системні виклики ядра. Його помилки — найважливіші.
- kernel логи (dmesg/journal) часто містять реальне відхилення або блокування, особливо для LSM.
«OCI runtime create failed» зазвичай означає, що runc повернув ненульовий код під час create.
Крок create включає маунт кореневої FS і bind маунти. Тому домінують проблеми зі зберіганням і безпекою.
Цитата (перефразована ідея): Ідея на кшталт Вернера Фогельса: все ламається постійно — ваше завдання будувати системи, що цього очікують і вміють з цим працювати.
Практичні завдання: 12+ команд з виводами і рішеннями
Нижче — практичні завдання, які можна виконати на Linux-хості з встановленим Docker Engine. Кожне містить:
команду, типічний вивід і рішення, що з нього випливає. Виконуйте їх у порядку, який відповідає вашим симптомам,
а не обов’язково зверху вниз.
Завдання 1: Повторіть запуск контейнера з максимальною ясністю
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.
Що це означає: Остання частина (open /proc/self/fd: permission denied) — ваш провідник. Це вказує на політику безпеки (SELinux/AppArmor/seccomp) або посилені налаштування маунту /proc.
Рішення: Перейдіть до логів ядра/LSM (Завдання 4–6) перед тим, як чіпати зберігання.
Завдання 2: Перевірте, чи проблема глобальна чи специфічна для образу
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.
Що це означає: Якщо навіть BusyBox падає, середовище хоста/рантайму зламане, а не ваш додаток.
Рішення: Зосередьтеся на конфігурації демона, можливостях ядра, політиках LSM, cgroups і стані драйвера зберігання.
Завдання 3: Прочитайте логи демона Docker навколо помилки
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"
Що це означає: dockerd повторює помилку рантайму, але підтверджує часову шкалу і що це не клієнтська помилка.
Рішення: Якщо в логах dockerd є «permission denied», «invalid argument», «no space» тощо, переслідуйте саме цю фразу вниз по стеку.
Завдання 4: Перегляньте логи containerd (де з’являються помилки shim/runc)
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"
Що це означає: «failed to create shim task» — це спосіб containerd сказати, що рантайм не зміг налаштувати контейнер. Остання частина залишається ключовою.
Рішення: Якщо тут видно помилки, пов’язані з маунтом — переходьте до перевірок драйвера зберігання. Якщо — відмови доступу/permission — перевіряйте LSM.
Завдання 5: Перевірте логи ядра на відмови AppArmor
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
Що це означає: Це «димлячий пістолет». AppArmor заблокував init-процес runc від читання /proc/self/fd.
Рішення: Виправте профіль AppArmor або запускайте контейнери з відповідним override профілем (див. Поширені помилки та чекліст). Не вимикайте AppArmor глобально, якщо ви не полюбляєте ризики.
Завдання 6: Перевірте відмови SELinux (RHEL/Fedora/CentOS похідні)
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
Що це означає: SELinux заблокував операцію маунта. tcontext з default_t виглядає підозріло; мітки неправильні або шлях зберігання не має правильних контекстів для контейнерів.
Рішення: Відновіть правильні контексти на шляхах Docker storage або коректно налаштуйте політику. Уникайте встановлення SELinux у permissive як постійне «вирішення»; це скоріше діагностичний крок.
Завдання 7: Перевірте драйвер зберігання Docker і кореневий каталог
cr0x@server:~$ docker info --format 'Driver={{.Driver}} RootDir={{.DockerRootDir}} CgroupDriver={{.CgroupDriver}}'
Driver=overlay2 RootDir=/var/lib/docker CgroupDriver=systemd
Що це означає: Тепер ви знаєте, де лежать дані і який драйвер. Overlay2 — нормально; це також означає, що маунти і підтримка overlay у ядрі важливі.
Рішення: Якщо RootDir на дивній файловій системі (NFS, eCryptfs, стара XFS без ftype), очікуйте проблем. Перевірте бекінг-ФС наступним кроком.
Завдання 8: Перевірте місце на диску та inode для Docker RootDir
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% /
Що це означає: «No space left on device» може бути спричинене як блоками диска, так і inode. Overlay2 сильно використовує inode.
Рішення: Якщо одне з них близьке до повного, припиніть шукати складні речі. Звільніть місце (Завдання 9) або розширте сховище. Контейнери не зможуть змонтувати шари, якщо ФС не може створити метадані.
Завдання 9: Безпечно звільнити місце Docker (і розуміти, що ви видаляєте)
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
Що це означає: docker system df показує, де зайняте місце. Prune видаляє зупинені контейнери, «dangling» образи і невикористовувані мережі. Томиви видаляються лише з --volumes.
Рішення: У продакшені prune прийнятний, якщо ви розумієте стратегію кешування образів і не покладаєтесь на зупинені контейнери як на джерело судових даних. Для вузлів, що часто перебираються, заплануйте prune з обмеженнями.
Завдання 10: Перевірте файлову систему, що лежить під 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
Що це означає: Overlay2 на XFS потребує ftype=1. Якщо там ftype=0, рано чи пізно ви отримаєте дивну поведінку overlay і помилки запуску контейнерів.
Рішення: Якщо ftype=0, правильне виправлення — перемістити Docker RootDir на правильно відформатовану файлову систему. Немає безпечної інлайн-зміни.
Завдання 11: Перевірте propagation маунтів / shared mounts (поширено на хостах Kubernetes)
cr0x@server:~$ findmnt -o TARGET,PROPAGATION /var/lib/docker
TARGET PROPAGATION
/var/lib/docker shared
Що це означає: Деякі навантаження в контейнерах вимагають shared mount propagation; інші падають, якщо макет маунтів хоста незвичний. Якщо це private в середовищі, що очікує shared, ви можете бачити помилки OCI create, пов’язані з маунтами.
Рішення: Якщо підозрюєте проблеми propagation, порівняйте з відомим робочим вузлом і узгодьте systemd mount unit-и. Уникайте випадкового mount --make-rshared / в продакшені, якщо не розумієте площу ураження.
Завдання 12: Перевірте seccomp і протестуйте з unconfined профілем (тільки для діагностики)
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.
Що це означає: Seccomp unconfined нічого не змінив. Це натякає, що seccomp не є причиною (в цьому прикладі); швидше за все це AppArmor.
Рішення: Використовуйте unconfined перемикачі як контрольні експерименти. Якщо unconfined «вирішує» проблему, розробіть правильний профіль замість того, щоб залишати його відкритим.
Завдання 13: Перевірте режим і ієрархію cgroup (поширено з cgroup v2)
cr0x@server:~$ stat -fc %T /sys/fs/cgroup
cgroup2fs
cr0x@server:~$ docker info --format 'CgroupVersion={{.CgroupVersion}} CgroupDriver={{.CgroupDriver}}'
CgroupVersion=2 CgroupDriver=systemd
Що це означає: Ви на cgroup v2 і Docker використовує systemd драйвер (загалом правильно для сучасних дистрибутивів). Якщо бачите невідповідність (cgroup v2 з cgroupfs драйвером в деяких налаштуваннях), це може викликати помилки create.
Рішення: Узгодьте драйвер cgroup Docker з systemd на systemd-хостах. Якщо ви в legacy-оточенні, тестуйте на відомому робочому вузлі перед змінами в кластері.
Завдання 14: Переконайтеся, що entrypoint-байт виконуваний і відповідає архітектурі
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
Що це означає: Якщо у вашому образі ARM-байт у x86_64-хості, ви побачите exec format error під час create/start. Ця перевірка показує, як виглядає «нормально».
Рішення: Якщо є невідповідність архітектури, виправте збірку образу або використовуйте мультиархітектурні маніфести правильно. Не «вирішуйте» це встановленням qemu-емуляції на продакшен-вузлах, якщо ви не розумієте наслідків продуктивності.
Завдання 15: Перевірте, що bind-маунти існують і мають правильні права
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.
Що це означає: Відсутній хостовий шлях викликає OCI create failure, бо налаштування маунту відбувається до старту процесу.
Рішення: Виправте хостовий шлях, створіть його з правильною власністю або використовуйте Docker-томи замість крихких хостових шляхів.
Завдання 16: Відшукайте явні помилки overlay2
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
Що це означає: Бекінг-файлова система не підтримує функції, які очікує overlay. Це може бути спричинено екзотичними файловими системами, певними опціями маунта або старими ядрами.
Рішення: Перемістіть Docker RootDir на підтримувану локальну ФС (ext4 або правильно налаштований XFS), або оновіть ядро/налаштування сховища, щоб відповідати вимогам overlay.
Жарт №2 (короткий, по темі): Вимикати SELinux, щоб «полагодити Docker» — це як зняти пожежну сигналізацію, бо вона голосно пищить.
Три короткі корпоративні історії з практики
Міні-історія 1: Інцидент через хибне припущення
Середня компанія запускала Docker на флоті загального призначення VM. Одна команда відповідала за «базовий образ», інша — за «платформу».
Команда платформи розгорнула зміну жорсткого захисту: нові AppArmor-профілі і оновлення ядра. Припущення було простим і хибним:
«Контейнери ізольовані; суворіший хост-профіль на них не вплине».
Вранці у понеділок підмножина сервісів перестала деплоїтися. Симптом був однаковим скрізь:
OCI runtime create failed з open /proc/self/fd: permission denied.
Команди спочатку звинувачували образ, бо відмова з’являлася при старті контейнера. Декілька інженерів даремно витратили години на перебудову образів
і перекат тегів, бо ж це мало бути «помилка аплікації».
Розв’язка прийшла від того, хто відкрив dmesg замість Slack.
Логи аудиту ядра показали AppArmor-deny на docker-default.
Оновлення політик посилило доступ до шляхів /proc так, що init-процес runc не міг працювати.
Docker не був зламаний. Хостова політика безпеки була жорсткішою, ніж потребував рантайм.
Лікування було хірургічним: відкоригували AppArmor-профіль для тих робочих навантажень і розкатали його канаркою.
Також написали короткий рукопис: «Якщо помилка закінчується permission denied — перевірте LSM-логи першими».
Інцидент міг би тривати 20 хвилин. Натомість він зайняв півдня через хибне припущення.
Міні-історія 2: Оптимізація, що відгукнулась боком
Інша організація намагалася оптимізувати швидкість збірки та деплою на CI-runner-ах. Вони помістили Docker RootDir на мережеву файлову систему,
бо це було «швидке сховище» і полегшувало прибирання. Також це уникало локальних апгрейдів дисків. Проєкт виглядав як економія коштів за рахунок перенесення складності.
Спочатку працювало. Потім рандомні джоби почали падати з OCI runtime create failed,
зазвичай у вигляді помилок маунту або «invalid argument». Це було періодично. Саме це найбільше вбивало час.
Періодичні помилки — це місце, куди йде інженерний час тихо та болісно.
Справжня причина: overlay2 на не‑локальному файловому сховищі — мінне поле сумісності. Навіть якщо «працює», виникають крайові випадки:
семантика блокувань файлів, підтримка d_type, підтримка tmpfile, сплески латентності при операціях маунта і гонки, коли тисячі шарів змінюються щодня.
Відкат був простим: повернули Docker RootDir на локальний SSD, ввели квоти на prune і визнали, що кеш збірки — це функція продуктивності, а не політика збереження даних.
Після цього create failures припинилися. Оптимізація була спрямована не на те: зручність сховища, а не коректність рантайму.
Міні-історія 3: Нудна, але правильна практика, що врятувала день
Велике підприємство мало змішаний флот: різні версії ядра, дистрибутиви, режим відповідності. Вони боялися простоїв, тож зробили непопулярну річ:
стандартизували базовий образ хоста для контейнерів.
Та сама файлова система й опції для Docker RootDir, той самий cgroup драйвер, однакова конфігурація модулів безпеки
і вузький набір протестованих версій ядра.
Одного дня новий сервіс почав падати на одному кластері з OCI runtime create failed і invalid argument.
On-call інженер порівняв вузол з відомим робочим базлайном за допомогою маленького чекліста:
docker info, тип ФС, версія ядра і швидкий перегляд логів ядра.
Виновник знайшовся швидко: невелика підмножина вузлів була підготована зі старішим XFS, де ftype=0
через застарілий скрипт image-ування. Це не ламало все негайно; ламало «достатньо», щоб дратувати, і лише при певних шаблонах шарів.
Оскільки у них був базлайн, виправлення не стало предметом дебатів. Вони відключили ті вузли, перебудували з правильними опціями ФС
і повернули ємність. Ніяких героїчних дій, ніякого «вимкнути безпеку», ніяких експериментальних прапорів вночі. Нудна практика перемогла.
Поширені помилки: симптом → корінна причина → виправлення
Помилки OCI create виглядають повторюваними, але корінні причини різні. Ось найпоширеніші шаблони, згруповані як ви насправді їх діагностуєте.
1) «permission denied» під час ініціалізації контейнера
Симптом: Помилка закінчується permission denied, часто згадуючи /proc, маунти або файли під /var/lib/docker.
Корінна причина: Відмова AppArmor/SELinux, неправильні мітки на директоріях Docker або жорсткі опції маунта.
Виправлення: Перевірте dmesg та логи аудиту. Відновіть SELinux-контексти для Docker RootDir; відкоригуйте профіль AppArmor. Використовуйте --security-opt лише як діагностику, а потім впровадьте правильну політику.
2) «no space left on device», хоча вільно кілька GB
Симптом: OCI create падає з ENOSPC, а df -h показує місце.
Корінна причина: Вичерпані inode (df -i) або RootDir Docker знаходиться не там, де ви думаєте (bind-mounted у менший том).
Виправлення: Перевірте df -i і docker info RootDir. Очистіть невикористовувані шари; розширте файлову систему; розгляньте переміщення RootDir на окремий том.
3) «invalid argument» навколо overlay маунтів
Симптом: failed to mount overlay: invalid argument або подібне в логах ядра.
Корінна причина: Непідтримувана бекінг-файлова система (NFS, стара конфігурація XFS, несумісні опції маунта) або невідповідність функцій ядра і overlay.
Виправлення: Помістіть Docker RootDir на підтримувану локальну ФС; перевірте XFS ftype=1; оновіть ядро за потреби; не намагайтеся працювати з overlay2 на «креативному» сховищі.
4) «exec format error» або «no such file or directory» при старті
Симптом: Контейнер падає відразу; ланцюжок помилок закінчується помилками виконання.
Корінна причина: Бінарник для іншої архітектури; відсутній інтерпретатор (наприклад, скрипт з #!/bin/bash, а bash у образі відсутній); CRLF-закінчення рядків в entrypoint-скриптах також можуть створювати проблему.
Виправлення: Перевірте архітектуру образу і entrypoint. Переконайтесь, що інтерпретатори існують. Будуйте мультиархітектурні образи правильно.
5) Невдачі bind-маунтів
Симптом: Помилка згадує «error mounting» хостовий шлях, «no such file», або «not a directory».
Корінна причина: Відсутній хостовий шлях, неправильний тип (файл замість директорії), або права/мітки, що перешкоджають маунту.
Виправлення: Створіть шлях, виправте права і контексти SELinux, або перейдіть на іменовані томи.
6) Помилки cgroup (особливо після оновлення ОС)
Симптом: OCI create падає з посиланням на cgroups, контролери або systemd.
Корінна причина: Переходи на cgroup v2, невідповідний драйвер cgroup Docker або заблоковані контролери.
Виправлення: Узгодьте драйвер cgroup з systemd на systemd-хостах; переконайтеся, що потрібні контролери включені; перевірте з docker info та stat -fc %T /sys/fs/cgroup.
Чеклісти / покроковий план
Чекліст для інциденту: відновіть сервіс, потім виправте правильно
-
Отримайте точний фінальний рядок помилки.
Повторіть мінімальний контейнер і зафіксуйте вивід.
Визначте, чи пахне це зберіганням, безпекою, cgroups чи entrypoint-ом. -
Підтвердіть, що це не специфічно для образу.
Запустітьbusybox true.
Якщо воно падає — припиніть звинувачувати аплікацію. -
Перевірте ресурси хоста (блоки + inode) на Docker RootDir.
Якщо заповнено — очистьте або розширте. Не ускладнюйте. -
Перегляньте логи ядра на предмет відмов і помилок маунта.
Якщо бачите відмови AppArmor/SELinux — маєте категорію корінної причини. -
Порівняйте один зламаний вузол з одним робочим.
Така сама версія ядра? та сама ФС? та сама конфігурація Docker? однакові опції безпеки?
Відмінності зазвичай дають відповідь. -
Застосуйте найменше безпечне пом’якшення.
Приклади: звільнити місце, відновити мітки, відкоригувати профіль, виправити шлях маунта.
Уникайте «вимкнути весь модуль безпеки», якщо це не короткий діагностичний крок з планом відкату. -
Перевірте заново мінімальним контейнером, потім справжнім робочим навантаженням.
Якщо мінімальний працює, а додаток ні — ви перейшли від рівня хоста до рівня аплікації (entrypoint, маунти, права користувача).
Чекліст для профілактики: не давайте майбутньому собі зустріти вас у халепі
- Розміщуйте Docker RootDir на підтримуваній локальній ФС. ext4 або правильно налаштований XFS. Уникайте мережевого сховища для шляхів runtime overlay2.
- Моніторьте і місце на диску, і використання inode. Алармуйтесь до 85–90% для обох, а не лише по GB.
- Стандартизуйте драйвер cgroup і ієрархію. Якщо у вас systemd — використовуйте systemd cgroups, якщо немає вагомої причини інакше.
- Логуйте LSM-відмови централізовано. Відмови AppArmor і SELinux мають потрапляти у вашу логінгову систему з фільтрами, інакше ви будете налагоджувати всліпу.
- Базуйте конфігурацію хостів і контролюйте дрейф. Версія ядра, драйвер зберігання, опції маунта, daemon.json. Робіть дрейф видимим.
- Тримайте в рукописі екстрений «мінімальний контейнер» тест. BusyBox/Alpine тест покаже, чи хост фундаментально зламаний.
- Документуйте дозволені виключення security-opt. Якщо деяким навантаженням потрібен unconfined, розглядайте це як ризикове рішення, а не як забаганку розробника.
Часті питання
1) Що таке OCI у повідомленнях Docker?
OCI — це специфікація Open Container Initiative. На практиці Docker використовує OCI-рантайм (зазвичай runc) для налаштування неймспейсів,
cgroups, маунтів, а потім запускає ваш процес. Помилка означає, що налаштування не вдалося.
2) Чому помилка згадує runc або контейнерd shim?
Docker делегує операції рантайму containerd, який використовує shim для керування процесами контейнерів. runc виконує низькорівневі
операції create/start. Збої піднімаються крізь шари, тож ви бачите їхні імена в ланцюжку.
3) Чи іноді «OCI runtime create failed» вирішується перезапуском Docker?
Іноді — якщо демон завис або containerd став некоректним. Але більшість випадків — це реальна проблема хоста (місце, маунти,
політики, cgroups). Перезапуск може тимчасово стерти симптоми, але не усуне корінну причину.
4) Як зрозуміти, чи це проблема образу чи хоста?
Запустіть маленький відомий робочий контейнер. Якщо docker run --rm busybox true падає — це хост/рантайм. Якщо BusyBox працює, а ваш образ падає — швидше за все це entrypoint, архітектура, відсутній інтерпретатор, маунти або права всередині образу.
5) Чому я бачу «no such file or directory», коли файл існує?
Часто entrypoint — це скрипт зі шебангом, який вказує на інтерпретатор, якого нема в образі (наприклад, /bin/bash).
Інша поширена причина — невідповідність архітектури, що породжує заплутані помилки виконання.
6) Як вичерпання inode призводить до OCI create failures?
Overlay2 створює багато дрібних файлів і директорій для метаданих шару. Якщо inode досягають 100%, рантайм не може створити необхідні
директорії під час маунта/налаштування, тому create падає, навіть якщо у вас ще є GB вільного місця.
7) Чи можуть SELinux/AppArmor справді зупинити запуск контейнерів?
Так. Сам рантайм (runc) — це процес на хості, підпорядкований політиці хоста. Якщо політика блокує маунти, доступ до файлів
або певні операції, створення контейнера зазнає невдачі ще до запуску вашого додатка.
8) Який найбезпечніший спосіб перевірити, чи проблема в безпеці?
Використовуйте адресні діагностики: спочатку перевірте логи ядра/аудиту. Якщо треба експериментувати, запустіть окремий тестовий контейнер з конкретним
override (наприклад, unconfined seccomp) і одразу поверніть налаштування. Не змінюйте глобальні параметри як випадковий тест.
9) Чи викликає cgroup v2 помилку OCI runtime create failed?
Може, особливо при невідповідній конфігурації Docker або застарілих компонентах рантайму. Перевірте версію cgroup і драйвер за допомогою
docker info та переконайтеся, що хост увімкнув потрібні контролери.
10) Якщо overlay2 зламаний, чи можу я переключити драйвер зберігання на тому ж RootDir?
Ставте це як міграційну роботу, а не як перемикач. Зміна драйвера зазвичай вимагає перенесення або перебудови стану Docker. Робіть це обдумано:
відключіть навантаження, зробіть бекап важливого (томи) і перебудуйте вузли, якщо це можливо.
Висновок: що робити наступного разу
«OCI runtime create failed» — це мовою Docker «ядро сказало ні», з додатковими кроками. Швидкий шлях:
зафіксуйте фінальний фрагмент помилки, класифікуйте її (безпека/зберігання/cgroups/entrypoint) і переходьте до логів, які можуть це підтвердити.
Наступні кроки, що дають швидкий ефект:
- Напишіть короткий рукопис: тест BusyBox,
docker infoRootDir/Driver,df -hіdf -i, потімdmesg/journalctl. - Базуйте ваші хости контейнерів: тип/опції файлової системи, XFS ftype, режим cgroup, модулі безпеки. Дрейф — тихий вбивця.
- Припиніть зберігати runtime-шари Docker на «розумному» сховищі. Використовуйте локальні диски для overlay2; для персистентних даних — відповідні системи зберігання.
- Коли помилка каже «permission denied», повірте їй. Ідіть прямо в логи AppArmor/SELinux/audit і виправляйте політику або мітки.