Работа с томами (Volumes) в Docker
Volumes — являются механизмом для сохранения данных, создаваемых и используемых Docker контейнерами (с хостевой машины на контейнер).
Надеюсь что у вас уже имеется докер на хостевой машине, если нет, вот полезные статьи:
Установка Docker на Debian/Ubuntu
Установка Docker на CentOS/RedHat/Fedora
Установка docker-compose в Unix/Linux
Запуск docker контейнеров в Unix/Linux
Установка docker machine в Unix/Linux
Настройка docker swarm кластера в Unix/Linux
Запуск GUI-приложения в Docker
Запустить bash/SSH в контейнере с Docker
Создание base image для docker в Unix/Linux
Создание docker контейнера в Unix/Linux
Остановить/Удалить все Docker контейнеры/images
Работа с сетью (Networking) в Docker
И так, приступим.
Работа с томами (Volumes) в Docker
Сейчас буду приводить наглядные примеры того, каким образом можно работать с волюмами, стореджами.
Создание Volumes в Docker
Чтобы создать Volume, выполните:
$ docker volume create --name http-custom-data http-custom-data
Проверим что имеется в докере:
$ docker volume ls
Или вывести только необходимый:
$ docker volume ls | grep http-custom-data local http-custom-data
Получим подробную инфу:
$ docker volume inspect http-custom-data
Создадим index.html файл:
my custom page from Volume
Скопируем созданный файл в волюму:
$ cp index.html /var/lib/docker/volumes/http-custom-data/_data/
Смотрим, есть ли файл:
$ ls -l /var/lib/docker/volumes/http-custom-data/_data/ total 4 -rw-r--r-- 1 root root 28 Oct 11 20:40 index.html
И запустим контейнер nginx:
$ docker run -d -P -v http-custom-data:/usr/share/nginx/html nginx b94feb29c143eea7900965706447151e96df86539312bdcea79b42952bae701a
Посмотрим какой порт юзает созданный контейнер:
$ docker port $(docker ps -lq) 80/tcp -> 0.0.0.0:32769
Дерним курл чтобы убедится что скопированные данные имеются в докере:
# curl 127.0.0.1:32769 my custom page from Volume
Собственно, что и требовалось доказать — все есть и работает должным образом.
Создание TMPFS Volumes в Docker
Рассмотрим пример создания TMPFS Volume (данные хранятся в RAM) следующим образом:
$ docker volume create --driver local \ --opt type=tmpfs \ --opt device=tmpfs \ --opt o=size=100m,uid=1000 \ foo
Создание BTRFS Volumes в Docker
Рассмотрим пример создания BTRFS Volume (данные хранятся на /dev/sda2 разделе) следующим образом:
$ docker volume create \ --driver local \ --opt type=btrfs \ --opt device=/dev/sda2 \ foo
Создание NFS Volumes в Docker
Рассмотрим пример создания NFS Volume (в удаленной части NFS) следующим образом:
$ docker volume create \ --driver local \ --opt type=nfs \ --opt o=addr=192.168.1.1,rw \ --opt device=:/path/to/dir \ foo
Монтирование Volumes с хостевой машины в контейнер.
Добавление Volum-ов в контейнер(ы) являются хорошим решением т.к при завершении жизни контейнера все ваши данные будут утеряны. Если ваш контейнер генерирует непостоянные данные, рассмотрите возможность использования монтирования tmpfs, чтобы избежать постоянного хранения данных в любом месте и увеличить производительность контейнера, избегая записи на перезаписываемый слой контейнера.
Рассмотрим пример:
$ docker run -d -p 127.0.0.1:8080:80 -v $(pwd):/var/www/html:ro httpd
Или вот еще примеры:
$ docker run --rm -v $(pwd):$(pwd) -w $(pwd) maven:3.3-jdk-8 clean package $ docker run -d -v /var/log/httpd:/var/log/httpd httpd $ docker run -d -v /var/log/tomcat:/usr/local/tomcat/logs tomcat $ docker run -d -v /data:/etc/mongo mongo
Монтирование tmpfs в Docker
Монтирование tmpfs является временным и сохраняется только в памяти хоста. Когда контейнер остановится, монтирование tmpfs будет удалено, и файлы, написанные там, не будут сохранены.
Ограничения монтирования tmpfs:
- Вы не можете шарить данные монтированием tmpfs между контейнерами.
- Эта функция доступна только в том случае, если вы используете Docker в Linux.
Пример запуска:
$ docker run -d -ti -p127.0.0.1:8282:8200 --name=vault_test --mount type=tmpfs,destination=/tmp vault:0.11.4
Выглядит это так:
Case #1. VOLUME в Dockerfile
Создадим докерфайл выглядит:
FROM nginx RUN echo "default page" > /usr/share/nginx/html/index.html VOLUME /usr/share/nginx/html/
Соберем:
$ docker build -t nginx_v:1 . ... Successfully built efdfe29e01fd Successfully tagged nginx_v:1
Проверим PRE-BUILT данные:
$ docker run -d -p80:80 nginx_v:1 $ curl localhost default page
Changing data:
$ docker exec $(docker ps -lq) \ sh -c 'echo changed page > /usr/share/nginx/html/index.html' $ curl localhost changed page
Остановим контейнер:
$ docker stop $(docker ps -lq)
Где мои данные?
$ docker inspect $(docker ps -lqa) | jq '.[]|.Mounts' [ { "Type": "volume", "Name": "395c2b4639c0a577ff25b379adc201e77a1cedbc5d50e91150149e1f51191182", "Destination": "/usr/share/nginx/html", "Driver": "local", "Mode": "", "RW": true, "Source": "/ var/lib/docker/volumes/395c2b4639c0...f51191182/_data", "Propagation": "" } ]
Чекаем:
$ cat /var/lib/docker/volumes/395c2b4639c0a577ff25b379adc201e77a1cedbc5d50e91150149e1f51191182/_data/index.html changed page
Удалим контейнер и поглядим что выйдет с данными:
$ docker rm $(docker ps -lqa) $ cat /var/lib/docker/volumes/395c2b4639c0a577ff25b379adc201e77a1cedbc5d50e91150149e1f51191182/_data/index.html changed page
Case #2. Создание Volume для контейнера
Запускаем контейнер вот так:
$docker run -d -p 80:80 -v /usr/share/nginx/html nginx $ curl localhost ... <title>Welcome to nginx!</title> ...
Находим куда смонтируется Volume:
$ docker inspect $(docker ps -lqa) | jq -r '.[]|.Mounts[] | .Source' /var/lib/docker/volumes/b6400a50ad0a0e8f11fa962cb99e7d2e425ac1654c4e4ea1376ae61a05e5dbc8/_data
Чекаем данные:
$ echo changed > $(docker inspect $(docker ps -lqa) | jq -r '.[]|.Mounts[] | .Source')/index.html $ curl localhost changed
Case #3. Шара данных между контейнерами
На 1-м контейнере, ранаем:
$ docker run -d -v /usr/share/nginx/html --name c1 nginx $ echo changed > $(docker inspect c1 | jq -r '.[]|.Mounts[] | .Source')/index.html
На 2-м контейнере, ранаем:
$ docker run --volumes-from c1 busybox cat /usr/share/nginx/html/index.html changed
Изменить storage driver для docker в Linux
Проверим что имеется:
$ docker info | egrep "(Cgroup|Storage) Driver" Storage Driver: overlay2 Cgroup Driver: cgroupfs
Можно выполнить настройку:
$ cat << EOF > /etc/docker/daemon.json { "exec-opts": [ "native.cgroupdriver=systemd" ], "storage-driver": "devicemapper" } EOF
Перезапускаем сервис:
# systemctl daemon-reload # systemctl restart docker.service
Ну и можно посмотреть что вышло:
# docker info | egrep "(Cgroup|Storage) Driver" Storage Driver: devicemapper Cgroup Driver: systemd
Изменить storage driver для docker в Mac OS X
Проверим что имеется:
$ docker info | egrep "(Cgroup|Storage) Driver" Storage Driver: overlay2 Cgroup Driver: cgroupfs
Я использую docker edge и по этому, приведу наглядный пример того, как можно поменять сторедж. Запускаем docker, переходим в «Preferences»:
Переходим во вкладку «Daemon». И во вкладке «Advanced» прописываем нужный сторедж, например:
После добавляения:
{ "debug" : true, "storage-driver" : "overlay2", "experimental" : true }
Жмакаем на «Apply & Restart». Ждем пока докер перезапустится и можно проверить что вышло:
$ docker info | grep -E "Storage Driver" Storage Driver: overlay2
Как видно с вывода — все работает.
У меня все, статья «Работа с томами (Volumes) в Docker» завершена.