Как найти volume контейнера

Use docker ps to get the container id.

Then:

docker inspect -f '{{ .Mounts }}' containerid

Example:

terminal 1

docker run -it -v /tmp:/tmp ubuntu:14.04 /bin/bash

terminal 2

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
ddb7b55902cc        ubuntu:14.04        "/bin/bash"         About a minute ago   Up About a minute                       distracted_banach   

$ docker inspect -f "{{ .Mounts }}" ddb7
map[/tmp:/tmp]

The output

map[/tmp:/tmp] 

is, apparently, due to the use of the Go language to implement the docker command tools.

The docker inspect command without the -f format is quite verbose. Since it is JSON you could pipe it to python or nodejs and extract whatever you needed.

paul@home:~$ docker inspect ddb7
[{
    "AppArmorProfile": "",
    "Args": [],
    "Config": {
        "AttachStderr": true,
        "AttachStdin": true,
        "AttachStdout": true,
        "Cmd": [
            "/bin/bash"
        ],
        "CpuShares": 0,
        "Cpuset": "",
        "Domainname": "",
        "Entrypoint": null,
        "Env": [
            "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
        ],
        "ExposedPorts": null,
        "Hostname": "ddb7b55902cc",
        "Image": "ubuntu:14.04",
        "MacAddress": "",
        "Memory": 0,
        "MemorySwap": 0,
        "NetworkDisabled": false,
        "OnBuild": null,
        "OpenStdin": true,
        "PortSpecs": null,
        "StdinOnce": true,
        "Tty": true,
        "User": "",
        "Volumes": null,
        "WorkingDir": ""
    },
    "Created": "2015-05-08T22:41:44.74862921Z",
    "Driver": "devicemapper",
    "ExecDriver": "native-0.2",
    "ExecIDs": null,
    "HostConfig": {
        "Binds": [
            "/tmp:/tmp"
        ],
        "CapAdd": null,
        "CapDrop": null,
        "ContainerIDFile": "",
        "Devices": [],
        "Dns": null,
        "DnsSearch": null,
        "ExtraHosts": null,
        "IpcMode": "",
        "Links": null,
        "LxcConf": [],
        "NetworkMode": "bridge",
        "PidMode": "",
        "PortBindings": {},
        "Privileged": false,
        "PublishAllPorts": false,
        "ReadonlyRootfs": false,
        "RestartPolicy": {
            "MaximumRetryCount": 0,
            "Name": ""
        },
        "SecurityOpt": null,
        "VolumesFrom": null
    },
    "HostnamePath": "/var/lib/docker/containers/ddb7b55902cc328612d794570fe9a936d96a9644411e89c4ea116a5fef4c311a/hostname",
    "HostsPath": "/var/lib/docker/containers/ddb7b55902cc328612d794570fe9a936d96a9644411e89c4ea116a5fef4c311a/hosts",
    "Id": "ddb7b55902cc328612d794570fe9a936d96a9644411e89c4ea116a5fef4c311a",
    "Image": "ed5a78b7b42bde1e3e4c2996e02da778882dca78f8919cbd0deb6694803edec3",
    "MountLabel": "",
    "Name": "/distracted_banach",
    "NetworkSettings": {
        "Bridge": "docker0",
        "Gateway": "172.17.42.1",
        "GlobalIPv6Address": "",
        "GlobalIPv6PrefixLen": 0,
        "IPAddress": "172.17.0.4",
        "IPPrefixLen": 16,
        "IPv6Gateway": "",
        "LinkLocalIPv6Address": "fe80::42:acff:fe11:4",
        "LinkLocalIPv6PrefixLen": 64,
        "MacAddress": "02:42:ac:11:00:04",
        "PortMapping": null,
        "Ports": {}
    },
    "Path": "/bin/bash",
    "ProcessLabel": "",
    "ResolvConfPath": "/var/lib/docker/containers/ddb7b55902cc328612d794570fe9a936d96a9644411e89c4ea116a5fef4c311a/resolv.conf",
    "RestartCount": 0,
    "State": {
        "Error": "",
        "ExitCode": 0,
        "FinishedAt": "0001-01-01T00:00:00Z",
        "OOMKilled": false,
        "Paused": false,
        "Pid": 6115,
        "Restarting": false,
        "Running": true,
        "StartedAt": "2015-05-08T22:41:45.367432585Z"
    },
    "Volumes": {
        "/tmp": "/tmp"
    },
    "VolumesRW": {
        "/tmp": true
    }
}
]

docker history <image name> will show the layers baked into an image. Unfortunately, docker history seems hobbled by its formatting and lack of options to choose what is displayed.

You can choose terse and verbose formats, via the —no-trunc flag.

$ docker history drpaulbrewer/spark-worker
IMAGE               CREATED             CREATED BY                                      SIZE
438ff4e1753a        2 weeks ago         /bin/sh -c #(nop) CMD [/bin/sh -c /spark/my-s   0 B
6b664e299724        2 weeks ago         /bin/sh -c #(nop) ADD file:09da603c5f0dca7cc6   296 B
f6ae126ae124        2 weeks ago         /bin/sh -c #(nop) MAINTAINER drpaulbrewer@eaf   0 B
70bcb3ffaec9        2 weeks ago         /bin/sh -c #(nop) EXPOSE 2222/tcp 4040/tcp 60   0 B
1332ac203849        2 weeks ago         /bin/sh -c apt-get update && apt-get --yes up   1.481 GB
8e6f1e0bb1b0        2 weeks ago         /bin/sh -c sed -e 's/archive.ubuntu.com/www.g   1.975 kB
b3d242776b1f        2 weeks ago         /bin/sh -c #(nop) WORKDIR /spark/spark-1.3.1    0 B
ac0d6cc5aa3f        2 weeks ago         /bin/sh -c #(nop) ADD file:b6549e3d28e2d149c0   25.89 MB
6ee404a44b3f        5 weeks ago         /bin/sh -c #(nop) WORKDIR /spark                0 B
c167faff18cf        5 weeks ago         /bin/sh -c adduser --disabled-password --home   335.1 kB
f55d468318a4        5 weeks ago         /bin/sh -c #(nop) MAINTAINER drpaulbrewer@eaf   0 B
19c8c047d0fe        8 weeks ago         /bin/sh -c #(nop) CMD [/bin/bash]               0 B
c44d976a473f        8 weeks ago         /bin/sh -c sed -i 's/^#s*(deb.*universe)$/   1.879 kB
14dbf1d35e28        8 weeks ago         /bin/sh -c echo '#!/bin/sh' > /usr/sbin/polic   701 B
afa7a164a0d2        8 weeks ago         /bin/sh -c #(nop) ADD file:57f97478006b988c0c   131.5 MB
511136ea3c5a        23 months ago                                                       0 B

Here’s a verbose example.

$ docker history --no-trunc=true drpaulbrewer/spark-worker
IMAGE                                                              CREATED             CREATED BY                                                                                                                                                                                                                                                                                                                                                                                                                        SIZE
438ff4e1753a60779f389a3de593d41f7d24a61da6e1df76dded74a688febd64   2 weeks ago         /bin/sh -c #(nop) CMD [/bin/sh -c /spark/my-spark-worker.sh]                                                                                                                                                                                                                                                                                                                                                                      0 B
6b664e29972481b8d6d47f98167f110609d9599f48001c3ca11c22364196c98a   2 weeks ago         /bin/sh -c #(nop) ADD file:09da603c5f0dca7cc60f1911caf30c3c70df5e4783f7eb10468e70df66e2109f in /spark/                                                                                                                                                                                                                                                                                                                            296 B
f6ae126ae124ca211c04a1257510930b37ea78425e31a273ea0b1495fa176c57   2 weeks ago         /bin/sh -c #(nop) MAINTAINER drpaulbrewer@eaftc.com                                                                                                                                                                                                                                                                                                                                                                               0 B
70bcb3ffaec97a0d14e93b170ed70cc7d68c3c9dfb0222c1d360a300d6e05255   2 weeks ago         /bin/sh -c #(nop) EXPOSE 2222/tcp 4040/tcp 6066/tcp 7077/tcp 7777/tcp 8080/tcp 8081/tcp                                                                                                                                                                                                                                                                                                                                           0 B
1332ac20384947fe1f15107213b675e5be36a68d72f0e81153d6d5a21acf35af   2 weeks ago         /bin/sh -c apt-get update && apt-get --yes upgrade     && apt-get --yes install sed nano curl wget openjdk-8-jdk scala     && echo "JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64" >>/etc/environment     && export MAVEN_OPTS="-Xmx2g -XX:MaxPermSize=512M -XX:ReservedCodeCacheSize=512m"     && ./build/mvn -Phive -Phive-thriftserver -DskipTests clean package     && chown -R spark:spark /spark     && mkdir /var/run/sshd   1.481 GB
8e6f1e0bb1b0b9286947d3a4b443cc8099b00f9670aab1d58654051e06f62e51   2 weeks ago         /bin/sh -c sed -e 's/archive.ubuntu.com/www.gtlib.gatech.edu/pub/' /etc/apt/sources.list > /tmp/sources.list && mv /tmp/sources.list /etc/apt/sources.list                                                                                                                                                                                                                                                                       1.975 kB
b3d242776b1f1f1ae5685471d06a91a68f92845ef6fc6445d831835cd55e5d0b   2 weeks ago         /bin/sh -c #(nop) WORKDIR /spark/spark-1.3.1                                                                                                                                                                                                                                                                                                                                                                                      0 B
ac0d6cc5aa3fdc3b65fc0173f6775af283c3c395c8dae945cf23940435f2785d   2 weeks ago         /bin/sh -c #(nop) ADD file:b6549e3d28e2d149c0bc84f69eb0beab16f62780fc4889bcc64cfc9ce9f762d6 in /spark/                                                                                                                                                                                                                                                                                                                            25.89 MB
6ee404a44b3fdd3ef3318dc10f3d002f1995eea238c78f4eeb9733d00bb29404   5 weeks ago         /bin/sh -c #(nop) WORKDIR /spark                                                                                                                                                                                                                                                                                                                                                                                                  0 B
c167faff18cfecedef30343ef1cb54aca45f4ef0478a3f6296746683f69d601b   5 weeks ago         /bin/sh -c adduser --disabled-password --home /spark spark                                                                                                                                                                                                                                                                                                                                                                        335.1 kB
f55d468318a4778733160d377c5d350dc8f593683009699c2af85244471b15a3   5 weeks ago         /bin/sh -c #(nop) MAINTAINER drpaulbrewer@eaftc.com                                                                                                                                                                                                                                                                                                                                                                               0 B
19c8c047d0fe2de7239120f2b5c1a20bbbcb4d3eb9cbf0efa59ab27ab047377a   8 weeks ago         /bin/sh -c #(nop) CMD [/bin/bash]                                                                                                                                                                                                                                                                                                                                                                                                 0 B
c44d976a473f143937ef91449c73f2cabd109b540f6edf54facb9bc2b4fff136   8 weeks ago         /bin/sh -c sed -i 's/^#s*(deb.*universe)$/1/g' /etc/apt/sources.list                                                                                                                                                                                                                                                                                                                                                          1.879 kB
14dbf1d35e2849a00c6c2628055030fa84b4fb55eaadbe0ecad8b82df65cc0db   8 weeks ago         /bin/sh -c echo '#!/bin/sh' > /usr/sbin/policy-rc.d                                                                                                                                                                                                                                                                                                                                                                               && echo 'exit 101' >> /usr/sbin/policy-rc.d    && chmod +x /usr/sbin/policy-rc.d                        && dpkg-divert --local --rename --add /sbin/initctl    && cp -a /usr/sbin/policy-rc.d /sbin/initctl    && sed -i 's/^exit.*/exit 0/' /sbin/initctl                        && echo 'force-unsafe-io' > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup                        && echo 'DPkg::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' > /etc/apt/apt.conf.d/docker-clean    && echo 'APT::Update::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' >> /etc/apt/apt.conf.d/docker-clean    && echo 'Dir::Cache::pkgcache ""; Dir::Cache::srcpkgcache "";' >> /etc/apt/apt.conf.d/docker-clean                        && echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/docker-no-languages                        && echo 'Acquire::GzipIndexes "true"; Acquire::CompressionTypes::Order:: "gz";' > /etc/apt/apt.conf.d/docker-gzip-indexes   701 B
afa7a164a0d215dbf45cd1aadad2a4d12b8e33fc890064568cc2ea6d42ef9b3c   8 weeks ago         /bin/sh -c #(nop) ADD file:57f97478006b988c0c68e5bf82684372e427fd45f21cd7baf5d974d2cfb29e65 in /                                                                                                                                                                                                                                                                                                                                  131.5 MB
511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158   23 months ago                                                                                                                                                                                                                                                                                                                                                                                                                                         0 B

I can list all containers with docker ps (-a), I can list all volumes with docker volumes ls, when I inspect a volume, I can see the name, driver and mountpoint, but not the container(s) it is being used by.

When I use docker inspect <container>, I can see the Mount data like this for example:

"Mounts": [
    {
        "Name": "centos_db_symfony",
        "Source": "/var/lib/docker/volumes/centos_db_symfony/_data",
        "Destination": "/var/lib/mysql",
        "Driver": "local",
        "Mode": "rw",
        "RW": true,
        "Propagation": "rprivate"
    },

so in theory, I could write a script that loops through all containers to match a specific volume by name. But I ran some containers through docker-compose, and didn’t bind a name (like now is possible in v2) to some volumes, so they show up like a sha256 in the docker volume ls list, like this:

DRIVER              VOLUME NAME
local               34009871ded5936bae81197247746b708c3ec9e9b9832b702c09736a90...etc
local               centos_data
local               centos_db_symfony

In this case 34009871ded5 (example) was created before I named the volume in docker-compose and centos_db_symfony after.

Question

When docker-compose.yml volume information is updated like in this case making the volume named and the information in docker inspect <container> is updated, is the history forever lost or can I find out which container a volume was used by? If so, is it also possible to restore an old volume like this?

Extra info

docker-compose version 1.6.0, build d99cad6
Docker version 1.10.2, build c3959b1

Хотите узнать, где находятся образы, контейнеры и тома Docker?

В типичной среде Linux образы Docker и данные контейнеров можно найти в:

/var/lib/docker/

Если на вашем сервере не хватает места, вам обязательно следует заглянуть в этот каталог.

В основном, все связанные с Docker сущности находятся в /var/lib/docker.

Но давайте рассмотрим его более конкретно, на примере образа и контейнера Alpine.

Примечание: Пожалуйста, обратите внимание, что эта информация предназначена только для образовательных целей. Манипуляции с каталогами/файлами Docker хост-системы никогда не рекомендуются. Команды docker и docker-compose всегда должны быть предпочтительным методом. Доступ к физически расположенным каталогам/файлам Docker должен осуществляться только в крайнем случае в чрезвычайных ситуациях.

Содержание

  1. Расположение образов Docker
  2. Определенные местоположения образов
  3. Расположение томов Docker
  4. /var/lib/docker/volumes/
  5. Тома Docker
  6. Монтирование на хосте
  7. Заключение

Расположение образов Docker

Всякий раз, когда вы используете команду docker pull или запускаете docker-compose up -d для подготовки запуска приложений, именно здесь хранятся образы на сервере Ubuntu:

/var/lib/docker/overlay2

Здесь Overlay2 является драйвером хранилища Docker по умолчанию в Ubuntu.

Вы можете подтвердить это, выполнив команду docker info и поискав Storage Driver:

...
Storage Driver: overlay2
...

Если оно отличается от вашего, значит, вы используете другой драйвер хранения для Docker.

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

Доступность драйвера хранилища зависит от поддержки ядра.

Определенные местоположения образов

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

Скажем, например, я извлек образ alpine с помощью команды docker pull alpine.

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

$ docker inspect alpine

После выполнения команды вы заметите три поля в подразделе Data в разделе GraphDriver:

...
        "GraphDriver": {
            "Data": {
                "MergedDir": "/var/lib/docker/overlay2/64c9c0cf8c9cfb0e2168071df0652a317d49f58a68fe86e4a9a9a525ab9e365e/merged",
                "UpperDir": "/var/lib/docker/overlay2/64c9c0cf8c9cfb0e2168071df0652a317d49f58a68fe86e4a9a9a525ab9e365e/diff",
                "WorkDir": "/var/lib/docker/overlay2/64c9c0cf8c9cfb0e2168071df0652a317d49f58a68fe86e4a9a9a525ab9e365e/work"
            },

...

Вышеуказанные каталоги – это физическое расположение данных вашего контейнера внутри хост-системы.

Помните большую директорию с хэш-именем: 64c9c0cf8c9cfb0e2168071df0652a317d49f58a68fe86e4a9a525ab9e365e из раздела Docker Images?

Каталог под ним называется diff, как вы можете видеть в разделе LowerDir после :, который теперь является точкой монтирования контейнера – полученной из базового образа UpperDir!

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

Итак, полный путь, который является общим между образом (MergedDir, UpperDir и WorkDir) и контейнером (точка монтирования LowerDir), следующий:

/var/lib/docker/overlay2/64c9c0cf8c9cfb0e2168071df0652a317d49f58a68fe86e4a9a9a525ab9e365e/

После присвоения контейнеру до уровня LowerDir цель образа является смежной, поэтому четыре поля выделяются и основываются на другом каталоге (с новым хэшем) из-за динамической природы последнего, который становится:

/var/lib/docker/overlay2/d734685e284c92bdcb6063ac292a48813f30f4b0b2dd6fa2882279c569e506a3/

Примечание: Процесс монтирования каталога из base-image в контейнер очень похож на то, как вы монтируете тома в Docker!

Расположение томов Docker

В отличие от образов и контейнеров Docker, физическое расположение томов довольно простое.

Тома располагаются по адресу:

/var/lib/docker/volumes/

Конкретные места расположения томов

В этом случае существует два типа томов.

Первый – обычные тома Docker, а второй – bind mounts.

Тома Docker

Если вы ищете местоположение определенных томов, вы можете сначала использовать команду docker volume ls и проверить имя или ID тома.

Например, я запустил контейнер alpine с помощью следующей команды с томом:

$ docker run -ti -d --name alpine-container -v test-data:/var/lib/app/content alpine

Теперь автоматически будет создан том с именем test-data.

Теперь давайте создадим файл test.md в этом месте:

~$ docker exec alpine-container sh -c "touch /var/lib/app/content/test.md"

Убедитесь, что файл действительно был создан:

$ docker exec -ti alpine-container sh
/ # ls /var/lib/app/content/
test.md
/ # exit

Когда вы запустите docker volume ls, в списке появится том с именем test-data:

$ docker volume ls
DRIVER    VOLUME NAME
local     d502589845f7ae7775474bc01d8295d9492a6c26db2ee2c941c27f3cac4449d1
local     e71ee3960cfef0a133d323d146a1382f3e25856480a727c037b5c81b5022cb1b
local     test-data

Наконец, вы можете подтвердить фактическое расположение файла на вашей хост-системе:

$ sudo ls -l /var/lib/docker/volumes/test-data/_data
total 0
-rw-r--r-- 1 root root 0 Oct  6 23:20 test.md

Поэтому путь для смонтированного тома всегда находится в каталоге с именем _data внутри соответствующего каталога тома.

Вы также можете проверить такие пути используя команду docker volume inspect с последующим указанием имени или ID тома и просмотрев параметр Mountpoint в выводе:

$ docker volume inspect test-data
[
    {
        "CreatedAt": "2021-10-06T23:20:20+05:30",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/test-data/_data",
        "Name": "test-data",
        "Options": null,
        "Scope": "local"
    }
]

Монтирование на хосте

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

$ mkdir /home/avimanyu/test-data
$ docker run -ti -d --name alpine-container -v /home/avimanyu/test-data:/var/lib/app/content alpine

В этом случае смонтированный том с именем test-data станет доступен на стороне контейнера как /var/lib/app/content.

Заключение

В этом кратком руководстве я использовал общий подход на базе Linux, чтобы показать физическое расположение образов Docker, контейнеров и томов, расположенных на вашем Linux-сервере (в данном случае Ubuntu 20.04) на уровне хоста.

Время на прочтение
5 мин

Количество просмотров 168K

В сегодняшней части перевода серии материалов о Docker мы поговорим о работе с данными. В частности — о томах Docker. В этих материалах мы постоянно сравнивали программные механизмы Docker с разными съедобными аналогиями. Не будем отходить от этой традиции и здесь. Данные в Docker пусть будут специями. В мире существует множество видов специй, а в Docker — множество способов работы с данными.

→ Часть 1: основы
→ Часть 2: термины и концепции
→ Часть 3: файлы Dockerfile
→ Часть 4: уменьшение размеров образов и ускорение их сборки
→ Часть 5: команды
→ Часть 6: работа с данными

Обратите внимание на то, что этот материал подготовлен с использованием движка Docker версии 18.09.1 и API версии 1.39.

Данные в Docker могут храниться либо временно, либо постоянно. Начнём с временных данных.

Временное хранение данные

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

По умолчанию файлы, создаваемые приложением, работающим в контейнере, сохраняются в слое контейнера, поддерживающем запись. Для того чтобы этот механизм работал, ничего специально настраивать не нужно. Получается дёшево и сердито. Приложению достаточно просто сохранить данные и продолжить заниматься своими делами. Однако после того как контейнер перестанет существовать, исчезнут и данные, сохранённые таким вот нехитрым способом.

Для хранения временных файлов в Docker можно воспользоваться ещё одним решением, подходящим для тех случаев, когда требуется более высокий уровень производительности, в сравнении с тем, который достижим при использовании стандартного механизма временного хранения данных. Если вам не нужно, чтобы ваши данные хранились бы дольше, чем существует контейнер, вы можете подключить к контейнеру tmpfs — временное хранилище информации, которое использует оперативную память хоста. Это позволит ускорить выполнение операций по записи и чтению данных.

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

Постоянное хранение данных

Существуют два способа, позволяющих сделать срок жизни данных большим срока жизни контейнера. Один из способов заключается в использовании технологии bind mount. При таком подходе к контейнеру можно примонтировать, например, реально существующую папку. Работать с данными, хранящимися в такой папке, смогут и процессы, находящиеся за пределами Docker. Вот как выглядят монтирование tmpfs и технология bind mount.

Монтирование tmpfs и bind mount

Минусы использования технологии bind mount заключаются в том, что её использование усложняет резервное копирование данных, миграцию данных, совместное использование данных несколькими контейнерами. Гораздо лучше для постоянного хранения данных использовать тома Docker.

Тома Docker

Том — это файловая система, которая расположена на хост-машине за пределами контейнеров. Созданием и управлением томами занимается Docker. Вот основные свойства томов Docker:

  • Они представляют собой средства для постоянного хранения информации.
  • Они самостоятельны и отделены от контейнеров.
  • Ими могут совместно пользоваться разные контейнеры.
  • Они позволяют организовать эффективное чтение и запись данных.
  • Тома можно размещать на ресурсах удалённого облачного провайдера.
  • Их можно шифровать.
  • Им можно давать имена.
  • Контейнер может организовать заблаговременное наполнение тома данными.
  • Они удобны для тестирования.

Как видите, тома Docker обладают замечательными свойствами. Давайте поговорим о том, как их создавать.

Создание томов

Тома можно создавать средствами Docker или с помощью запросов к API.

Вот инструкция в Dockerfile, которая позволяет создать том при запуске контейнера.

VOLUME /my_volume

При использовании подобной инструкции Docker, после создания контейнера, создаст том, содержащий данные, которые уже имеются в указанном месте. Обратите внимание на то, что если вы создаёте том с использованием Dockerfile, это не освобождает вас от необходимости указать точку монтирования тома.

Создавать тома в Dockerfile можно и используя формат JSON.

Кроме того, тома можно создавать средствами командной строки во время работы контейнера.

Работа с томами из командной строки

▍Создание тома

Создать самостоятельный том можно следующей командой:

docker volume create —-name my_volume

▍Выяснение информации о томах

Для того чтобы просмотреть список томов Docker, воспользуйтесь следующей командой:

docker volume ls

Исследовать конкретный том можно так:

docker volume inspect my_volume

▍Удаление тома

Удалить том можно так:

docker volume rm my_volume

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

docker volume prune

Перед удалением томов Docker запросит у вас подтверждение выполнения этой операции.

Если том связан с каким-либо контейнером, такой том нельзя удалить до тех пор, пока не удалён соответствующий контейнер. При этом, даже если контейнер удалён, Docker не всегда это понимает. Если это случилось — можете воспользоваться следующей командой:

docker system prune

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

Флаги —mount и —volume

Для работы с томами вам, при вызове команды docker, часто придётся пользоваться флагами. Например, для того чтобы создать том во время создания контейнера можно воспользоваться такой конструкцией:

docker container run --mount source=my_volume, target=/container/path/for/volume my_image

В давние времена (до 2017 года) популярен был флаг --volume. Изначально этот флаг (ещё им можно пользоваться в сокращённом виде, тогда он выглядит как -v) использовался для самостоятельных контейнеров, а флаг --mount — в среде Docker Swarm. Однако, начиная с Docker 17.06, флаг --mount можно использовать в любых сценариях.

Надо отметить, что при использовании флага --mount увеличивается объём дополнительных данных, которые приходится указывать в команде, но, по нескольким причинам, лучше использовать именно этот флаг, а не --volume. Флаг --mount — это единственный механизм, который позволяет работать с сервисами или указывать параметры драйвера тома. Кроме того, работать с этим флагом проще.

В существующих примерах команд, направленных на работу с данными в Docker, вы можете встретить множество примеров употребления флага -v. Пытаясь адаптировать эти команды для себя, учитывайте то, что флаги --mount и --volume используют различные форматы параметров. То есть, нельзя просто заменить -v на --mount и получить рабочую команду.

Главное различие между --mount и --volume заключается в том, что при использовании флага --volume все параметры собирают вместе, в одном поле, а при использовании --mount параметры разделяются.

При работе с --mount параметры представлены как пары вида ключ-значение, а именно, это выглядит как key=value. Эти пары разделяют запятыми. Вот часто используемые параметры --mount:

  • type — тип монтирования. Значением для соответствующего ключа могут выступать bind, volume или tmpfs. Мы тут говорим о томах, то есть — нас интересует значение volume.
  • source — источник монтирования. Для именованных томов это — имя тома. Для неименованных томов этот ключ не указывают. Он может быть сокращён до src.
  • destination — путь, к которому файл или папка монтируется в контейнере. Этот ключ может быть сокращён до dst или target.
  • readonly — монтирует том, который предназначен только для чтения. Использовать этот ключ необязательно, значение ему не назначают.

Вот пример использования --mount с множеством параметров:

docker run --mount type=volume,source=volume_name,destination=/path/in/container,readonly my_image

Итоги

Вот полезные команды, которыми можно пользоваться при работе с томами Docker:

  • docker volume create
  • docker volume ls
  • docker volume inspect
  • docker volume rm
  • docker volume prune

Вот список часто используемых параметров для --mount, применимых в команде вида docker run --mount my_options my_image:

  • type=volume
  • source=volume_name
  • destination=/path/in/container
  • readonly

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

Уважаемые читатели! Какие материалы о 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» завершена.

Понравилась статья? Поделить с друзьями:
  • Как составить структуру диплома
  • Как найти количество koh
  • Mass effect 2 как найти серого посредника
  • Как найти свой звук голоса
  • Как найти песню по мелодии через яндекс