Работа с томами (Volumes) в Docker

Работа с томами (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

Выглядит это так:

Работа с томами/хранилищами (Volumes/Storages) в Docker

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»:

docker Preferences

Переходим во вкладку «Daemon». И во вкладке «Advanced» прописываем нужный сторедж, например:

docker preferences, advanced options

После добавляения:

{
  "debug" : true,
  "storage-driver" : "overlay2",
  "experimental" : true
}

Жмакаем на «Apply & Restart». Ждем пока докер перезапустится и можно проверить что вышло:

$ docker info | grep -E "Storage Driver"
Storage Driver: overlay2

Как видно с вывода — все работает.

У меня все, статья «Работа с томами (Volumes) в Docker» завершена.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.