Снятие ограничений для 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 режима.