Jak działają obrazy platformy Docker

Ukończone

Przypomnij sobie, że obraz kontenera staje się jednostką używaną do dystrybucji aplikacji. Wspomnieliśmy również, że kontener jest w ustandaryzowanym formacie używanym zarówno przez nasze zespoły deweloperów, jak i zespołów operacyjnych.

W tym miejscu przyjrzymy się różnicom między oprogramowaniem, pakietami i obrazami używanymi w platformie Docker. Znajomość różnic między tymi koncepcjami pomoże nam lepiej zrozumieć, jak działają obrazy platformy Docker.

Opiszemy również krótko role systemu operacyjnego działającego na hoście i w kontenerze.

Oprogramowanie spakowane w kontenerze

Oprogramowanie spakowane w kontenerze nie jest ograniczone do aplikacji, które tworzą nasi deweloperzy. Kiedy mówimy o oprogramowaniu, mamy na myśli działające w kontenerze kod aplikacji, pakiety systemowe, pliki binarne, biblioteki, pliki konfiguracji i system operacyjny.

Załóżmy na przykład, że opracowujemy portal śledzenia zamówień dla różnych placówek firmy do użycia. Nasze aplikacje internetowe będą obsługiwane przez stos oprogramowania, który musimy traktować całościowo. Kompilowany aplikacja to aplikacja MVC platformy .NET Core i planujemy wdrożyć aplikację przy użyciu serwera nginx jako zwrotnego serwera proxy w systemie Ubuntu Linux. Wszystkie te składniki oprogramowania stanowią część obrazu kontenera.

Co to jest obraz kontener?

Obraz kontenera jest przenośnym pakietem zawierającym oprogramowanie. Kiedy obraz zostanie uruchomiony, staje się naszym kontenerem. Kontener jest wystąpieniem w pamięci obrazu.

Nie można zmienić obrazu kontenera. Po utworzeniu obrazu nie można go zmienić. Jedynym sposobem zmiany obrazu jest utworzenie nowego obrazu. Ta funkcja gwarantuje, że obraz używany w środowisku produkcyjnym jest tym samym obrazem, którego użyto podczas programowania i kontroli jakości.

Co to jest system operacyjny hosta?

System operacyjny hosta to system operacyjny, w którym działa aparat platformy Docker. Kontenery platformy Docker działające w systemie Linux współużytkują jądro systemu operacyjnego hosta i nie wymagają systemu operacyjnego kontenera, o ile plik binarny może uzyskać bezpośredni dostęp do jądra systemu operacyjnego.

Diagram przedstawiający obraz platformy Docker bez podstawowego systemu operacyjnego i zależność od jądra systemu operacyjnego hosta.

Kontenery systemu Windows potrzebują jednak systemu operacyjnego kontenera. Kontener zarządza usługami, takimi jak system plików, zarządzanie siecią, planowanie procesów i zarządzanie pamięcią, za pośrednictwem jądra systemu operacyjnego.

Co to jest system operacyjny kontenera?

System operacyjny kontenera to system operacyjny, który jest częścią spakowanego obrazu. Mamy elastyczność dołączania różnych wersji systemów operacyjnych Linux lub Windows w kontenerze. Ta elastyczność pozwala nam uzyskać dostęp do określonych funkcji systemu operacyjnego lub zainstalować dodatkowe oprogramowanie, z których mogą korzystać nasze aplikacje.

Diagram przedstawiający obraz platformy Docker z podstawowym systemem operacyjnym Ubuntu i zależność od jądra systemu operacyjnego hosta.

System operacyjny kontenera jest odizolowany od systemu operacyjnego hosta i jest to środowisko, w którym wdrażamy i uruchamiamy naszą aplikację. W połączeniu z niezmiennością obrazu ta izolacja gwarantuje, że środowisko programistyczne naszej aplikacji jest takie samo jak środowisko produkcyjne.

W naszym przykładzie używamy systemu operacyjnego Ubuntu Linux jako systemu operacyjnego kontenera, a ten system operacyjny nie zmienia się z programowania ani produkcji. Używany przez nas obraz jest zawsze taki sam.

Co to jest jednolity stosowy system plików (Unionfs)?

Służymy Unionfs do tworzenia obrazów platformy Docker. Unionfs to system plików, który umożliwia tworzenie stosu kilku katalogów — nazywanych gałęziami — w taki sposób, że jest wyświetlany tak, jakby zawartość została scalona. Jednak zawartość jest fizycznie niezależna. System Unionfs umożliwia dodawanie i usuwanie gałęzi w miarę rozszerzania systemu plików.

Diagram przedstawiający ułożone w stos warstwy w obrazie platformy Docker utworzonym z użyciem systemu plików unionfs.

Załóżmy na przykład, że tworzymy obraz dla naszej aplikacji internetowej, bazując na wcześniejszym obrazie. Dystrybucję systemu Ubuntu ułożymy w obrazie podstawowym jako warstwę leżącą nad warstwą rozruchowego systemu plików. Następnie zainstalujemy serwer nginx i naszą aplikację internetową. Skutecznie nakładamy warstwy nginx i aplikację internetową na podstawie oryginalnego obrazu systemu Ubuntu.

Końcowa warstwa z możliwością zapisu jest tworzona po uruchomieniu kontenera na podstawie obrazu. Jednak ta warstwa nie jest zachowywana, gdy kontener zostanie zniszczony.

Co to jest obraz podstawowy?

Obraz podstawowy jest obrazem korzystającym z obrazu scratch platformy Docker. Obraz scratch jest pustym obrazem kontenera, który nie tworzy warstwy systemu plików. W przypadku tego obrazu przyjmuje się założenie, że aplikacja, która ma zostać uruchomiona, może bezpośrednio korzystać z jądra systemu operacyjnego hosta.

Co to jest obraz nadrzędny?

Obraz nadrzędny to obraz kontenera, na podstawie którego są tworzone obrazy użytkownika.

Na przykład zamiast tworzyć obraz z scratch systemu Ubuntu, a następnie instalować go, użyjemy obrazu już opartego na systemie Ubuntu. Możemy nawet użyć obrazu, który ma już zainstalowany serwer nginx. Obraz nadrzędny zwykle zawiera system operacyjny kontenera.

Jaka jest główna różnica między obrazami podstawowymi i nadrzędnymi?

Oba typy obrazów pozwalają nam utworzyć obraz wielokrotnego użytku. Jednak obrazy podstawowe umożliwiają nam większą kontrolę nad ostateczną zawartością obrazu. Przypomnij sobie wcześniej, że obraz jest niezmienny; Można dodać tylko do obrazu i nie odjąć.

W systemie Windows można tworzyć tylko obrazy kontenerów oparte na podstawowych obrazach kontenerów systemu Windows. Firma Microsoft udostępnia i obsługuje te podstawowe obrazy kontenerów systemu Windows.

Co to jest plik Dockerfile?

Dockerfile to plik tekstowy, który zawiera instrukcje dotyczące kompilowania i uruchamiania obrazu platformy Docker. Definiuje on następujące aspekty obrazu:

  • Obraz podstawowy lub nadrzędny używany do tworzenia nowego obrazu
  • Polecenia służące do aktualizowania podstawowego systemu operacyjnego i instalowania dodatkowego oprogramowania
  • Artefakty kompilacji do dołączenia, takie jak opracowana aplikacja
  • Usługi do uwidocznienia, takie jak konfiguracja magazynu i sieci
  • Polecenie wykonywane podczas uruchamiania kontenera

Zamapujmy te aspekty na przykładowy plik Dockerfile. Załóżmy, że tworzymy obraz platformy Docker dla witryny internetowej platformy ASP.NET Core. Plik Dockerfile może wyglądać podobnie do następującego przykładu:

# Step 1: Specify the parent image for the new image
FROM ubuntu:18.04

# Step 2: Update OS packages and install additional software
RUN apt -y update &&  apt install -y wget nginx software-properties-common apt-transport-https \
	&& wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb \
	&& dpkg -i packages-microsoft-prod.deb \
	&& add-apt-repository universe \
	&& apt -y update \
	&& apt install -y dotnet-sdk-3.0

# Step 3: Configure Nginx environment
CMD service nginx start

# Step 4: Configure Nginx environment
COPY ./default /etc/nginx/sites-available/default

# STEP 5: Configure work directory
WORKDIR /app

# STEP 6: Copy website code to container
COPY ./website/. .

# STEP 7: Configure network requirements
EXPOSE 80:8080

# STEP 8: Define the entry point of the process that runs in the container
ENTRYPOINT ["dotnet", "website.dll"]

Nie omówimy tutaj specyfikacji pliku Dockerfile ani szczegółów każdego polecenia w poprzednim przykładzie. Zauważ jednak, że w tym pliku znajduje się kilka poleceń, które umożliwiają manipulowanie strukturą obrazu. Na przykład COPY polecenie kopiuje zawartość z określonego folderu na komputerze lokalnym do obrazu kontenera, który tworzymy.

Pamiętaj, że wcześniej wspomnieliśmy, że obrazy platformy Docker korzystają z unionfsusługi . W miarę kompilowania końcowego obrazu kontenera w każdym z tych kroków jest tworzony buforowany obraz kontenera. Te obrazy tymczasowe są nakładane na górę poprzedniego obrazu i prezentowane jako pojedynczy obraz po wykonaniu wszystkich kroków.

Ostatnim krokiem jest krok nr 8. Element ENTRYPOINT w pliku wskazuje, który proces będzie wykonywany po uruchomieniu kontenera na podstawie obrazu. Jeśli nie ma punktu WEJŚCIA ani innego procesu do wykonania, platforma Docker zinterpretuje to, ponieważ nie ma nic do zrobienia dla kontenera, a kontener zakończy działanie.

Jak zarządzać obrazami platformy Docker

Obrazy platformy Docker to duże pliki, które są początkowo przechowywane na komputerze i potrzebujemy narzędzi do zarządzania tymi plikami.

Interfejs wiersza polecenia platformy Docker i program Docker Desktop umożliwiają zarządzanie obrazami przez kompilowanie, wyświetlanie listy, usuwanie i uruchamianie ich. Obrazy platformy Docker są zarządzane za pomocą klienta docker. Klient nie wykonuje poleceń bezpośrednio i wysyła wszystkie zapytania do demona dockerd .

Nie będziemy tutaj omawiać wszystkich poleceń klienta i ich flag. Opiszemy tylko kilka najczęściej używanych poleceń. Sekcja Dowiedz się więcej w lekcji Podsumowanie tego modułu zawiera linki do dokumentacji platformy Docker, która szczegółowo obejmuje wszystkie polecenia i flagi poleceń.

Jak skompilować obraz

Polecenie docker build umożliwia kompilowanie obrazów platformy Docker. Załóżmy, że użyjemy definicji pliku Dockerfile z wcześniejszego przykładu do skompilowania obrazu. Oto przykład pokazujący polecenie kompilacji:

docker build -t temp-ubuntu .

Oto dane wyjściowe, które generuje polecenie kompilacji:

Sending build context to Docker daemon  4.69MB
Step 1/8 : FROM ubuntu:18.04
 ---> a2a15febcdf3
Step 2/8 : RUN apt -y update && apt install -y wget nginx software-properties-common apt-transport-https && wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb && dpkg -i packages-microsoft-prod.deb && add-apt-repository universe && apt -y update && apt install -y dotnet-sdk-3.0
 ---> Using cache
 ---> feb452bac55a
Step 3/8 : CMD service nginx start
 ---> Using cache
 ---> ce3fd40bd13c
Step 4/8 : COPY ./default /etc/nginx/sites-available/default
 ---> 97ff0c042b03
Step 5/8 : WORKDIR /app
 ---> Running in 883f8dc5dcce
Removing intermediate container 883f8dc5dcce
 ---> 6e36758d40b1
Step 6/8 : COPY ./website/. .
 ---> bfe84cc406a4
Step 7/8 : EXPOSE 80:8080
 ---> Running in b611a87425f2
Removing intermediate container b611a87425f2
 ---> 209b54a9567f
Step 8/8 : ENTRYPOINT ["dotnet", "website.dll"]
 ---> Running in ea2efbc6c375
Removing intermediate container ea2efbc6c375
 ---> f982892ea056
Successfully built f982892ea056
Successfully tagged temp-ubuntu:latest

Nie martw się, jeśli nie rozumiesz powyższych danych wyjściowych. Zwróć tylko uwagę na listę kroków widoczną w danych wyjściowych. W miarę wykonywania poszczególnych kroków do kompilowanego obrazu jest dodawana nowa warstwa.

Zwróć również uwagę, że wykonujemy też kilka poleceń w celu zainstalowania oprogramowania i zarządzania konfiguracją. Na przykład w kroku 2 uruchamiamy polecenia apt -y update i apt install -y, aby zaktualizować system operacyjny. Te polecenia są wykonywane w uruchomionym kontenerze utworzonym dla tego kroku. Po uruchomieniu polecenia kontener pośredni zostanie usunięty. Buforowany bazowy obraz jest przechowywany na hoście kompilacji i nie jest automatycznie usuwany. Dzięki takiej optymalizacji późniejsze kompilacje ponownie użyją tych obrazów w celu skrócenia czasu kompilacji.

Co to jest tag obrazu?

Tag obrazu to ciąg tekstowy używany do obsługi wersji obrazu.

We wcześniejszym przykładzie kompilacji ostatnim komunikatem była informacja „Successfully tagged temp-ubuntu: latest” (Pomyślnie otagowano temp-ubuntu: latest). Korzystając z flagi polecenia -t, można podczas kompilowania obrazu nadać mu nazwę i opcjonalnie oznaczyć go tagiem. W naszym przykładzie nazwaliśmy obraz przy użyciu flagi -t temp-ubuntu, a wynikowy obraz został oznaczony tagiem temp-ubuntu: latest. Obraz jest oznaczany etykietą latest, jeśli nie zostanie określony dla niego żaden tag.

Do jednego obrazu można przypisać wiele tagów. Zgodnie z konwencją najnowsza wersja obrazu ma przypisany tag latest oraz tag z numerem wersji obrazu. Po wydaniu nowej wersji obrazu można ponownie przypisać tag latest w taki sposób, aby odwoływał się do nowego obrazu.

W przypadku systemu Windows firma Microsoft nie udostępnia podstawowych obrazów kontenerów przy użyciu najnowszego tagu. W przypadku podstawowych obrazów kontenerów systemu Windows należy określić tag, którego chcesz użyć. Na przykład podstawowy obraz kontenera systemu Windows dla serwera Server Core to mcr.microsoft.com/windows/servercore. Wśród jego tagów znajdują się ltsc2016wartości , ltsc2019i ltsc2022.

Oto kolejny przykład. Załóżmy, że chcesz użyć obrazów platformy Docker z przykładami platformy .NET Core. W tym miejscu mamy cztery wersje platform, z których możemy wybrać:

  • mcr.microsoft.com/dotnet/core/samples:dotnetapp

  • mcr.microsoft.com/dotnet/core/samples:aspnetapp

  • mcr.microsoft.com/dotnet/core/samples:wcfservice

  • mcr.microsoft.com/dotnet/core/samples:wcfclient

Na powyższej liście obrazów widać, że firma Microsoft udostępnia wiele przykładów platformy .NET Core. Tagi określają, do których przykładów odwołuje się obraz: ASP.NET, usługa WCF itd.

Jak wyświetlić listę obrazów

Oprogramowanie platformy Docker automatycznie konfiguruje lokalny rejestr obrazów na komputerze. Aby wyświetlić listę obrazów w tym rejestrze, użyj polecenia docker images.

docker images

Dane wyjściowe wyglądają jak w poniższym przykładzie:

REPOSITORY          TAG                     IMAGE ID            CREATED                     SIZE
tmp-ubuntu          latest             f89469694960        14 minutes ago         1.69GB
tmp-ubuntu          version-1.0        f89469694960        14 minutes ago         1.69GB
ubuntu              18.04                   a2a15febcdf3        5 weeks ago            64.2MB

Zwróć uwagę, że każdy obraz na liście ma swoją Nazwę, Tag i Identyfikator obrazu. Jak zapewne pamiętasz, do obrazu można zastosować wiele etykiet. Powyższe dane wyjściowe przedstawiają przykład; Mimo że nazwy obrazów są różne, możemy zobaczyć, że identyfikatory są takie same.

Identyfikator obrazu to przydatny sposób identyfikowania obrazów i zarządzania nimi w przypadku, kiedy nazwa lub tag obrazu mogą być niejednoznaczne.

Jak usunąć obraz

Obraz z lokalnego rejestru platformy Docker można usunąć za pomocą polecenia docker rmi. Jest to przydatne, jeśli musisz zaoszczędzić miejsce na dysku hosta kontenera, ponieważ warstwy obrazu kontenera sumują się do całkowitego dostępnego miejsca.

Podaj nazwę lub identyfikator obrazu do usunięcia. W tym przykładzie podawana jest nazwa usuwanego obrazu przykładowej aplikacji internetowej:

docker rmi temp-ubuntu:version-1.0

Nie można usunąć obrazu, jeśli kontener nadal używa obrazu. Polecenie docker rmi zwraca komunikat o błędzie, który wyświetla listę kontenera, który opiera się na obrazie.

Poznaliśmy podstawy obrazów platformy Docker, sposób zarządzania tymi obrazami oraz sposób uruchamiania kontenera na podstawie obrazu. Teraz przyjrzyjmy się sposobom zarządzania kontenerami.

Sprawdź swoją wiedzę

1.

W których z następujących systemów operacyjnych dostępna jest aplikacja Docker Desktop służąca do kompilowania i udostępniania konteneryzowanych aplikacji oraz mikrousług?

2.

Które polecenie platformy Docker służy do ponownego kompilowania obrazu kontenera?

3.

Które z poniższych zdań najlepiej opisuje obraz kontenera?