Jak wdrożyć kontener dokera i powiązany kontener danych, w tym zawartość?

18

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:

  1. utwórz kontener danych, aby przechowywać niektóre trwałe dane na komputerze A.
  2. utwórz kontener aplikacji, który używa woluminów z kontenera danych
  3. wykonać trochę pracy, potencjalnie zmieniając dane w kontenerze danych
  4. zatrzymaj kontener aplikacji
  5. zatwierdzić i oznaczyć kontener danych
  6. wypchnij kontener danych do (prywatnego) repozytorium
  7. pociągnij i uruchom obraz z kroku 6 na maszynie B
  8. 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 echookreś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:

  1. utwórz kontener danych
  2. uruchomić pisarza
  3. natychmiast uruchom czytnik, zobacz „brak danych tutaj!” wiadomość
  4. Poczekaj chwile
  5. uruchom czytnik, zobacz losowy ciąg
  6. zatrzymać pisarza
  7. zrestartuj pisarz
  8. uruchom czytnik, zobacz ten sam losowy ciąg

Ale zatwierdzanie i pchanie nie robi tego, czego oczekuję:

  1. utwórz kontener danych
  2. uruchomić pisarza
  3. natychmiast uruchom czytnik, zobacz „brak danych tutaj!” wiadomość
  4. Poczekaj chwile
  5. uruchom czytnik, zobacz losowy ciąg
  6. zatrzymać pisarza
  7. zatwierdzić i oznaczyć kontener danych za pomocą docker commit datatest_data myrepository:5000/datatest-data:latest
  8. wypchnij do repozytorium
  9. 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?

Kryten
źródło

Odpowiedzi:

22

Masz błędne założenie dotyczące działania woluminów w oknie dokowanym. Spróbuję wyjaśnić, w jaki sposób woluminy odnoszą się do kontenerów dokowanych i obrazów dokowanych, i mam nadzieję, że różnice między woluminami danych a kontenerami objętości danych staną się jasne.

Najpierw przypomnijmy sobie kilka definicji

Obrazy dokerów

Obrazy dokerów to zasadniczo system plików Unii + metadane. Za pomocą polecenia można sprawdzić zawartość systemu plików unii obrazu dokera, a za pomocą docker exportpolecenia można sprawdzić metadane obrazu dokera docker inspect.

Woluminy danych

z podręcznika użytkownika Docker :

Wolumin danych to specjalnie wyznaczony katalog w jednym lub kilku kontenerach, który omija system plików Unii, zapewniając kilka przydatnych funkcji dla trwałych lub współdzielonych danych.

Należy tutaj zauważyć, że dany wolumin (jako katalog lub plik zawierający dane) nadaje się do ponownego użytku tylko wtedy, gdy istnieje co najmniej jeden kontener dokujący go używający. Obrazy dokerów nie mają woluminów, mają tylko metadane, które ostatecznie wskazują, gdzie woluminy zostaną zamontowane w unijnym systemie plików. Woluminy danych nie są częścią systemu plików unii kontenerów dokerów, więc gdzie one są? under /var/lib/docker/volumesna hoście dokera (podczas gdy kontenery są przechowywane pod /var/lib/docker/containers).

Pojemniki objętości danych

Ten specjalny rodzaj pojemnika nie ma nic specjalnego. Są to po prostu zatrzymane kontenery korzystające z woluminu danych, których jedynym i niepowtarzalnym celem jest posiadanie co najmniej jednego kontenera korzystającego z tego woluminu danych. Pamiętaj, że jak tylko ostatni kontener (uruchomiony lub zatrzymany) korzystający z danego woluminu danych zostanie usunięty, wolumin ten stanie się nieosiągalny dzięki opcji uruchamiania dokera --volumes-from .

Praca z kontenerami woluminów danych

Jak utworzyć kontener woluminu danych

Obraz użyty do utworzenia kontenera woluminu danych nie ma znaczenia, ponieważ taki kontener może pozostać zatrzymany i nadal wypełniać swój cel. Aby utworzyć kontener danych o nazwie datatest_datadla woluminu /datafolder, wystarczy uruchomić:

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

Oto basenazwa obrazu (dogodnie mała) i truejest to polecenie, które udostępniamy, aby uniknąć sytuacji, w której demon dokera narzeka na brakujące polecenie. W każdym razie po zatrzymaniu kontenera o nazwie datatest_datawyłącznie w celu umożliwienia osiągnięcia tego woluminu z --volumes-fromopcjądocker run polecenia.

Jak czytać z kontenera woluminu danych

Znam dwa sposoby odczytywania woluminu danych: pierwszy odbywa się przez kontener. Jeśli nie możesz mieć powłoki w istniejącym kontenerze, aby uzyskać dostęp do tego woluminu danych, możesz uruchomić nowy kontener z--volumes-from opcją wyłącznie w celu odczytu tych danych.

Na przykład:

docker run --rm --volumes-from datatest_data busybox cat /datafolder/data.txt

Innym sposobem jest skopiowanie woluminu z /var/lib/docker/volumesfolderu. Możesz odkryć nazwę woluminu w tym folderze, sprawdzając metadane jednego z kontenerów za pomocą woluminu. Zobacz tę odpowiedź aby uzyskać szczegółowe informacje.

Praca z woluminami (od Docker 1.9.0)

Jak utworzyć wolumin (od Docker 1.9.0)

Docker 1.9.0 wprowadził nowe polecenie, docker volumektóre pozwala tworzyć woluminy:

docker volume create --name hello

Jak czytać z woluminu (od Docker 1.9.0)

Powiedzmy utworzony wolumin o nazwie helloz docker volume create --name hello, można zamontować go w pojemniku z -vopcji:

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

O popełnianiu i pchaniu pojemników

Teraz powinno być jasne, że ponieważ woluminy danych nie są częścią kontenera (unijnego systemu plików), zatwierdzenie kontenera do utworzenia nowego obrazu dokera nie utrwali żadnych danych, które byłyby w woluminie danych.

Tworzenie kopii zapasowych woluminów danych

Podręcznik użytkownika dokera zawiera przyjemny artykuł na temat tworzenia kopii zapasowych woluminów danych .


Dobre objętości reagowania artykułów: http://container42.com/2014/11/03/docker-indepth-volumes/

Thomasleveil
źródło
Wygląda na to, że „Obraz użyty do utworzenia kontenera woluminu danych nie ma znaczenia” nie jest całkiem poprawny. Po prostu spróbuj z obrazem „scratch”, który da ci „exec:„ true ”: nie znaleziono pliku wykonywalnego”
tcurdt
Pomimo tego błędu Twój kontener zostanie utworzony i spełni swoją rolę jako posiadacz wolumenu
Thomasleveil
1
Hm - może warto wtedy otworzyć na to problem.
tcurdt
nie, takie zachowanie jest oczekiwane, ponieważ obraz rysunkowy jest pustym obrazem, który i tak nie może mieć pliku /bin/truebinarnego (ani żadnego innego)
Thomasleveil,
1
Tylko jedna rzecz. Powiedziałeś, że „jak tylko ostatni kontener (uruchomiony lub zatrzymany) korzystający z danego woluminu danych zostanie usunięty, doker zniszczy ten wolumin danych z / var / lib / docker / woluminów.”, Ale tak naprawdę nie jest to prawda: wystarczy zobaczyć: docs.docker.com/userguide/dockervolumes ( Woluminy danych utrzymują się, nawet jeśli sam kontener zostanie usunięty. Musisz podać docker rm -vpolecenie dla ostatniego kontenera, aby również usunąć wolumin)
juanra
1

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:

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/

Możesz teraz przesuwać obraz i używać woluminów z itp.

jmny
źródło
Właśnie tego szukam, ale w zaakceptowanej odpowiedzi wyraźnie wspomniano, że nie można tego zrobić. Spróbuję teraz.
andho
1
Na drugi rzut oka zaakceptowana odpowiedź mówi, że woluminy (lub dane w nim zawarte) nie zostaną zatwierdzone, ale można dodać dane do kontenera za pomocą COPYlub ADDi utworzyć wolumin za pomocą VOLUMEpliku Docker.
andho