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

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

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

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

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

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

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

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

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

Создано с

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 на машине разработки:

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

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

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

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

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

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

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

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

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


Хорошая статья по объемам: 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/

Теперь вы можете протолкнуть свое изображение и использовать объемы и т. Д.