Проблема с устройствами цикличной ссылки в Docker

Вопрос или проблема

Я пытаюсь создать образ виртуального диска в Docker. Мне удалось создать пустой файл с помощью dd и создать разделы с помощью parted, но когда я пытаюсь сделать файловую систему, возникает ошибка, говорящая о том, что устройство не найдено. В контейнере Docker я запускаю от имени root и передал --privileged=true в docker run.

Это работает вне Docker и работает в Docker на моем локальном компьютере. Ошибка возникает только на моем сборочном сервере (AWS elastic agent).

Вот часть вывода, показывающая, что блочное устройство существует до вызова создания файловой системы.

28-фев-2019 10:39:33  +./scripts/make.sh:105> ls -l /dev/loop2 /dev/loop2p1 /dev/loop2p2
28-фев-2019 10:39:33  brwxrwxrwx 1 root disk   7, 2 28 фев 15:39 /dev/loop2
28-фев-2019 10:39:33  brwxrwxrwx 1 root disk 259, 8 28 фев 15:39 /dev/loop2p1
28-фев-2019 10:39:33  brwxrwxrwx 1 root disk 259, 9 28 фев 15:39 /dev/loop2p2
28-фев-2019 10:39:33  +./scripts/make.sh:108> mkfs.vfat -n boot /dev/loop2p1
28-фев-2019 10:39:33  mkfs.fat 3.0.28 (2015-05-16)
28-фев-2019 10:39:33  /dev/loop2p1: Нет такого устройства или адреса

И часть скрипта:

## Создаем файл, заполненный нулями
dd if=/dev/zero of=disk.img bs=1M count=400

## Находим следующее доступное блочное устройство
local lodev=$(losetup -f)

## Делаем так, чтобы обычный файл выглядел как блочное устройство
ls -l ${lodev}*
losetup ${lodev} disk.img

## Создаем таблицу разделов и сам раздел
parted -s -a optimal ${lodev} mklabel msdos
parted -s -a optimal -- ${lodev} unit compact mkpart primary "10" "20"
parted -s -a optimal -- ${lodev} unit compact mkpart primary "21" "-1"
parted -s ${lodev} set 1 boot on
ls -l ${lodev}*

## Создаем файловую систему
mkfs.vfat -n boot ${lodev}p1
mkfs.ext3 -L rootfs ${lodev}p2

Есть идеи, почему mkfs.fat считает, что блочное устройство не существует, когда, похоже, оно существует?

Один из способов обойти эту проблему – смонтировать папку /dev. Кажется, это сработало для меня.

 docker run --privileged -ti -v /dev:/dev ...

Ответ или решение

Проблема, с которой вы столкнулись при создании виртуального дискового образа в Docker, связана с тем, как Docker обрабатывает устройства блоков и устройства цикловых (loop) устройств, особенно в сочетании с использованием инфраструктуры CI/CD, таких как AWS Elastic Agent.

Основная проблема

При создании файловой системы на разделе /dev/loop2p1 Docker считает, что это устройство не существует, хотя при выполнении команды ls -l оно отображается как доступное. Это может происходить из-за особенностей работы Docker, а также конфигурации вашего CI/CD окружения.

Возможное решение

Одним из решений этой проблемы является монтирование каталога /dev в контейнере Docker. Это позволяет вашему контейнеру видеть устройства, которые существуют на хост-системе. Вы можете сделать это, добавив опцию -v /dev:/dev к вашей команде docker run.

Пример команды:

docker run --privileged -ti -v /dev:/dev ...

Дополнительные рекомендации

  1. Проверка прав доступа: Убедитесь, что у вашего CI/CD процесса есть соответствующие права для работы с устройствами блоков. Возможно, вам потребуется запускать нужные команды под пользователем с достаточными привилегиями.

  2. Проверка конфигурации Docker:

    • Убедитесь, что конфигурация Docker на вашем сервере позволяет использование привилегированных контейнеров и монтирование устройств.
    • Рассмотрите возможность настройки параметров безопасности SELinux или AppArmor, если они используются, которые могут ограничивать доступ к устройствам.
  3. Логирование и отладка: Используйте диагностические команды, такие как dmesg или docker logs, чтобы получить дополнительную информацию о возможных ошибках и проблемах, связанных с доступом к устройствам.

  4. Конструкция образа: Если вы планируете выполнять такие операции часто, подумайте о том, чтобы создать кастомизированный Docker-образ, в который уже будут интегрированы нужные настройки и утилиты, что облегчит повторное использование.

Следуя этим рекомендациям, вы сможете устранить проблему с недоступностью устройств в вашем Docker контейнере на сервере сборки. Надеюсь, это поможет вам решить вашу задачу!

Оцените материал
Добавить комментарий

Капча загружается...