Что такое дисковый ввод-вывод при запуске контейнеров докеров с подключенными к хосту томами и как его уменьшить?

При запуске контейнера докеров с подключенными к хосту томами, оба из а также , на RHEL я наблюдаю большой объем дискового ввода-вывода (используя ) перед запуском контейнера. Ввод / вывод связан с процесс, и я могу явно увеличить или уменьшить количество операций ввода-вывода, монтируя или удаляя тома хоста. Если я не смонтирую хост-тома, контейнер запускается немедленно. Если я монтирую тома, которые покрывают большую часть файловой системы, ввод-вывод будет значительным, в моем случае около 20 ГБ, что занимает около трех минут до запуска контейнера. В некоторых случаях это вызывает оркестровка просто по таймауту.

Типичная команда запуска выглядит так

      docker run -it --rm --name my_container \
-v /host/app/src:/app:ro,z \                         # host volume defined here
-v my_ro_data:/data/read_only/files:ro,z \           # external named volume
-v /host/data/write:/data/container_output/files:z \ # another host volume
my/image:latest

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

      docker volume create \
--driver local \
--opt type=none \
--opt o=bind \
--opt device=/host/data/files \
my_ro_data

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

1 ответ

Несколько возможностей, и неясно, какая из них основана на вашем вопросе.

Если бы это была файловая система оверлея, это было бы неожиданно, поскольку для ее настройки нет копирования файлов. И это также не отражает ваше описание, поскольку это происходит только с томами, и у вас есть наложенная файловая система для каждого контейнера (при условии, что драйвер графа настроен на наложение).

Для демона докеров без root (dockerd не запущен как root) вы можете увидеть, как драйвер графа переключается на собственный, что означает, что он копирует файловую систему изображений для каждого уровня и контейнера, что очень дорого. Но вы оба заметили бы это при использовании большого количества дискового пространства и без томов.

С именованным томом, когда этот том пуст и создается контейнер с именованным томом, docker инициализирует именованный том содержимым образа. Сюда входят все файлы, разрешения, права собственности и другие метаданные. Этот шаг инициализации пропускается, если на именованном томе уже есть данные, а с хост-томами этого не происходит.

Если ваша проблема специфична для томов хоста, я могу думать только о том, что метки selinux установлены с параметром «z» на томе. В противном случае и именованные тома, и тома хоста по умолчанию являются монтированием привязки Linux, и это обычно очень быстрые операции.

Наконец, неясно, включает ли «до запуска контейнера» время, затрачиваемое приложением внутри контейнера на переход в состояние готовности. Чтобы отделить шаги докера от приложения внутри контейнера, измените приложение на что-то простое, например что приведет к немедленному выходу контейнера после создания. Если для выхода требуется 30 секунд, вы знаете, что докер работает медленно, но если он сразу переходит в завершенное состояние, проблема не связана с докером, и проблема в том, что вы запускаете внутри контейнера.

Другие вопросы по тегам