Модуль 9 / 18
Дані: volumes, bind mounts, tmpfs і backup
Зміст
1. Цілі та модель даних
Ви навчитеся обирати volume, bind mount або tmpfs, обмежувати доступ і перевіряти відновлення backup.
- writable layer належить контейнеру
- volume живе незалежно
- bind mount пов’язаний із host path
- tmpfs ефемерний
- backup підтверджується restore
2. Теорія: writable layer і mount
Root filesystem об’єднує read-only image layers із writable layer. Copy-on-write зручний для тимчасового state, але видаляється разом із контейнером.
Mount приховує image-файли у destination до відключення. Два набори даних автоматично не об’єднуються.
3. Теорія: volumes
Named volume — об’єкт Engine з ім’ям, driver, labels і mountpoint. Видалення контейнера не видаляє volume. Одночасний запис мають підтримувати застосунок і filesystem.
Внутрішній шлях local driver не є переносимим API; зовнішній driver успадковує властивості storage backend.
4. Теорія: bind mounts і права
Bind mount показує container наявний host path і прив’язує workload до машини. --mount повертає помилку для відсутнього source, а legacy -v може мовчки створити каталог.
Ядро перевіряє числові UID/GID; також діють SELinux/AppArmor labels. Без потреби запису використовуйте readonly.
5. Теорія: tmpfs
tmpfs не потрапляє до writable layer та очищується разом із контейнером. Він підходить для sockets, cache і тимчасових secrets, але не замінює secret manager.
Обмежуйте розмір: пам’ять враховується cgroup і може спричинити OOM; swap залежить від host policy.
6. Теорія: backup, RPO та RTO
Файлова копія під час активного запису може бути неузгодженою. Для database потрібен native dump/snapshot або quiesce, а не tar активного datadir.
Перевіряйте checksum і metadata, відновлюйте до нового volume. RPO задає допустиму втрату, RTO — час відновлення.
7. Методичні вказівки
- Класифікуйте path: immutable, persistent або ephemeral
- Віддавайте перевагу --mount
- Не монтуйте /, /etc або docker.sock
- Використовуйте readonly
- Плануйте UID/GID і LSM labels
- Не видаляйте volume до evidence та backup
- Регулярно тестуйте restore
8. Лабораторна робота
Доведіть різні життєві цикли та заборону запису.
docker volume create docker-m9-data
docker run --name docker-m9-writer --mount type=volume,src=docker-m9-data,dst=/data alpine:3.21 sh -c 'printf "persistent data\n" > /data/message.txt; sha256sum /data/message.txt'
docker rm docker-m9-writer
docker volume inspect docker-m9-data
docker run --rm --mount type=volume,src=docker-m9-data,dst=/data,readonly alpine:3.21 sh -c 'cat /data/message.txt; sha256sum /data/message.txt; if touch /data/forbidden 2>/dev/null; then exit 1; else echo read_only=enforced; fi'mkdir -p /tmp/docker-module-09/backup
printf 'host input\n' > /tmp/docker-module-09/input.txt
docker run --rm --mount type=bind,src=/tmp/docker-module-09,dst=/workspace alpine:3.21 sh -c 'stat -c "uid=%u gid=%g mode=%a" /workspace/input.txt; printf "container output\n" > /workspace/output.txt'
stat -c 'uid=%u gid=%g mode=%a path=%n' /tmp/docker-module-09/output.txt
docker run --rm --mount type=bind,src=/tmp/docker-module-09,dst=/workspace,readonly alpine:3.21 sh -c 'if touch /workspace/forbidden 2>/dev/null; then exit 1; else echo read_only=enforced; fi'docker run -d --name docker-m9-tmpfs --mount type=tmpfs,dst=/run/course,tmpfs-size=16m,tmpfs-mode=0700 alpine:3.21 sh -c 'printf "ephemeral\n" > /run/course/state; sleep 300'
docker inspect docker-m9-tmpfs --format '{{json .Mounts}}'
docker exec docker-m9-tmpfs sh -c 'cat /run/course/state; df -h /run/course; stat -c "mode=%a" /run/course'
docker rm -f docker-m9-tmpfs
docker run --rm --mount type=tmpfs,dst=/run/course alpine:3.21 sh -c 'test ! -e /run/course/state && echo new_tmpfs=empty'Створіть backup поза source volume і відновіть його окремо.
docker run --rm --mount type=volume,src=docker-m9-data,dst=/source,readonly --mount type=bind,src=/tmp/docker-module-09/backup,dst=/backup alpine:3.21 tar -C /source -czf /backup/data.tgz .
sha256sum /tmp/docker-module-09/backup/data.tgz
tar -tzf /tmp/docker-module-09/backup/data.tgz
docker volume create docker-m9-restore
docker run --rm --mount type=volume,src=docker-m9-restore,dst=/restore --mount type=bind,src=/tmp/docker-module-09/backup,dst=/backup,readonly alpine:3.21 tar -C /restore -xzf /backup/data.tgz
docker run --rm --mount type=volume,src=docker-m9-restore,dst=/data,readonly alpine:3.21 sha256sum /data/message.txtКритерій: checksum збігається, readonly забороняє запис, новий tmpfs порожній.
9. Діагностика даних і Permission denied
Спочатку перевірте context і Mounts. Не виправляйте проблему через --privileged або chmod 777.
docker volume inspect docker-m9-data
docker system df --verbose
df -h /var/lib/docker 2>/dev/null || true
findmnt /var/lib/docker 2>/dev/null || true
stat -c 'uid=%u gid=%g mode=%a path=%n' /tmp/docker-module-09 /tmp/docker-module-09/input.txt- inspect .Mounts: Type, Source, Destination, RW
- volume inspect: ім’я, driver, scope
- stat: UID/GID і mode
- df/findmnt: capacity та read-only state
- logs, events і LSM audit
10. Контроль і cleanup
- Чому writable layer не persistent?
- Volume чи bind mount?
- Чому --mount безпечніший за -v?
- Що приховує mountpoint?
- Як впливають UID/GID?
- Коли tar неузгоджений?
- Як tmpfs пов’язаний з OOM?
- Навіщо restore test?
docker rm -f docker-m9-tmpfs 2>/dev/null || true
docker volume rm docker-m9-data docker-m9-restore
rm -f /tmp/docker-module-09/backup/data.tgz /tmp/docker-module-09/input.txt /tmp/docker-module-09/output.txt
rmdir /tmp/docker-module-09/backup /tmp/docker-module-09
docker volume lsМодуль засвоєно, якщо ви обираєте правильний lifecycle і відтворювано відновлюєте дані до нового volume.