Как реализуется распределение ресурсов в Docker
Что проверяют
Понимаете ли вы, что за флагами docker run стоят cgroups ядра, и чем лимит памяти отличается от лимита CPU по последствиям. Для ML-позиции почти всегда уточняют про GPU и про то, почему обучение падает в контейнере, хотя на хосте работало.
Как отвечать
Изоляцию дают namespaces, а ресурсы ограничивают cgroups (на современных дистрибутивах cgroups v2). Docker лишь выставляет их параметры:
- CPU:
--cpus=2задаёт квоту, контейнер получает не больше двух ядер процессорного времени, сверх этого его троттлят.--cpu-sharesэто относительный вес, он работает только при конкуренции за процессор.--cpuset-cpusпривязывает к конкретным ядрам; - память:
--memory=8gжёсткий предел. При превышении приходит OOM killer и убивает процесс, код выхода 137.--memory-swapзадаёт лимит памяти вместе со свопом; - GPU:
--gpus allили конкретные устройства через NVIDIA Container Toolkit, в Compose это блокdeploy.resources.reservations.devices; - разделяемая память: по умолчанию
/dev/shmвсего 64 МБ, иDataLoaderв PyTorch сnum_workers > 0падает с bus error. Лечится--shm-sizeили--ipc=host; - наблюдение:
docker statsв реальном времени, для истории cAdvisor и Prometheus.
Отдельно скажите, что код внутри не всегда видит лимит: os.cpu_count() возвращает число ядер хоста, а не квоту --cpus, и библиотека плодит лишние потоки BLAS или воркеров. Число потоков лучше задавать явно через OMP_NUM_THREADS или настройки фреймворка. В Kubernetes те же механизмы выражаются через requests и limits.
Где спотыкаются
Путают --cpus и --cpu-shares. Шары ничего не ограничивают, пока хост свободен, и сервис инференса внезапно замедляется, когда рядом стартует обучение.
Ставят лимит памяти без запаса под пиковую загрузку батча или модели. Контейнер тихо умирает с кодом 137, а в логах приложения нет ни строки, потому что процесс убило ядро.
Рассказывают про сети и тома как про «распределение ресурсов». Это конфигурация, а не лимиты: интервьюер ждёт cgroups, OOM, троттлинг и GPU.