Я начну с признания того, что я довольно новичок в Docker, и, возможно, я подхожу к этой проблеме, исходя из неправильного набора предположений... дайте мне знать, если это так. Я видел много дискуссий о том, как Docker полезен для развертывания, но никаких примеров того, как это делается на самом деле, нет.
Вот как я мысль это сработало бы:
- создайте контейнер данных для хранения некоторых постоянных данных на компьютере A
- создайте контейнер приложения, который использует тома из контейнера данных
- проделайте некоторую работу, потенциально изменяя данные в контейнере данных
- остановите контейнер приложения
- зафиксируйте и пометьте контейнер данных тегом
- переместите контейнер данных в (частное) хранилище
- извлеките и запустите изображение с шага 6 на компьютере B
- продолжайте с того места, где вы остановились на машине 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 "-----"
Когда я создаю и запускаю эти контейнеры, они работают нормально и работают так, как я ожидаю:
Остановка и запуск на машине разработки:
- создайте контейнер данных
- запустите программу writer
- немедленно запустите программу чтения, увидите сообщение "здесь нет данных!"
- подождите немного
- запустите программу чтения, посмотрите случайную строку
- остановите писателя
- перезапустите программу записи
- запустите программу чтения, увидите ту же случайную строку
Но фиксация и подталкивание не делают того, чего я ожидаю:
- создайте контейнер данных
- запустите программу writer
- немедленно запустите программу чтения, увидите сообщение "здесь нет данных!"
- подождите немного
- запустите программу чтения, посмотрите случайную строку
- остановите писателя
- зафиксируйте и пометьте контейнер данных с помощью
docker commit datatest_data myrepository:5000/datatest-data:latest
- переход к хранилищу
- удалите все контейнеры и воссоздайте их заново
На этом этапе я ожидал бы запустить программу чтения и увидеть ту же случайную строку, поскольку контейнер данных был зафиксирован, помещен в репозиторий, а затем воссоздан из того же изображения в репозитории. Однако то, что я на самом деле вижу, - это сообщение "здесь нет данных!".
Может кто-нибудь объяснить, где я здесь ошибаюсь? Или, в качестве альтернативы, укажите мне на пример того, как выполняется развертывание с помощью Docker?