Назад | Перейти на главную страницу

Какова цель инструкции VOLUME в Dockerfile?

В документации говорится, что инструкция VOLUME создает точку крепления, но я создал изображение, используя

FROM alpine
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting

и я смог смонтировать / myvol или любой другой путь в файловой системе контейнеров, используя docker run -v vol:/myvol myimage и смог увидеть данные в / var / lib / docker / vol / _data на хост-машине.

Какая разница добавила бы VOLUME myvol в Dockerfile сделать?

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

С помощью директивы VOLUME в Dockerfile вы явно объявляете том, который контейнер, созданный из этого образа, предоставляет, даже если он не монтируется явно при создании контейнера во время создания контейнера - например, docker run -v <volume>:/data <image name>.

Вместо этого я могу иметь директиву в Dockerfile

FROM alpine

RUN mkdir /data && echo "Some data" > /data/mydata
VOLUME /data

Запустите контейнер из образа, созданного с помощью указанного выше файла Dockerfile:

docker run -ti --rm --name volume-test voltest

Осмотрите работающий контейнер

docker container inspect volume-test

...
        "Mounts": [
            {
                "Type": "volume",
                "Name": "c4d070456dfa65540bd5c75b958930837bbf4277f4a4169b791679127f29a73a",
                "Source": "/var/snap/docker/common/var-lib-docker/volumes/c4d070456dfa65540bd5c75b958930837bbf4277f4a4169b791679127f29a73a/_data",
                "Destination": "/data",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ]
...

Как видите, в каталог / data контейнера смонтирован том. Этот анонимный том был автоматически создан во время создания контейнера из-за директивы VOLUME в Dockerfile и поскольку контейнер был запущен с --rm вариант, он будет автоматически удален при остановке контейнера (при условии, что в это время его больше не будет использовать). Вы можете подтвердить это, используя docker volume ls после остановки контейнера.

Это позволяет использовать такие специальные тома из других контейнеров, например, монтировать их, запустив:

docker run --rm -ti --name alpine-vol --volumes-from volume-test alpine sh

Проверить /data directoy во вновь запущенном контейнере, он будет содержать данные исходного контейнера, записанные на том.

Я определенно вижу использование этого, когда данные должны быть разделены между контейнерами, но не должны сохраняться после удаления исходного контейнера (например, как часть шаблона sidecar). Если требуется постоянство данных, вы все равно можете явно подключить том в тот же каталог.

Очевидное использование VOLUME - заполнить новый постоянный том данными, предоставленными вашим контейнером. Независимо от того, какое приложение вы развертываете, почти всегда есть некоторые исходные данные, с которых вам нужно начать. В документация проясняет, что эта копия имеет место только при новом создании тома.