Снятие ограничений для Docker в Incus на Debian 13
Введение
При запуске Docker внутри контейнера Incus (LXC) на Debian 13 можно столкнуться с ошибкой:
OCI runtime create failed:
open sysctl net.ipv4.ip_unprivileged_port_start file: permission denied
Эта ошибка возникает не из-за Docker, а из-за ограничений безопасности LXC-контейнера.
В данной статье объясняется, что именно блокируется и почему команда:
incus config set incus-jitsi security.privileged true
incus restart incus-jitsi
решает проблему.
Архитектура по умолчанию
Стандартная схема:
Host Debian 13
└── Incus container (unprivileged)
└── Docker
└── Docker containers
По умолчанию Incus создаёт непривилегированные контейнеры (unprivileged).
Это означает:
- UID 0 внутри контейнера ≠ root на хосте
- используется user namespace
- запрещена запись в ряд файлов
/proc/sys - запрещены некоторые операции с cgroups
- ограничены сетевые sysctl
Почему Docker не запускался
Docker использует:
- namespaces
- cgroups
- overlayfs
- изменение sysctl
- runtime
runc
При запуске контейнера runc применяет стандартные параметры OCI, включая попытку изменить:
/proc/sys/net/ipv4/ip_unprivileged_port_start
В unprivileged LXC:
- доступ к этому sysctl запрещён
- запись блокируется механизмами user namespace + AppArmor
- Docker получает
permission denied
Даже если внутри контейнера вы root — это "виртуальный" root.
Что делает security.privileged true
Команда:
incus config set incus-jitsi security.privileged true
переключает контейнер в privileged режим.
После перезапуска:
incus restart incus-jitsi
контейнер:
- больше не использует user namespace
- UID 0 внутри контейнера = UID 0 на хосте
- получает расширенные права к
/proc - может изменять sysctl
- получает доступ к большему набору kernel capabilities
- снимаются ограничения на часть cgroup операций
Фактически контейнер становится максимально близким к полноценной виртуальной машине по правам (но без собственного ядра).
Почему это помогло Docker
После включения privileged:
runcсмог записать sysctl- не произошло блокировки при reopen fd
- container init завершился успешно
- Docker-контейнер стартовал
То есть проблема была не в Docker, а в том, что LXC запрещал операции, необходимые для запуска вложенной контейнеризации.
Что именно было снято
При переходе в privileged режим:
| Ограничение | До | После |
|---|---|---|
| User namespace | включён | отключён |
| UID mapping | remapped | прямой |
Запись в /proc/sys |
ограничена | разрешена |
| Kernel capabilities | урезаны | расширены |
| Работа Docker | частично блокируется | работает |
Важное предупреждение
security.privileged=true снижает безопасность.
Контейнер:
- получает почти полный root-доступ к хосту
- может потенциально повлиять на систему
- не изолирован так строго, как unprivileged
Для production-систем рекомендуется:
- использовать
security.nesting=trueвместо privileged - или запускать Docker в Incus VM (
--vm) - или запускать Docker непосредственно на хосте
Когда допустимо использовать privileged
- лабораторные стенды
- тестовые окружения
- разработка
- домашний сервер
Для публичных сервисов (например, Jitsi Meet) лучше рассмотреть VM.
Итог
Команда:
incus config set <container> security.privileged true
снимает ограничения user namespace и расширяет права контейнера до уровня, необходимого для полноценной работы Docker внутри Incus.
Это решает проблему запуска, но делает контейнер менее безопасным.
Оптимальный баланс между работоспособностью и безопасностью — security.nesting=true без privileged режима.