02.09.2020

Передача данных между контейнером Docker и хостом

С помощью контейнеров Docker вы и ваша компания может предлагать приложения и услуги в таких масштабах и с такой скоростью, о которых вы и не могли думать раньше. А поскольку развертывание контейнерных приложений происходит настолько просто, вы сможете невероятно сэкономить на скорости. Одна вещь, которую вы можете вскоре обнаружить (после знакомства с первыми шагами в мире Docker), заключается в том, что после развертывания ваши контейнеры оказываются несколько ограничены в том, как они могут сохранять и использовать данные. Ограничение лежит в пределах файловой системы контейнера. Контейнеры Docker используют Объединенную файловую систему (UFS), которая работает с серией слоев только для чтения, последний слой чтения-записи располагается на самом верхнем слое контейнера. Эта система отлично работает, когда контейнеру не нужно сохранять данные. Но когда вам нужно развернуть службу, которая требует возможности сохранять данные (например, приложение, которое работает с базой данных), что вы собираетесь делать?

Добро пожаловать в Volumes

Том Docker — это каталог (или коллекция файлов), который находится в файловой системе хоста и не является частью UFS контейнера. Именно внутри этих томов контейнеры способны сохранять свои данные. С помощью команды docker volume вы можете легко управлять томами, чтобы расширить ваши контейнеры далеко за пределы их основных возможностей. Давайте узнаем, как развернуть новый контейнер, включающий в себя том, прикрепленный к определенному каталогу на хосте, чтобы контейнер оставался синхронизированным с данными в томе. Я буду демонстрировать на Ubuntu Server 18.04, но процесс будет таким же (независимо от дистрибутива) на любой другой платформе, поддерживающей Docker. Я предположу, что Docker у вас уже установлен и готов к работе, подробнее о процессе его установки можно прочитать в серии инструкций.

Создание тома данных на хосте

Первым шагом необходимо создать новый каталог для размещения тома Docker. Для этого откройте окно терминала и введите команду:

mkdir ~/container-data

Необходимо убедиться, что вновь созданный каталог размещен в том месте, к которому пользователь Docker может получить доступ (с правами на чтение и запись). После того, как вы создали этот каталог, будьте готовы его подключить к контейнеру. Предположим, вы собираетесь развернуть контейнер, основанный на официальном образе Ubuntu, который содержит каталог с именем /data. Чтобы развернуть такой контейнер, который присоединяет внутренний каталог /data к тому в каталоге хоста ~/container-data, необходимо выполнить команду:

docker run -dit -P --name ubuntu-test -v ~/container-data:/data ubuntu

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

Как только команда завершится, вы получите идентификатор контейнера. Убедитесь, что вы запомнили первые четыре символа этого идентификатора, так как он понадобится вам для получения доступа к оболочке bash внутри контейнера.

root@serverspace:~# docker run -dit -P --name ubuntu-test -v ~/container-data:/data ubuntu
cca8b77142eb3610a9b4e53d5f2b8e50f264f56343487005739ddae650ac98e3

Теперь вы развернули контейнер, основанный на официальном образе Ubuntu, который включает каталог /data, монтирующийся на том хоста в ~/container-data.

Тестирование тома

Давайте проверим этот том. Если вы забыли идентификатор контейнера, выполните команду docker ps -a, чтобы увидеть его в списке.

Скриншот №1. Проверка тома

Получите доступ к вновь развернутому контейнеру с помощью команды:

docker attach ID

Где ID — это первые четыре символа развернутого контейнера. Теперь вы должны найти себя в оболочке bash контейнера.

Выполните команду ls /, и вы увидите каталог /data, добавленный в контейнер Ubuntu. Давайте создадим тестовый файл в этом каталоге с помощью команды:

touch /data/test

После создания этого тестового файла выйдите из оболочки bash контейнера введя команду

exit

Попав обратно в оболочку хоста введите команду

ls ~/container-data

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

Скриншот №2. Тестовый файл в каталоге

Вы только что развернули контейнер, который включает постоянное хранилище, через том на хосте.