Вопрос или проблема
Я пытаюсь создать образ docker, который включает этот репозиторий github: https://github.com/javgh/sia-nbdserver
Это nbd-сервер, который кэширует файлы локально, а затем записывает их в распределенную сеть хранения sia. Я выполнил modprobe nbd
на хосте и теперь пытаюсь передать /dev/nbd0 в контейнер и использовать nbd-client внутри контейнера, чтобы отправлять данные, которые хост записывает на устройство, на nbd-сервер с помощью сокета Unix. Я вижу /dev/nbd0 внутри контейнера, nbd-сервер запущен и слушает на сокете по адресу /tmp/sia-nbdserver, но когда я пытаюсь запустить # nbd-client -b 4096 -t 3600 -u /tmp/sia-nbdserver /dev/nbd0
, я получаю Ошибка: Не удалось разрешить семью netlink nbd, убедитесь, что модуль nbd загружен, и ваш драйвер nbd поддерживает интерфейс netlink.
Я запускаю контейнер с --cap-add SYS-ADMIN
и --privileged
, так что разрешения не должны быть проблемой.
Есть идеи?
Запустите контейнер с чем-то вроде:
docker run -it --rm --privileged --cap-add=ALL -v/dev:/dev -v/lib/modules:/lib/modules:ro image-id
И посмотрите, загружается ли модуль внутри контейнера правильно.
Столкнулся с тем же, решил, добавив --net=host
docker run -it --rm --privileged --cap-add=ALL --net=host -v/dev:/dev -v/lib/modules:/lib/modules:ro image-id
Существует два API для настройки узлов устройств nbd
: старый способ, основанный на ioctl()
, и новый способ, который использует API netlink.
Нет пространства имен блочного устройства, что означает, что блочное устройство не может быть ограничено контейнером. Однако есть много вещей, которые настраиваются через netlink, которые могут быть ограничены контейнером (например, конфигурация сети), и поэтому я предполагаю, что netlink различает вещи, которые могут быть ограничены, и вещи, которые не могут быть ограничены контейнером, и я не вижу, как это могло бы быть расшарено без введения осложнений.
Тем не менее, вы можете использовать параметр командной строки -nonetlink
(также известный как -L
), чтобы попросить nbd-client
использовать API ioctl()
для настройки устройства вместо netlink. Поскольку это использует прямой доступ к узлу устройства NBD, сделать это изнутри контейнера должно быть возможным.
Тем не менее, я должен отметить, что не думаю, что запускать это внутри контейнера имеет большой смысл. Поскольку узлы устройств nbd
не имеют пространства имен, изоляции, которую вы ожидаете от запуска этого внутри контейнера, с устройствами nbd
не существует.
Ответ или решение
Проблема с nbd-client и nbd-server в контейнере Docker: "Couldn’t resolve the nbd netlink family"
Когда вы работаете с сетевыми блочными устройствами и контейнерами Docker, могут возникать разные проблемы, связанные с ограничениями контейнерной изоляции и доступом к системным ресурсам. Одной из распространенных ошибок, с которой сталкиваются пользователи, является сообщение об ошибке: "Couldn’t resolve the nbd netlink family". Эта статья поможет вам понять причины данной ошибки и предложит возможные решения.
Причины проблемы
Сообщение об ошибке связано с тем, что nbd-client (клиент сетевого блочного устройства) не может взаимодействовать с nbd-server (сервер сетевого блочного устройства) с использованием интерфейса netlink. Вот несколько возможных причин:
-
Недостаточная изоляция доступа: По умолчанию, Docker использует сетевую изоляцию, которая может помешать корректной работе netlink интерфейса.
-
Не загружен модуль nbd: Хотя вы уже применили команду
modprobe nbd
на хосте, важно убедиться, что модуль корректно загружен и доступен в контейнере. -
Отсутствие доступа к интерфейсу netlink: Для корректной работы nbd вам может понадобиться предоставить доступ к интерфейсу netlink, что может быть ограничено в среде контейнеризации.
Решения
Вот ряд шагов, которые помогут вам устранить данную ошибку.
-
Запуск контейнера с привилегиями:
Убедитесь, что вы запускаете контейнер с флагами--privileged
и--cap-add=ALL
, чтобы предоставить контейнеру все необходимые привилегии:docker run -it --rm --privileged --cap-add=ALL -v /dev:/dev -v /lib/modules:/lib/modules:ro image-id
-
Использование сетевого пространства хоста:
Попробуйте запустить контейнер с использованием сетевого пространства хоста, добавив флаг--net=host
:docker run -it --rm --privileged --cap-add=ALL --net=host -v /dev:/dev -v /lib/modules:/lib/modules:ro image-id
Это позволит контейнеру использовать сетевые ресурсы родительского хоста и может решить проблему с доступом к интерфейсу netlink.
-
Использование альтернативного API:
Если вышеуказанные шаги не помогли, вы можете попробовать использовать альтернативный метод для настройки устройства с помощью-nonetlink
:nbd-client -b 4096 -t 3600 -u /tmp/sia-nbdserver -L /dev/nbd0
Этот параметр принудит
nbd-client
использоватьioctl()
API вместо netlink, что может устранить возникшую проблему. -
Синхронизация модулей:
Убедитесь, что модули ядра, необходимые для работы nbd, находятся в нужной версии и их доступ к контейнеру корректно настроен.
Заключение
Работа с сетевыми блочными устройствами в контейнерах Docker требует внимания к деталям, особенно в контексте управления привилегиями и доступом к ресурсам. Описанные выше шаги помогут вам устранить ошибку "Couldn’t resolve the nbd netlink family". Однако важно помнить, что использование nbd
внутри контейнера может привести к снижению ожидаемой изоляции, поскольку блочные устройства не подлежат контейнеризации.
Если трудности продолжаются, рассмотрите возможность выполнения этих действий на хост-системе, особенно если безопасность является приоритетом в вашей среде.