Работа с томами Docker

DockerBeginner
Практиковаться сейчас

Введение

В этой лабораторной работе вы научитесь управлять данными в контейнерах Docker с помощью томов (volumes). Тома Docker являются предпочтительным механизмом для обеспечения сохранности данных, создаваемых и используемых контейнерами. Данное руководство проведет вас через различные аспекты работы с томами, включая их создание, управление, совместное использование данных, а также процессы резервного копирования и восстановления. К концу занятия вы будете четко понимать, как эффективно организовать хранение данных в среде Docker.

Понимание вариантов хранения данных в Docker

Прежде чем мы перейдем к практике, важно разобраться в различных вариантах хранения данных, которые предлагает Docker. Существует три основных способа:

  1. Volumes (Тома): Рекомендуемый механизм для постоянного хранения данных.
  2. Bind mounts (Привязочное монтирование): Связывание конкретного пути на хост-машине с контейнером.
  3. tmpfs mounts: Временное хранение данных в оперативной памяти хост-машины.

В этой работе мы сосредоточимся в основном на томах, так как они являются наиболее гибким и рекомендуемым вариантом для управления данными.

Для начала давайте выведем список текущих томов в вашей системе:

docker volume ls

Вы увидите вывод, похожий на этот:

DRIVER    VOLUME NAME
local     jenkins-data

Эта команда показывает все тома Docker в системе. В выводе указан драйвер тома (обычно «local») и его имя. Вы можете увидеть уже существующие тома или пустой список, если ранее ничего не создавали.

Не беспокойтесь, если имена томов отличаются или список пуст. Это нормально и зависит от того, какие операции с Docker выполнялись в системе ранее.

Создание и управление именованными томами

Теперь давайте создадим новый именованный том. Именованный том — это том, который вы создаете явно и которому присваиваете конкретное имя. Это упрощает обращение к нему и управление им в дальнейшем.

Выполните следующую команду для создания тома:

docker volume create my_data

Эта команда создает новый том с именем my_data. Docker сам позаботится о том, где и как этот том будет храниться в вашей хост-системе.

Убедимся, что том был создан:

docker volume ls

Теперь в списке должен появиться my_data вместе с другими томами, если они были.

Чтобы получить более подробную информацию о томе, воспользуемся командой инспекции:

docker volume inspect my_data

Вывод будет выглядеть примерно так:

[
  {
    "CreatedAt": "2024-08-22T14:31:09+08:00",
    "Driver": "local",
    "Labels": {},
    "Mountpoint": "/var/lib/docker/volumes/my_data/_data",
    "Name": "my_data",
    "Options": {},
    "Scope": "local"
  }
]

Этот вывод сообщает нам несколько важных вещей:

  • Дата и время создания.
  • Используемый драйвер (в данном случае local).
  • Точка монтирования (Mountpoint) — фактическое место на диске хост-системы, где хранятся данные.
  • Имя, которое мы присвоили.

Не переживайте, если сейчас не все детали понятны. Самые важные поля для нас — это Name и Mountpoint.

Использование томов в контейнерах

Теперь, когда у нас есть том, давайте подключим его к контейнеру. Мы запустим новый контейнер и смонтируем в него наш том.

Выполните команду:

docker run -d --name my_container -v my_data:/app/data ubuntu:latest sleep infinity

Разберем параметры этой команды:

  • docker run: Запуск нового контейнера.
  • -d: Запуск в фоновом режиме (detached mode).
  • --name my_container: Присвоение контейнеру имени для удобства обращения.
  • -v my_data:/app/data: Монтирование тома my_data в директорию /app/data внутри контейнера.
  • ubuntu:latest: Образ, на основе которого создается контейнер.
  • sleep infinity: Команда, которую будет выполнять контейнер, чтобы он не завершал работу сразу.

Теперь контейнер запущен с подключенным томом. Давайте создадим какие-нибудь данные внутри этого тома:

docker exec my_container sh -c "echo 'Hello from Docker volume' > /app/data/test.txt"

Что здесь происходит:

  • docker exec: Выполнение команды в уже запущенном контейнере.
  • my_container: Имя нашего контейнера.
  • sh -c "...": Запуск командной оболочки внутри контейнера для выполнения строки команд.
  • Сама команда создает файл test.txt в нашем томе с текстом «Hello from Docker volume».

Чтобы убедиться, что данные записаны, прочитаем этот файл:

docker exec my_container cat /app/data/test.txt

Вы должны увидеть сообщение «Hello from Docker volume» в консоли.

Совместное использование данных между контейнерами

Одним из главных преимуществ томов Docker является возможность совместного использования данных несколькими контейнерами. Создадим второй контейнер, использующий тот же том:

docker run -d --name another_container -v my_data:/app/shared_data ubuntu:latest sleep infinity

Эта команда почти идентична предыдущей, но мы дали контейнеру другое имя и смонтировали том по другому пути внутри контейнера.

Теперь проверим, имеет ли этот новый контейнер доступ к данным, созданным ранее:

docker exec another_container cat /app/shared_data/test.txt

Вы увидите то же самое сообщение «Hello from Docker volume». Это доказывает, что оба контейнера работают с одними и теми же данными.

Добавим еще немного данных из этого нового контейнера:

docker exec another_container sh -c "echo 'Data from another container' >> /app/shared_data/test.txt"

Эта команда добавляет новую строку в файл test.txt.

Теперь, если мы проверим содержимое файла из любого контейнера, мы увидим обе строки:

docker exec my_container cat /app/data/test.txt

В выводе должны появиться и «Hello from Docker volume», и «Data from another container».

Это демонстрирует, как тома Docker могут использоваться для обмена данными между контейнерами, что крайне полезно для многих архитектур приложений.

Резервное копирование и восстановление томов

Резервное копирование и восстановление томов Docker критически важно для сохранности данных. Рассмотрим этот процесс:

Сначала нам нужно остановить и удалить контейнеры, использующие том. Это необходимо, так как том нельзя удалить, пока он используется:

docker stop my_container another_container
docker rm my_container another_container

Теперь создадим резервную копию нашего тома:

docker run --rm -v my_data:/source:ro -v $(pwd):/backup ubuntu tar cvf /backup/my_data_backup.tar -C /source .

Команда может показаться сложной, разберем её:

  • docker run --rm: Запустить временный контейнер и удалить его сразу после завершения работы.
  • -v my_data:/source:ro: Смонтировать наш том в режиме «только чтение» (read-only).
  • -v $(pwd):/backup: Смонтировать текущую рабочую директорию хоста в папку /backup контейнера.
  • ubuntu: Использовать образ Ubuntu.
  • tar cvf /backup/my_data_backup.tar -C /source .: Создать tar-архив с данными из тома.

Теперь удалим наш исходный том:

docker volume rm my_data

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

docker volume create my_restored_data
docker run --rm -v my_restored_data:/dest -v $(pwd):/backup ubuntu bash -c "tar xvf /backup/my_data_backup.tar -C /dest"

Это создаст новый том и извлечет в него содержимое бэкапа.

Проверим, что данные успешно восстановлены:

docker run --rm -v my_restored_data:/app/data ubuntu cat /app/data/test.txt

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

Резюме

В ходе этой лабораторной работы вы научились работать с томами Docker. Вы научились создавать именованные тома и управлять ими, подключать их к контейнерам, организовывать совместный доступ к данным между несколькими контейнерами, а также выполнять операции резервного копирования и восстановления. Эти навыки являются базовыми для эффективного управления данными в экосистеме Docker.

Основные выводы:

  • Тома Docker обеспечивают гибкий и эффективный способ управления постоянными данными в контейнерах.
  • Тома легко создавать, инспектировать и удалять с помощью команд Docker CLI.
  • Данные в томах могут быть доступны одновременно нескольким контейнерам.
  • Резервное копирование и восстановление томов критически важно для предотвращения потери данных и может быть выполнено с помощью стандартных команд Linux.

Продолжая работу с Docker, всегда уделяйте внимание вопросам сохранности и управления данными в ваших контейнеризированных приложениях. Всегда планируйте стратегии резервного копирования, особенно для продуктовых сред.