Learning Platform
Глоссарий Troubleshooting
Урок 07.03 · 22 мин
Средний
dockerstorage-driveroverlay2btrfszfs

Storage drivers: overlay2, btrfs, zfs, vfs

Под капотом каждой команды docker run есть конкретная реализация union filesystem. На Linux это overlayfs (через storage driver overlay2), на macOS Docker Desktop крутит VM и тоже использует overlay2 внутри VM, на CI-runner’ах часто видим overlay2 или специальные drivers под btrfs/zfs если кто-то так настроил. Этот выбор влияет на производительность: время старта контейнера, скорость copy-up, износ диска.

В этом уроке: что такое storage driver, как узнать какой используется, что выбрать в каких случаях.


ext4 vs xfs vs btrfs vs zfs — когда какую

Концепция: storage driver

Docker отделяет логику слоёв от физического хранилища через абстракцию storage driver. Driver отвечает за:

  • Распаковку tar-blob’ов в директории
  • Создание union mount (overlay/btrfs subvolume/zfs filesystem)
  • Управление copy-up при записи
  • Очистку при docker rm

Все drivers реализуют один интерфейс, но разными низкоуровневыми механизмами.

Список основных drivers:

DriverТип FS под нимProduction-readyОсобенности
overlay2ext4, xfs (ftype=1)ДаDefault на Linux. Самый быстрый, наиболее проверенный.
btrfsbtrfsДаИспользует субволумы и снапшоты btrfs. Хорош для копий, но медленнее на запись.
zfszfsДаАналогично btrfs, но через ZFS. Требует ZFS на хосте, не везде доступен.
vfsлюбаяНет (testing only)Без union — просто копирует все слои. Очень медленно, много диска.
aufsлюбаяDeprecatedСтарый default до overlay2. Не используется в современных ядрах.
devicemapperblock deviceDeprecatedТонко-provisioned LVM. Был popular на RHEL/CentOS, теперь deprecated.
fuse-overlayfsлюбаяДа (rootless)Userspace-реализация для rootless Docker / Podman, медленнее.

Как узнать какой driver используется

$ docker info | grep -A 5 "Storage Driver"
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Using metacopy: false
  Native Overlay Diff: true
  userxattr: false

Что важно:

  • Storage Driver — имя драйвера.
  • Backing Filesystem — на какой fs лежит /var/lib/docker (extfs = ext4, xfs, btrfs).
  • Supports d_type — поддержка типа файла в dirent (нужна overlayfs). На xfs нужно создавать с mkfs.xfs -n ftype=1, иначе overlayfs не запустится.
  • Native Overlay Diff — оптимизация в современных ядрах.

На Docker Desktop / OrbStack значение будет тот же overlay2, но это говорит о состоянии Linux VM, не хоста (macOS/Windows). Из самого macOS нельзя «видеть» эту fs напрямую.


overlay2: default на Linux

overlay2 это рекомендованный driver для большинства случаев. Использует ядерный overlayfs, который мы разбирали в уроке 01.

Преимущества:

  • Очень быстрый старт контейнера (миллисекунды)
  • Эффективный layer sharing (один read-only слой на хосте независимо от количества контейнеров)
  • Низкая нагрузка на CPU (всё в ядре)
  • Хорошая поддержка inotify, fsync, всех POSIX-операций

Ограничения:

  • Файлы, изменённые в верхнем слое, копируются целиком (copy-up) — больно для больших файлов
  • Не поддерживает hardlinks между слоями (минорная проблема для редких сценариев)
  • rename(2) между слоями требует copy-up

Требования к backing filesystem:

  • ext4 работает из коробки.
  • xfs требует ftype=1 (создаётся при mkfs или через xfs_repair -t).
  • btrfs, zfs — overlay2 поверх них работает, но плохая идея (двойная union).
NOTE

Если ты на сервере с RHEL 7 / CentOS 7 — там был storage driver devicemapper по умолчанию (RHEL 8+ перешёл на overlay2). Если видишь его — нужно мигрировать: docker daemon просто использует разный backend, переключение требует docker stop + изменения /etc/docker/daemon.json + удаления /var/lib/docker/devicemapper.


btrfs и zfs: для специальных случаев

btrfs и zfs — copy-on-write filesystems на уровне самой файловой системы. Docker может использовать их встроенные механизмы (subvolumes для btrfs, datasets для zfs) вместо overlayfs.

Преимущества:

  • Instant clone при создании контейнера (snapshot subvolume — практически бесплатная операция)
  • Compression на уровне fs (zstd, lz4 — можно сжать слои на лету)
  • Checksumming — встроенная проверка целостности
  • Snapshots / send-receive — удобно для backup/restore слоёв

Недостатки:

  • btrfs не всегда стабилен в кучных-write workload (исторические репутационные проблемы — улучшилось в последние годы)
  • zfs не входит в mainline kernel (лицензия CDDL), нужно ставить отдельно (zfsutils-linux)
  • Производительность на write зависит от настроек и дополнительной нагрузки на CPU

Где использовать:

  • btrfs: домашняя dev-машина с btrfs, желание иметь snapshots контейнеров
  • zfs: NAS / storage сервер, на котором уже есть zfs pool, и Docker должен жить рядом
  • На обычном production-сервере — overlay2 + ext4/xfs, никаких сюрпризов

vfs: только для тестов

vfs (Virtual File System) — это не union filesystem. Он просто копирует все слои в отдельные директории при создании контейнера.

/var/lib/docker/vfs/dir/
├── layer-1/    # все файлы слоя 1
├── layer-2/    # все файлы слоёв 1 + 2 (дублирование!)
├── layer-3/    # все файлы слоёв 1 + 2 + 3
└── container-A/ # все файлы образа + контейнер

Запуск контейнера = cp -r всего образа в новую директорию. На образе 500MB и 10 контейнерах — 5GB на диске. Старт контейнера = секунды/десятки секунд вместо миллисекунд.

Почему vfs всё-таки существует? Потому что overlay2 не работает в некоторых nested-docker сценариях (Docker внутри Docker без правильного volume-mount для /var/lib/docker), и vfs — fallback, который работает «везде». Использовать его в продакшене НЕЛЬЗЯ.

Если на твоей машине storage driver vfs — это либо мисконфигурация, либо ты внутри nested-docker без правильного volume. На macOS Docker Desktop в редких случаях падает в vfs если что-то сломалось — лечится reset to factory defaults.

Storage drivers: trade-offs
overlay2default, fast, provenDefault на Linux. Самый быстрый старт контейнера, эффективный layer sharing, низкий CPU overhead. Используй везде где можно.
btrfs / zfssnapshot-friendlyЕсли хост уже на btrfs/zfs. Дают instant clones, compression, snapshot-based backup. Сложнее операционно.
fuse-overlayfsrootless modeUserspace overlayfs для rootless Docker и Podman. Работает без root, но медленнее ядерного overlay2 (~10-30% slowdown).
vfstesting onlyБез union: копирует слои целиком. Очень медленно, много диска. Только для тестирования или fallback в nested-docker.

Где живут слои

На Linux с overlay2:

$ sudo ls /var/lib/docker/overlay2/
a1b2c3d4...   # layer A
b2c3d4e5...   # layer B
c3d4e5f6...   # layer C
...

$ sudo ls /var/lib/docker/overlay2/a1b2c3d4.../
diff/       # фактическое содержимое слоя
lower       # текстовый файл с цепочкой нижних слоёв
link        # короткий ID для mount-параметров
work/       # служебная директория overlayfs

На macOS с Docker Desktop эти директории внутри Linux VM по пути ~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw — это disk image VM. Доступ только через саму VM.

На OrbStack аналогично — внутри Linux VM. OrbStack экономит место за счёт sparse files (disk image растёт по мере использования, в отличие от Docker Desktop где предварительно аллоцируется).

На Windows + WSL2 — внутри WSL2-дистрибутива (docker-desktop-data).

# Размер слоёв на Linux
sudo du -sh /var/lib/docker/overlay2 | head -1
# 12G  /var/lib/docker/overlay2

# Размер всех Docker-данных
sudo du -sh /var/lib/docker
# 18G  /var/lib/docker

Почему на mac/win всё внутри VM

Контейнеры это Linux-технология. Технически: namespaces, cgroups, overlayfs, seccomp — это ядерные фичи Linux. На macOS и Windows нет этих ядерных API (у Windows есть свои контейнеры через Hyper-V Containers, но это другая технология).

Docker Desktop и OrbStack крутят минимальную Linux VM (на macOS это VirtualBox/QEMU/Apple Virtualization Framework — зависит от версии). Внутри VM работает Docker daemon, который и использует overlay2.

Файлы хоста (bind mounts) пробрасываются в VM через специальные shared filesystem-протоколы:

  • Docker Desktop: gRPC FUSE (новый) или osxfs (старый, медленный)
  • OrbStack: virtio-fs (нативный, быстрый)
  • Rancher Desktop: 9P или sshfs

Это объясняет, почему на macOS bind-mount часто заметно медленнее, чем на Linux: данные идут через слой между VM и хостом.


Попробуй сам

Проверь конфигурацию своего Docker:

docker info | grep -A 10 "Storage Driver"

# Размеры на диске
docker system df

# Подробная информация
docker system df --verbose

# Список слоёв с их id (на Linux)
# sudo ls /var/lib/docker/overlay2/ | head -10

# Проверим, что overlayfs смонтирован для активного контейнера
docker run -d --name probe alpine:3.21 sleep 3600
docker inspect probe --format '{{.GraphDriver}}'
# {Data:map[LowerDir:/var/lib/docker/overlay2/.../diff:...
#               MergedDir:/var/lib/docker/overlay2/.../merged
#               UpperDir:/var/lib/docker/overlay2/.../diff
#               WorkDir:/var/lib/docker/overlay2/.../work]
#  Name:overlay2}

# Cleanup
docker rm -f probe

Если хочешь поэкспериментировать с другим driver — это требует изменения /etc/docker/daemon.json и пересоздания всех образов/контейнеров (нельзя на лету переключить). Не делай на dev-машине, где есть рабочие образы.


Проверка знанийKnowledge check
На production-сервере docker info показывает Storage Driver: vfs. Команда жалуется на медленный старт контейнеров (10+ секунд) и быстрое заполнение диска. В чём проблема и как исправить?
ОтветAnswer
vfs не использует union filesystem -- он копирует все слои образа целиком при создании контейнера. Это объясняет медленный старт (copy 500MB+ файлов) и быстрое заполнение диска (каждый контейнер занимает полный размер образа без шаринга). Исправление: переключить storage driver на overlay2. Шаги: docker stop всех контейнеров; в /etc/docker/daemon.json добавить {storage-driver: overlay2}; убедиться, что backing filesystem -- ext4 или xfs с ftype=1 (через docker info после рестарта); удалить /var/lib/docker/vfs/ (теряются все локальные образы и контейнеры -- нужен заранее push в registry); systemctl restart docker; docker pull нужных образов.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 4. Какой storage driver используется по умолчанию в Docker на современном Linux (Docker 28)?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 4