Как мне развернуть контейнер docker и связанный с ним контейнер данных, включая содержимое?

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

Вот как я мысль это сработало бы:

  1. создайте контейнер данных для хранения некоторых постоянных данных на компьютере A
  2. создайте контейнер приложения, который использует тома из контейнера данных
  3. проделайте некоторую работу, потенциально изменяя данные в контейнере данных
  4. остановите контейнер приложения
  5. зафиксируйте и пометьте контейнер данных тегом
  6. переместите контейнер данных в (частное) хранилище
  7. извлеките и запустите изображение с шага 6 на компьютере B
  8. продолжайте с того места, где вы остановились на машине B

Ключевым шагом здесь является шаг 5, который, как я думал, сохранит текущее состояние (включая содержимое файловой системы). Затем вы можете поместить это состояние в репозиторий и извлечь его откуда-нибудь еще, что даст вам новый контейнер, который по существу идентичен исходному.

Но, похоже, это так не работает. Что я нахожу, так это то, что либо шаг 5 не делает того, что я думаю, либо шаг 7 (вытягивание и запуск изображения) "сбрасывает" контейнер в исходное состояние.

Я собрал набор из трех образов и контейнеров Docker, чтобы проверить это: контейнер данных, средство записи, которое записывает случайную строку в файл в контейнере данных каждые 30 секунд, и средство чтения, которое просто echoвводит значение в файл контейнера данных и завершает работу.

Контейнер данных

Созданный с помощью

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.shRUN chmod 755 /usr/local/sbin/*.shCMD ["/usr/local/sbin/run.sh"]

run.sh

#!/bin/bashwhile :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 scriptsADD run.sh /run.shRUN chmod 0777 /run.shCMD ["/run.sh"]

run.sh:

#!/bin/bashecho "reading..."echo "-----"cat /datafolder/data.txtecho "-----"

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

Остановка и запуск на машине разработки:

  1. создайте контейнер данных
  2. запустите программу writer
  3. немедленно запустите программу чтения, увидите сообщение "здесь нет данных!"
  4. подождите немного
  5. запустите программу чтения, посмотрите случайную строку
  6. остановите писателя
  7. перезапустите программу записи
  8. запустите программу чтения, увидите ту же случайную строку

Но фиксация и подталкивание не делают того, чего я ожидаю:

  1. создайте контейнер данных
  2. запустите программу writer
  3. немедленно запустите программу чтения, увидите сообщение "здесь нет данных!"
  4. подождите немного
  5. запустите программу чтения, посмотрите случайную строку
  6. остановите писателя
  7. зафиксируйте и пометьте контейнер данных с помощью docker commit datatest_data myrepository:5000/datatest-data:latest
  8. переход к хранилищу
  9. удалите все контейнеры и воссоздайте их заново

На этом этапе я ожидал бы запустить программу чтения и увидеть ту же случайную строку, поскольку контейнер данных был зафиксирован, помещен в репозиторий, а затем воссоздан из того же изображения в репозитории. Однако то, что я на самом деле вижу, - это сообщение "здесь нет данных!".

Может кто-нибудь объяснить, где я здесь ошибаюсь? Или, в качестве альтернативы, укажите мне на пример того, как выполняется развертывание с помощью Docker?

У вас неверное предположение о том, как тома работают в docker. Я попытаюсь объяснить, как тома связаны с контейнерами docker и образами docker, и, надеюсь, различия между объемы данных и контейнеры объемов данных станет ясно.

Сначала давайте вспомним несколько определений

Изображения Docker

Образы Docker - это, по сути, объединенная файловая система + метаданные. Вы можете проверить содержимое файловой системы docker image union с помощью docker export команду, и вы можете проверить метаданные изображения docker с помощью docker inspect команда.

Объемы данных

из Руководство пользователя Docker:

Том данных - это специально выделенный каталог в одном или нескольких контейнерах, который обходит файловую систему Union, предоставляя несколько полезных функций для постоянных или совместно используемых данных.

Здесь важно отметить, что данный том (как каталог или файл, содержащий данные) можно использовать повторно, только если существует хотя бы один контейнер docker, использующий его. Образы Docker не имеют томов, у них есть только метаданные, которые в конечном итоге сообщают, где тома будут смонтированы в файловой системе union. Тома данных не являются частью файловой системы docker containers union, так где же они находятся? под /var/lib/docker/volumes на хосте docker (в то время как контейнеры хранятся под /var/lib/docker/containers).

Контейнеры объемов данных

В этом особом типе контейнера нет ничего особенного. Это просто остановленные контейнеры, использующие объем данных с единственной и уникальной целью - иметь по крайней мере один контейнер, использующий этот объем данных. Помните, что как только последний контейнер (запущенный или остановленный), использующий данный том данных, будет удален, этот том станет недоступным через запуск докера --volumes-from вариант.

Работа с контейнерами объемов данных

Как создать контейнер тома данных

Изображение, используемое для создания контейнера тома данных, не имеет значения, поскольку такой контейнер может оставаться остановленным и по-прежнему выполнять свое назначение. Итак, чтобы создать контейнер данных с именем datatest_data для тома в /datafolder вам нужно только бежать:

docker run --name datatest_data --volume /datafolder busybox true

Здесь base это имя изображения (удобно маленькое) и true это команда, которую мы предоставляем только для того, чтобы не видеть, как демон docker жалуется на отсутствующую команду. В любом случае, после того, как у вас есть остановленный контейнер с именем 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 1.9.0)

Docker 1.9.0 ввел новую команду docker volume который позволяет создавать тома :

docker volume create --name hello

Как читать с тома (начиная с Docker 1.9.0)

Допустим, вы создали том с именем hello с docker volume create --name hello, вы можете установить его в контейнер с -v вариант :

docker run -v hello:/data busybox ls /data

О фиксации и перемещении контейнеров

Теперь должно быть ясно, что, поскольку тома данных не являются частью контейнера (файловой системы union), передача контейнера для создания нового образа docker не сохранит никаких данных, которые были бы в томе данных.

Создание резервных копий томов данных

В руководстве пользователя docker есть хорошая статья о создание резервных копий томов данных.


Хорошая статья, реагирующая на объемы: http://container42.com/2014/11/03/docker-indepth-volumes/

Вы также можете использовать контейнер данных docker для развертывания кода

Я не знаю, хорошая ли это практика, но я делаю это так :

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 fileRUN echo "no data here!" > /data-image/data.txt# expose the data folder #VOLUME /datafolderENTRYPOINT cp -r /data-image/* /datafolder/

Теперь вы можете нажать на свое изображение и использовать volumes-from и т.д...