Я начну с признания, что я новичок в Docker и, возможно, подхожу к этой проблеме, исходя из неправильного набора предположений ... дайте мне знать, если это так. Я видел много обсуждений того, как Docker полезен для развертывания, но не видел примеров того, как это делается на самом деле.
Вот как я мысль это будет работать:
Ключевым шагом здесь является шаг 5, который, как я думал, сохранит текущее состояние (включая содержимое файловой системы). Затем вы можете отправить это состояние в репозиторий и вытащить его откуда-то еще, получив новый контейнер, который по сути идентичен оригиналу.
Но похоже, что это не так. Я обнаружил, что либо шаг 5 не выполняет то, что я думаю, либо шаг 7 (извлечение и запуск изображения) «сбрасывает» контейнер в исходное состояние.
Я собрал набор из трех образов и контейнеров Docker, чтобы проверить это: контейнер данных, модуль записи, который записывает случайную строку в файл в контейнере данных каждые 30 секунд, и устройство чтения, которое просто echo
es значение в файле контейнера данных и завершает работу.
Создано с
docker run \
--name datatest_data \
-v /datafolder \
myrepository:5000/datatest-data:latest
Dockerfile:
FROM ubuntu:trusty
# make the data folder
#
RUN mkdir /datafolder
# write something to the data file
#
RUN echo "no data here!" > /datafolder/data.txt
# expose the data folder
#
VOLUME /datafolder
Создано с
docker run \
--rm \
--name datatest_write \
--volumes-from datatest_data \
myrepository:5000/datatest-write:latest
Dockerfile:
FROM ubuntu:trusty
# Add script
#
ADD run.sh /usr/local/sbin/run.sh
RUN chmod 755 /usr/local/sbin/*.sh
CMD ["/usr/local/sbin/run.sh"]
run.sh
#!/bin/bash
while :
do
sleep 30s
NEW_STRING=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
echo "$NEW_STRING" >> /datafolder/data.txt
date >> /datafolder/data.txt
echo "wrote '$NEW_STRING' to file"
done
Этот скрипт записывает случайную строку и дату / время в /datafolder/data.txt
в контейнере данных.
Создано с
docker run \
--rm \
--name datatest_read \
--volumes-from datatest_data \
myrepository:5000/datatest-read:latest
Dockerfile:
FROM ubuntu:trusty
# Add scripts
ADD run.sh /run.sh
RUN chmod 0777 /run.sh
CMD ["/run.sh"]
run.sh:
#!/bin/bash
echo "reading..."
echo "-----"
cat /datafolder/data.txt
echo "-----"
Когда я создаю и запускаю эти контейнеры, они работают нормально и работают так, как я ожидал:
Stop & Start на машине разработки:
Но фиксация и нажатие не делают того, чего я ожидаю:
docker commit datatest_data myrepository:5000/datatest-data:latest
На этом этапе я ожидал бы запустить программу чтения и увидеть ту же самую случайную строку, поскольку контейнер данных был зафиксирован, помещен в репозиторий, а затем воссоздан из того же изображения в репозитории. Однако на самом деле я вижу "никаких данных здесь нет!" сообщение.
Может кто-нибудь объяснить, где я здесь ошибаюсь? Или, в качестве альтернативы, укажите мне пример того, как выполняется развертывание с помощью Docker?
Вы ошиблись в предположении, как работают тома в докере. Я попытаюсь объяснить, как объемы связаны с контейнерами докеров и образами докеров, и, надеюсь, различия между объемы данных и контейнеры томов данных станет ясно.
Образы Docker представляют собой объединение файловой системы и метаданных. Вы можете проверить содержимое файловой системы объединения образов докеров с помощью docker export
, и вы можете проверить метаданные образа докера с помощью docker inspect
команда.
из Руководство пользователя Docker:
Том данных - это специально назначенный каталог в одном или нескольких контейнерах, который обходит файловую систему Union и предоставляет несколько полезных функций для постоянных или общих данных.
Здесь важно отметить, что данный том (как каталог или файл, содержащий данные) можно повторно использовать, только если он существует хотя бы в одном контейнере докеров, который его использует. Образы Docker не имеют томов, у них есть только метаданные, которые в конечном итоге указывают, где тома будут смонтированы в файловой системе union. Тома данных не являются частью файловой системы объединения контейнеров докеров, так где же они? под /var/lib/docker/volumes
на хосте докеров (в то время как контейнеры хранятся в /var/lib/docker/containers
).
В этом особом контейнере нет ничего особенного. Это просто остановленные контейнеры, использующие том данных с единственной и уникальной целью - иметь хотя бы один контейнер, использующий этот том данных. Помните, что как только последний контейнер (запущенный или остановленный), использующий данный том данных, будет удален, этот том станет недоступным через докер запустить --volumes-from
вариант.
Образ, используемый для создания контейнера тома данных, не имеет значения, поскольку такой контейнер может оставаться остановленным и по-прежнему выполнять свое предназначение. Итак, чтобы создать контейнер данных с именем datatest_data
для тома в /datafolder
вам нужно только запустить:
docker run --name datatest_data --volume /datafolder busybox true
Вот base
имя изображения (удобно маленькое) и true
- это команда, которую мы предоставляем, чтобы не видеть, как демон докера жалуется на отсутствующую команду. В любом случае после того, как у вас есть остановленный контейнер с именем datatest_data
с единственной целью - позволить вам достичь этого объема с помощью --volumes-from
вариант docker run
команда.
Я знаю два способа чтения тома данных: первый - через контейнер. Если у вас нет оболочки в существующем контейнере для доступа к этому тому данных, вы можете запустить новый контейнер с --volumes-from
вариант с единственной целью чтения этих данных.
Например:
docker run --rm --volumes-from datatest_data busybox cat /datafolder/data.txt
Другой способ - скопировать том из /var/lib/docker/volumes
папка. Вы можете узнать имя тома в этой папке, проверив метаданные одного из контейнеров, использующих том. Видеть этот ответ для подробностей.
Docker 1.9.0 представил новую команду docker volume
что позволяет создавать объемы:
docker volume create --name hello
Допустим, вы создали том с именем hello
с участием docker volume create --name hello
, вы можете установить его в контейнер с -v
вариант:
docker run -v hello:/data busybox ls /data
Теперь должно быть ясно, что, поскольку тома данных не являются частью контейнера (объединенной файловой системы), фиксация контейнера для создания нового образа докера не сохранит никаких данных, которые были бы в томе данных.
В руководстве пользователя докера есть хорошая статья о создание резервных копий томов данных.
Хорошая статья по объемам: http://container42.com/2014/11/03/docker-indepth-volumes/
Вы также можете использовать контейнер данных докера для развертывания кода
Не знаю, хорошая ли это практика, но я делаю так:
FROM ubuntu:trusty
# make the data folder
#
RUN mkdir /data-image
# in my case, I have a
# ADD dest.tar /data-image/
#
# but to follow your example :
# write something to the data file
RUN echo "no data here!" > /data-image/data.txt
# expose the data folder
#
VOLUME /datafolder
ENTRYPOINT cp -r /data-image/* /datafolder/
Теперь вы можете протолкнуть свое изображение и использовать объемы и т. Д.