Zacznę od przyznania, że jestem całkiem nowy w Docker i być może podchodzę do tego problemu z niewłaściwych założeń ... daj mi znać, jeśli tak jest. Widziałem wiele dyskusji na temat tego, w jaki sposób Docker jest przydatny do wdrożenia, ale nie ma przykładów, jak to się faktycznie robi.
Oto sposób, w jaki ja myślałem, że to zadziała:
- utwórz kontener danych, aby przechowywać niektóre trwałe dane na komputerze A.
- utwórz kontener aplikacji, który używa woluminów z kontenera danych
- wykonać trochę pracy, potencjalnie zmieniając dane w kontenerze danych
- zatrzymaj kontener aplikacji
- zatwierdzić i oznaczyć kontener danych
- wypchnij kontener danych do (prywatnego) repozytorium
- pociągnij i uruchom obraz z kroku 6 na maszynie B
- wybierz miejsce, w którym przerwałeś na maszynie B
Kluczowym krokiem tutaj jest krok 5, który, jak sądzę, zapisałby bieżący stan (w tym zawartość systemu plików). Następnie możesz wypchnąć ten stan do repozytorium i wyciągnąć go z innego miejsca, co daje nowy pojemnik, który jest zasadniczo identyczny z oryginałem.
Ale to nie działa w ten sposób. Zauważyłem, że albo krok 5 nie robi tego, co myślę, albo krok 7 (ciągnięcie i uruchamianie obrazu) „resetuje” kontener do stanu początkowego.
Złożyłem zestaw trzech obrazów Docker i kontenerów, aby to przetestować: kontener danych, program piszący, który zapisuje losowy ciąg do pliku w kontenerze danych co 30 sekund, oraz czytnik, który po prostu echo
określa wartość w danych plik kontenera i wyjścia.
Kontener danych
Utworzono za pomocą
docker run \
--name datatest_data \
-v /datafolder \
myrepository:5000/datatest-data:latest
Plik Docker:
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
Pisarz
Utworzono za pomocą
docker run \
--rm \
--name datatest_write \
--volumes-from datatest_data \
myrepository:5000/datatest-write:latest
Plik Docker:
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
Ten skrypt zapisuje losowy ciąg oraz datę / godzinę /datafolder/data.txt
w kontenerze danych.
Czytelnik
Utworzono za pomocą
docker run \
--rm \
--name datatest_read \
--volumes-from datatest_data \
myrepository:5000/datatest-read:latest
Plik Docker:
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 "-----"
Kiedy buduję i uruchamiam te kontenery, działają one dobrze i działają tak, jak się spodziewam:
Stop & Start na maszynie programistycznej:
- utwórz kontener danych
- uruchomić pisarza
- natychmiast uruchom czytnik, zobacz „brak danych tutaj!” wiadomość
- Poczekaj chwile
- uruchom czytnik, zobacz losowy ciąg
- zatrzymać pisarza
- zrestartuj pisarz
- uruchom czytnik, zobacz ten sam losowy ciąg
Ale zatwierdzanie i pchanie nie robi tego, czego oczekuję:
- utwórz kontener danych
- uruchomić pisarza
- natychmiast uruchom czytnik, zobacz „brak danych tutaj!” wiadomość
- Poczekaj chwile
- uruchom czytnik, zobacz losowy ciąg
- zatrzymać pisarza
- zatwierdzić i oznaczyć kontener danych za pomocą
docker commit datatest_data myrepository:5000/datatest-data:latest
- wypchnij do repozytorium
- usuń wszystkie pojemniki i utwórz je ponownie
W tym momencie spodziewałbym się uruchomić czytnik i zobaczyć ten sam losowy ciąg, ponieważ kontener danych został zatwierdzony, wypchnięty do repozytorium, a następnie odtworzony z tego samego obrazu w repozytorium. Jednak tak naprawdę to „brak danych tutaj!” wiadomość.
Czy ktoś może wyjaśnić, gdzie się mylę? Lub, alternatywnie, wskaż mi przykład, jak wdrażanie odbywa się za pomocą Dockera?
/bin/true
binarnego (ani żadnego innego)docker rm -v
polecenie dla ostatniego kontenera, aby również usunąć wolumin)Możesz również użyć kontenera danych dokera do wdrożenia kodu
Nie wiem, czy to dobra praktyka, ale robię to w ten sposób:
Możesz teraz przesuwać obraz i używać woluminów z itp.
źródło
COPY
lubADD
i utworzyć wolumin za pomocąVOLUME
pliku Docker.