Что такое OverlayFS и как она используется в Docker?

Ответ

OverlayFS — это современная объединяющая файловая система (union filesystem), которая является стандартным драйвером хранения (storage driver) в Docker. Она позволяет эффективно объединять несколько директорий (слоёв) в единое представление, что лежит в основе работы Docker-образов и контейнеров.

Архитектура слоёв в Docker:

  1. lowerdir (нижние, read-only слои): Базовый образ (например, ubuntu:latest) и все слои из Dockerfile (RUN, COPY и т.д.). Эти слои общие для всех контейнеров, основанных на одном образе.
  2. upperdir (верхний, read-write слой): Уникальный для каждого контейнера слой, куда записываются все изменения (создание, модификация, удаление файлов) во время его жизни.
  3. merged: Единое виртуальное представление файловой системы контейнера, которое видит запущенный процесс.

Практический пример: При запуске контейнера docker run -it ubuntu bash Docker монтирует OverlayFS. Если внутри контейнера изменить файл из нижнего слоя, OverlayFS реализует механизм copy-on-write (CoW): файл копируется в upperdir, и изменения применяются уже к этой копии.

Проверка и отладка:

# Узнать, какой storage driver используется
docker info | grep "Storage Driver"
# Просмотреть информацию о слоях конкретного контейнера
docker inspect <container_id> --format='{{.GraphDriver.Data}}'

Преимущества для DevOps:

  • Экономия дискового пространства: Общие слои не дублируются.
  • Быстрый запуск контейнеров: Не нужно копировать весь образ.
  • Эффективное использование кэша сборки: Изменение в одном слое Dockerfile не требует пересборки предыдущих.

Ограничения и нюансы:

  • Работа с OverlayFS требует поддержки ядром (CONFIG_OVERLAY_FS).
  • Производительность операций, интенсивно использующих CoW (например, частые записи в большие файлы), может быть ниже, чем у нативных ФС. Для таких сценариев используют volumes.

Ответ 18+ 🔞

А, OverlayFS! Ну это ж, блядь, та самая хитрая жопа, на которой весь Docker и держится сейчас. Представь себе, как будто ты собираешь бутерброд из нескольких кусков хлеба, но только один кусок — свежий, а остальные лежат в общей тарелке для всех. Вот примерно так и работает эта файловая система, ёпта.

Что это за зверь такой? Это объединяющая файловая система, которая сейчас у всех в Docker по умолчанию стоит. Она из нескольких папок (слоёв) делает одну общую картинку, которую контейнер и видит. Без этого механизма каждый контейнер тащил бы за собой овердохуища одинаковых файлов.

Как это всё устроено внутри, на пальцах:

  1. lowerdir (нижние слои, только чтение): Это как общая библиотека. Твой базовый образ ubuntu и все команды из Dockerfile (RUN, COPY) лежат тут. Один раз скачал — и все контейнеры этим пользуются, не копируя.
  2. upperdir (верхний слой, чтение-запись): А вот это уже твой личный блокнот, который дали только тебе. Все изменения, которые делает конкретный контейнер (создал файл, удалил, поправил), пишутся сюда. Уникальный для каждой песочницы.
  3. merged: А это уже готовый бутерброд, который ты ешь. Виртуальная файловая система, где всё из lowerdir и upperdir слилось в одно целое. Процесс в контейнере видит именно её.

Практический пример, чтобы вообще всё стало ясно: Запускаешь ты docker run -it ubuntu bash. Внутри решил поправить системный файл, который был в образе. OverlayFS не будет трогать оригинал! Он сработает по принципу copy-on-write (CoW): тихо скопирует этот файл в твой личный upperdir и уже там даст тебе его почесать. Оригинал останется нетронутым для других. Умно, да?

Как посмотреть, что там творится под капотом, если не веришь:

# Глянуть, какой драйвер используется (скорее всего, overlay2)
docker info | grep "Storage Driver"
# А вот так можно разузнать про слои конкретного контейнера — где что лежит.
docker inspect <container_id> --format='{{.GraphDriver.Data}}'

Почему это круто для DevOps-инженера:

  • Место на диске не жрёт почём зря. Общие слои не дублируются. Представь, если у тебя 100 контейнеров на одном образе — экономия просто пиздец.
  • Контейнеры запускаются почти мгновенно. Не надо жевать и копировать гигабайты образа каждый раз.
  • Кэш сборки образов работает, как швейцарские часы. Изменил одну строку в Dockerfile — пересобирается только последний слой и те, что после него. Остальные берутся из кэша. Волнение ебать, как удобно.

Но и подводные камни есть, куда без них:

  • Ядро Linux должно эту фигню поддерживать (CONFIG_OVERLAY_FS). В старых дистрибутивах может быть затык.
  • Если твоё приложение постоянно и много пишет в файлы (базы данных, логи), то эта система CoW может начать тормозить, потому что каждый раз копирование. Для таких прожорливых зверей умные люди используют volumes — подключают внешние диски напрямую, в обход всех этих слоёв.