Вопрос или проблема
Я пытаюсь создать образ виртуального диска в 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 ...
Дополнительные рекомендации
-
Проверка прав доступа: Убедитесь, что у вашего CI/CD процесса есть соответствующие права для работы с устройствами блоков. Возможно, вам потребуется запускать нужные команды под пользователем с достаточными привилегиями.
-
Проверка конфигурации Docker:
- Убедитесь, что конфигурация Docker на вашем сервере позволяет использование привилегированных контейнеров и монтирование устройств.
- Рассмотрите возможность настройки параметров безопасности SELinux или AppArmor, если они используются, которые могут ограничивать доступ к устройствам.
-
Логирование и отладка: Используйте диагностические команды, такие как
dmesg
илиdocker logs
, чтобы получить дополнительную информацию о возможных ошибках и проблемах, связанных с доступом к устройствам. -
Конструкция образа: Если вы планируете выполнять такие операции часто, подумайте о том, чтобы создать кастомизированный Docker-образ, в который уже будут интегрированы нужные настройки и утилиты, что облегчит повторное использование.
Следуя этим рекомендациям, вы сможете устранить проблему с недоступностью устройств в вашем Docker контейнере на сервере сборки. Надеюсь, это поможет вам решить вашу задачу!