Могу ли я использовать "mount" внутри контейнера Docker Alpine? - PullRequest
0 голосов
/ 15 сентября 2018

Я докеризую старый проект. Функция в проекте использует заданные пользователем репозитории Git, и, поскольку размер репо может привести к перегрузке системы хранения, я создал локальную систему хранения фиксированного размера, а затем смонтировал ее. Это было сделано, чтобы предотвратить переполнение файловой системы веб-хоста.

Общий подход таков:

IMAGE=filesystem/image.img
MOUNT_POINT=filesystem/mount
SIZE=20
PROJECT_ROOT=`pwd`

# Number of M to set aside for this filing system
dd if=/dev/zero of=$IMAGE bs=1M count=$SIZE &> /dev/null

# Format: the -F permits creation even though it's not a "block special device"
mkfs.ext3 -F -q $IMAGE

# Mount if the filing system is not already mounted
$MOUNTCMD | cut -d ' ' -f 3 | grep -q "^${PROJECT_ROOT}/${MOUNT_POINT}$"
if [ $? -ne 0 ]; then
    # -p Create all parent dirs as necessary
    mkdir -p $MOUNT_POINT
    /bin/mount -t ext3 $IMAGE $MOUNT_POINT
fi

Это прекрасно работает в локальной или удаленной виртуальной машине Linux. Однако я хотел бы запустить этот шелл-код или что-то в этом роде внутри контейнера. Одна из причин, по которой я хотел бы сделать это, состоит в том, чтобы содержать все ненужные вещи внутри контейнера, чтобы сборка нового хост-компьютера была максимально простой (на мой взгляд, настройка пользовательских монтировок и правил перезапуска cron хозяин работает против этого).

Итак, эта команда не работает внутри контейнера («файловая система» - это том Docker на хосте)

mount -t ext3 filesystem/image.img filesystem/mount
mount: can't setup loop device: No space left on device

Он также не работает с папкой контейнера («filesystem2» - это папка контейнера):

dd if=/dev/zero of=filesystem2/image.img bs=1M count=20
mount -t ext3 filesystem2/image.img filesystem2/mount
mount: can't setup loop device: No space left on device

Интересно, у контейнеров просто нет подходящего внутреннего оборудования для монтажа, и, следовательно, должен ли я изменить курс? Я бы предпочел не тратить на это слишком много времени (я просто перемещаю проект на сервер, использующий только Docker), поэтому я бы хотел, чтобы mount работал, если смогу.

Другие опции

Если это невозможно, то альтернативный том Docker, который работает как с Docker, так и с Swarm, может быть альтернативой, которую мне нужно рассмотреть. В Интернете существуют противоречивые сообщения о том, действительно ли это работает ( см. Этот вопрос ).

Здесь есть предложение о том, что это поддерживается во Flocker. Тем не менее, я не решаюсь воспользоваться этим, поскольку, как представляется, будет заброшено , предположительно пострадавшим от разорения ClusterHQ.

Этот пост указывает на то, что я могу использовать --storage-opt size=120G с docker run. Однако, похоже, что он не поддерживается docker service create (если, возможно, параметр не был переименован).

Обновление

Согласно комментарию convo, я добился определенного прогресса; Я обнаружил, что добавление --privileged к docker run позволяет монтировать за счет удаления изоляции безопасности. Полезный комментатор говорит, что лучше использовать более мелкозернистый элемент управления --cap-add SYS_ADMIN, позволяющий контейнеру сохранить часть своей изоляции.

Однако Docker Swarm еще не реализовал ни один из этих флагов, поэтому я не могу использовать это решение. Этот длительный запрос функции подсказывает мне, что эта функция не будет добавлена ​​в спешке; он ожидает уже два года.

Ответы [ 2 ]

0 голосов
/ 17 сентября 2018

Вы не сможете безопасно сделать это внутри контейнера. Docker удаляет привилегию монтирования из контейнеров, потому что с ее помощью вы можете смонтировать файловую систему хоста и покинуть контейнер. Однако вы можете сделать это вне контейнера и смонтировать файловую систему в контейнер как том, используя локальный драйвер по умолчанию. Параметр size не поддерживается большинством файловых систем, tmpfs является одним из немногих исключений. Большинство из них используют размер базового устройства, который вы определили с помощью команды создания файла образа:

dd if=/dev/zero of=filesystem/image.img bs=1M count=$SIZE

У меня были проблемы с установкой докера для динамического создания устройства цикла, поэтому вот процесс его создания вручную:

$ sudo losetup --find --show ./vol-image.img
/dev/loop0
$ sudo mkfs -t ext3 /dev/loop0
mke2fs 1.43.4 (31-Jan-2017)
Creating filesystem with 10240 1k blocks and 2560 inodes
Filesystem UUID: 25c95fcd-6c78-4b8e-b923-f808517b28df
Superblock backups stored on blocks:
        8193

Allocating group tables: done
Writing inode tables: done
Creating journal (1024 blocks): done
Writing superblocks and filesystem accounting information: done

При определении параметров монтирования тома передаются практически дословно из команды монтирования, которую вы запускаете в командной строке:

docker volume create --driver local --opt type=ext3 \
  --opt device=filesystem/image.img app_vol
docker service create --mount type=volume,src=app_vol,dst=/filesystem/mount ...

или в одной команде создания сервиса:

docker service create \
  --mount type=volume,src=app_vol,dst=/filesystem/mount,volume-driver=local,volume-opt=type=ext3,volume-opt=device=filesystem/image.img ...

С docker run команда выглядит так:

$ docker run -it --rm --mount type=volume,dst=/data,src=ext3vol,volume-driver=local,volume-opt=type=ext3,volume-opt=device=/dev/loop0 busybox /bin/sh
/ # ls -al /data
total 17
drwxr-xr-x    3 root     root          1024 Sep 19 14:39 .
drwxr-xr-x    1 root     root          4096 Sep 19 14:40 ..
drwx------    2 root     root         12288 Sep 19 14:39 lost+found

Единственным предварительным условием является создание этого файлового и зацикленного устройства перед созданием службы и доступ к этому файлу везде, где запланирована служба. Я бы также предложил сделать все пути в этих командах полностью определенными, а не относиться к текущему каталогу. Я почти уверен, что есть несколько мест, где относительные пути не работают.

0 голосов
/ 16 сентября 2018

Я нашел решение для ограничения размера, которым я доволен, и оно вообще не использует команду Linux mount. Я еще не реализовал это, но описанные ниже тесты достаточно удовлетворительны. Читатели могут пожелать отметить незначительные предупреждения в конце.

Я не пробовал монтировать тома Docker до того, как задавать этот вопрос, так как часть моего исследования наткнулась на постер Stack Overflow, ставящий под сомнение возможность создания томов Docker с учетом ограничения размера. Мой тест показывает, что они могут, но вы можете проверить это на своей собственной платформе, чтобы убедиться, что она работает для вас.

ограничение размера контейнера Docker

Приведенные ниже команды собраны из различных источников в сети.

Начнем с того, что я создаю том, например, с ограничением размера 20 м:

docker volume create \
    --driver local \
    --opt o=size=20m \
    --opt type=tmpfs \
    --opt device=tmpfs \
    hello-volume

Затем я создаю сервис Alpine Swarm с монтированием в этом контейнере:

docker service create \
    --mount source=hello-volume,target=/myvol \
    alpine \
    sleep 10000

Мы можем убедиться, что контейнер смонтирован, установив оболочку на один контейнер в этом сервисе:

docker exec -it amazing_feynman.1.lpsgoyv0jrju6fvb8skrybqap
/ # ls - /myvol
total 0

ОК, отлично. Итак, оставаясь в этой оболочке, давайте попробуем медленно перегружать этот диск с шагом 5 м. Мы видим, что он терпит неудачу с пятой попытки, чего мы и ожидали:

/ # cd /myvol
/myvol # ls
/myvol # dd if=/dev/zero of=image1 bs=1M count=5
5+0 records in
5+0 records out
/myvol # dd if=/dev/zero of=image2 bs=1M count=5
5+0 records in
5+0 records out
/myvol # ls -l
total 10240
-rw-r--r--    1 root     root       5242880 Sep 16 13:11 image1
-rw-r--r--    1 root     root       5242880 Sep 16 13:12 image2
/myvol # dd if=/dev/zero of=image3 bs=1M count=5
5+0 records in
5+0 records out
/myvol # dd if=/dev/zero of=image4 bs=1M count=5
5+0 records in
5+0 records out
/myvol # ls -l
total 20480
-rw-r--r--    1 root     root       5242880 Sep 16 13:11 image1
-rw-r--r--    1 root     root       5242880 Sep 16 13:12 image2
-rw-r--r--    1 root     root       5242880 Sep 16 13:12 image3
-rw-r--r--    1 root     root       5242880 Sep 16 13:12 image4
/myvol # dd if=/dev/zero of=image5 bs=1M count=5
dd: writing 'image5': No space left on device
1+0 records in
0+0 records out
/myvol # 

Наконец, давайте посмотрим, сможем ли мы получить ошибку, переполнив диск за один раз, в случае, если ограничение касается только вновь открытых файловых дескрипторов на полном диске:

/ # cd /myvol
/ # rm *
/myvol # dd if=/dev/zero of=image1 bs=1M count=21
dd: writing 'image1': No space left on device
21+0 records in
20+0 records out

Оказывается, мы можем, так что для меня это выглядит довольно здраво.

Nota bene

Том создается с type и device из «tmpfs», что звучит для меня тревожно, как RAM-диск. Я успешно проверил, что том остается подключенным и неповрежденным после перезагрузки системы, поэтому он выглядит хорошо для меня, по крайней мере, на данный момент.

Однако я бы сказал, что когда речь идет об организации ваших систем хранения данных, не просто копируйте то, что у меня есть. Прежде чем запускать его в производство, убедитесь, что том достаточно надежен для вашего случая использования, и, конечно, обязательно включите его в процесс резервного копирования.

(Это для Docker версии 18.06.1-ce, сборка e68fc7a).

...