null

Docker volumes

Как известно, docker контейнеры не предполагают какого-либо постоянного хранения данных, однако зачастую бывают такие ситуации, когда это необходимо. Для решения этих задач и предназначены docker volume.

Самый просто способ использования:

docker run -d \
--name my_db \
-p 5432:5432 \
-v /var/lib/postgresql/9.5/main \
postgres:9.5

В этом случае будет автоматически создан volume, в который будет смонтирована директория /var/lib/postgresql/9.5/main из контейнера. По умолчанию все volume находятся в директории /var/lib/docker/volumes.  Теперь наши данные будут сохранены на диске и не удалятся после перезапуска контейнера. Более того, даже после удаления контейнера volume со всеми данными останется существовать до его принудительного удаления.

Минусом данного способа является то, что название созданного volume будет совершенно нечитаемым.

Можно усовершенствовать данную команду, добавив туда имя volume:

docker run -d \
--name my_db \
-p 5432:5432 \
-v my_volume:/var/lib/postgresql/9.5/main \
postgres:9.5

Теперь у нас появился volume с именем my_volume, можем взглянуть на него командой docker inspect:

$ docker inspect my_volume
[
    {
        "CreatedAt": "2018-04-07T17:56:04+03:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/my_volume/_data",
        "Name": "my_volume",
        "Options": {},
        "Scope": "local"
    }
]

 

Также, если нам необходимо создать некую область, через которую несколько контейнеров могли бы обмениваться данными, например один контейнер сохраняет логи в /log, а другой берёт логи из /log и производит их некую обработку, мы можем воспользоваться ключом --volumes-from:

docker run -d --name log_prod -v /log log_producer:latest
docker run -d --name log_cons --volumes-from log_prod log_consumer:latest

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

 

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

docker run -it -v some_volume:/volume -v /tmp:/backup alpine \
    tar -cjf /backup/some_archive.tar.bz2 -C /volume ./

Данная команда сохранит содержимое some_volume в /tmp/some_archive.tar.bz2

docker run -it -v some_volume:/volume -v /tmp:/backup alpine \
    sh -c "rm -rf /volume/* /volume/..?* /volume/.[!.]* ; tar -C /volume/ -xjf /backup/some_archive.tar.bz2"

Данная команда, соответсвенно, восстановит volume из архива /tmp/some_archive.tar.bz2

Также важно упомянуть, что процессом создания volume можно управлять с помощью различных драйверов, указывая их в команде docker volume create. Это позволит создать, например, удалённое хранилище, к которому контейнеры будут обращаться по ssh. Подробнее про драйвера можно почтитать здесь https://docs.docker.com/storage/storagedriver/