Зачем эти псевдо-ФС
Не всё хранится на диске. Linux умеет:
- tmpfs - ФС в RAM, может swap'ить
- overlayfs - объединить две (или больше) ФС в одну view
- devtmpfs -
/devс динамическими node'ами - proc, sysfs - интерфейсы к ядру
tmpfs и overlayfs - две самые часто используемые в проде.
tmpfs - RAM-disk
Где встречается по дефолту
$ mount | grep tmpfs
tmpfs on /run type tmpfs (rw,nosuid,nodev,size=...)
tmpfs on /run/lock type tmpfs (rw,nosuid,nodev,noexec,relatime)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev,inode64)
tmpfs on /run/user/1000 type tmpfs (rw,nosuid,nodev,relatime,size=...)
Системные tmpfs:
| Mount | Зачем |
|---|---|
/run | состояние демонов после boot'а (PID-файлы, сокеты) |
/run/lock | lock-файлы |
/run/user/$UID | per-user runtime (X11/wayland, dbus, systemctl --user) |
/dev/shm | shared memory сегменты POSIX (shm_open) |
/tmp (часто) | временные файлы; на серверах часто на диске |
Создать свой tmpfs
sudo mount -t tmpfs -o size=2G,mode=1777 tmpfs /mnt/cache
Опции:
| Опция | Что |
|---|---|
size=N | максимум; default - 50% RAM |
nr_inodes=N | максимум inode |
mode=1777 | права на корень (1777 = sticky как /tmp) |
uid=, gid= | владелец |
noexec, nosuid, nodev | hardening |
huge=advise | использовать transparent huge pages |
В fstab:
tmpfs /mnt/cache tmpfs size=2G,mode=1777,noexec,nosuid,nodev 0 0
tmpfs vs ramfs
Старая ramfs - просто RAM, без swap, без size-limit. Опасна:
можно её заполнить и подвесить машину. Не используй - tmpfs
её заменяет на 100%.
tmpfs и swap
По дефолту tmpfs может попасть в [[swap|swap]]. Это плюс (не падает на ENOSPC при превышении RAM), и минус (медленнее). В контейнерах часто запрещают swap - тогда tmpfs ограничена RAM.
Файл в tmpfs не подгружается через page cache (он уже в RAM) -
чтение быстрое, но не "free": RES процессов не учитывает tmpfs.
Часто на 16GB-машине из-за tmpfs free -h показывает "доступно 8GB".
Когда использовать
- Build-кэши (
/tmpподcargo/go build- в разы быстрее на HDD) - Сессии веб-приложений
- Inter-process queues (но лучше unix-сокеты или shm POSIX)
- Тестовая ФС в CI - быстрая mkfs+mount без блочного устройства (но это уже не tmpfs, а loop+tmpfs)
overlayfs - слои
Идея
Берёшь две (или больше) директорий: одна - lower (read-only база), другая - upper (changes layer). Монтируешь их через overlayfs - получаешь merged: вид "lower + upper", где запись идёт в upper.
lower: /var/lib/docker/.../l1
├─ /etc/passwd
├─ /usr/bin/sh
upper: /var/lib/docker/.../diff
└─ /etc/passwd ← переписали
merged: /var/lib/docker/.../merged
├─ /etc/passwd ← из upper
└─ /usr/bin/sh ← из lower
- Чтение существующего файла - lower (если в upper нет)
- Запись существующего файла - copy-up в upper, потом запись в copy
- Удаление - whiteout marker в upper
- Создание директории - в upper
Mount
mount -t overlay overlay \
-o lowerdir=/lower,upperdir=/upper,workdir=/work \
/merged
- lowerdir - база (read-only); может быть несколько через
:(l1:l2:l3) - upperdir - changes; должен быть на той же ФС что workdir
- workdir - служебная пустая директория, нужна для атомарных операций
- lowerdir БЕЗ upper/work - read-only overlay (всё read-only)
Несколько lower:
mount -t overlay overlay \
-o lowerdir=/l1:/l2:/l3,upperdir=/up,workdir=/work /merged
Поиск файла идёт сверху вниз: l1 побеждает l2, l2 побеждает l3.
Где встречается
- Docker overlay2 storage driver - каждый image-слой = lower, container changes = upper
- podman, containerd - тот же overlayfs
- Live-ISO - read-only ISO как lower, tmpfs как upper
- OSTree / Fedora Silverblue / NixOS - immutable system
- systemd-sysext / confext - расширения системы поверх RO root'а
- CI build кэш - layers per-step
Ограничения
- Не nested без труда - lower не должен быть overlayfs
(на новых ядрах можно через
redirect_dir=on, но осторожно) - No NFS lower на старых ядрах (5.10+ работает)
- selinux/security-context - upper должен поддерживать xattr,
tmpfsего поддерживает с ядром 6+, раньше нужна была ext4/xfs - inode-номера меняются между lower и upper - ломает hardlink-deduplication
Команды и проверка
mount | grep overlay # все overlayfs-mount'ы
cat /proc/self/mounts | grep overlay
findmnt -t overlay
Внутри Docker контейнера /proc/self/mountinfo показывает все слои:
awk '$5=="/" { print $4 }' /proc/self/mountinfotmpfs + overlayfs = живой Live-USB
# / - read-only с ISO
mount -t squashfs -o ro /dev/sr0 /mnt/iso/
# tmpfs для изменений
mount -t tmpfs tmpfs /mnt/upper
mkdir /mnt/upper/data /mnt/upper/work
# Объединить
mount -t overlay overlay \
-o lowerdir=/mnt/iso,upperdir=/mnt/upper/data,workdir=/mnt/upper/work \
/mnt/merged
Изменения в /mnt/merged пишутся в RAM. После перезагрузки ISO
снова чистый.
Когда что-то пошло не так
tmpfs: Bad value for ...- неверная опция; на старых ядрах нетinode64илиhuge=.- tmpfs съел всю RAM, OOM - не указали
size=. Default 50% может вылиться в OOM при набивке. Всегдаsize=Nявно. - overlayfs
Invalid argument-lowerdirиupperdirна разных ФС, либоworkdirне пустой, либо отсутствует, либо нет xattr-поддержки на upper. Operation not supportedпри copy-up - upper-FS не поддерживает нужные xattr (старая или специфичная). Только ext4/xfs/btrfs/tmpfs(>=6.0).- Docker диск распух непонятно - удалённые файлы в верхнем слое
не освобождают место в нижнем (lower иммутабелен). Нужен
docker image pruneи пересборка. - Файл "пропал" после chown в overlayfs - copy-up прав может
отличаться от lower. Проверь
ls -lна обеих сторонах.