Przepływ pracy tworzenia oprogramowania dla aplikacji platformy Docker
Napiwek
Ta zawartość jest fragmentem książki eBook, architektury mikrousług platformy .NET dla konteneryzowanych aplikacji platformy .NET dostępnych na platformie .NET Docs lub jako bezpłatnego pliku PDF, który można odczytać w trybie offline.
Cykl życia tworzenia aplikacji rozpoczyna się na komputerze jako deweloper, gdzie kodujesz aplikację przy użyciu preferowanego języka i testujesz go lokalnie. Dzięki temu przepływowi pracy, niezależnie od wybranego języka, platformy i platformy, zawsze opracowujesz i testujesz kontenery platformy Docker, ale robisz to lokalnie.
Każdy kontener (wystąpienie obrazu platformy Docker) zawiera następujące składniki:
- Wybór systemu operacyjnego, na przykład dystrybucji systemu Linux, systemu Windows Nano Server lub Windows Server Core.
- Pliki dodane podczas programowania, na przykład kod źródłowy i pliki binarne aplikacji.
- Informacje o konfiguracji, takie jak ustawienia środowiska i zależności.
Przepływ pracy do tworzenia aplikacji opartych na kontenerach platformy Docker
W tej sekcji opisano przepływ pracy tworzenia pętli wewnętrznej dla aplikacji opartych na kontenerach platformy Docker. Przepływ pracy pętli wewnętrznej oznacza, że nie uwzględnia szerszego przepływu pracy metodyki DevOps, który może obejmować wdrożenie produkcyjne i koncentruje się tylko na pracy programistycznej wykonywanej na komputerze dewelopera. Początkowe kroki konfigurowania środowiska nie są uwzględniane, ponieważ te kroki są wykonywane tylko raz.
Aplikacja składa się z własnych usług oraz dodatkowych bibliotek (zależności). Poniżej przedstawiono podstawowe kroki, które zwykle należy wykonać podczas tworzenia aplikacji platformy Docker, jak pokazano na rysunku 5–1.
Proces programowania aplikacji platformy Docker: 1 — Kodowanie aplikacji, 2 — Pisanie pliku Dockerfile/s, 3 — Tworzenie obrazów zdefiniowanych w pliku Dockerfile/s, 4 — (opcjonalnie) Tworzenie usług w pliku docker-compose.yml, 5 — Uruchamianie kontenera lub aplikacji docker-compose, 6 — Testowanie aplikacji lub mikrousług, 7 — Wypychanie do repozytorium i powtarzanie.
Rysunek 5–1. Przepływ pracy krok po kroku do tworzenia konteneryzowanych aplikacji platformy Docker
W tej sekcji cały proces jest szczegółowy, a każdy główny krok jest wyjaśniany przez skupienie się na środowisku programu Visual Studio.
W przypadku korzystania z podejścia programistycznego edytora/interfejsu wiersza polecenia (na przykład programu Visual Studio Code i interfejsu wiersza polecenia platformy Docker w systemie macOS lub Windows) musisz znać każdy krok, ogólnie bardziej szczegółowo niż w przypadku korzystania z programu Visual Studio. Aby uzyskać więcej informacji na temat pracy w środowisku interfejsu wiersza polecenia, zobacz książkę elektroniczną Cykl życia konteneryzowanej aplikacji platformy Docker przy użyciu platform i narzędzi firmy Microsoft.
W przypadku korzystania z programu Visual Studio 2022 wiele z tych kroków jest obsługiwanych, co znacznie zwiększa produktywność. Jest to szczególnie istotne w przypadku korzystania z programu Visual Studio 2022 i kierowania do aplikacji wielokontenerowych. Na przykład za pomocą jednego kliknięcia myszy program Visual Studio dodaje plik Dockerfile
i docker-compose.yml
do projektów z konfiguracją aplikacji. Po uruchomieniu aplikacji w programie Visual Studio kompiluje obraz platformy Docker i uruchamia aplikację z wieloma kontenerami bezpośrednio na platformie Docker; umożliwia nawet debugowanie kilku kontenerów jednocześnie. Te funkcje zwiększą szybkość programowania.
Jednak tylko dlatego, że program Visual Studio wykonuje te kroki automatycznie, nie oznacza, że nie musisz wiedzieć, co dzieje się pod platformą Docker. W związku z tym poniższe wskazówki zawierają szczegółowe informacje o każdym kroku.
Krok 1. Rozpocznij kodowanie i utwórz początkową aplikację lub punkt odniesienia usługi
Tworzenie aplikacji platformy Docker jest podobne do sposobu tworzenia aplikacji bez platformy Docker. Różnica polega na tym, że podczas tworzenia oprogramowania dla platformy Docker wdrażasz i testujesz aplikację lub usługi działające w kontenerach platformy Docker w środowisku lokalnym (konfiguracja maszyny wirtualnej z systemem Linux przez platformę Docker lub bezpośrednio system Windows, jeśli korzystasz z kontenerów systemu Windows).
Konfigurowanie środowiska lokalnego za pomocą programu Visual Studio
Aby rozpocząć, upewnij się, że masz zainstalowany program Docker Desktop dla systemu Windows , jak wyjaśniono w poniższych instrukcjach:
Wprowadzenie do aplikacji Docker Desktop dla systemu Windows
Ponadto potrzebny jest program Visual Studio 2022 w wersji 17.0 z zainstalowanym pakietem roboczym .ASP.NET i tworzeniem aplikacji internetowych, jak pokazano na rysunku 5–2.
Rysunek 5–2. Wybieranie obciążenia ASP.NET i tworzenia aplikacji internetowych podczas konfigurowania programu Visual Studio 2022
Możesz rozpocząć kodowanie aplikacji na zwykłych platformach .NET (zwykle na platformie .NET Core lub nowszym, jeśli planujesz używać kontenerów) jeszcze przed włączeniem platformy Docker w aplikacji i wdrażaniu i testowaniu na platformie Docker. Zaleca się jednak rozpoczęcie pracy z platformą Docker tak szybko, jak to możliwe, ponieważ będzie to prawdziwe środowisko i jak najszybciej można odnaleźć wszelkie problemy. Zachęcamy do tego, ponieważ program Visual Studio ułatwia pracę z platformą Docker, że niemal czuje się przezroczysty — najlepszym przykładem debugowania aplikacji wielokontenerowych z programu Visual Studio.
Dodatkowe zasoby
Wprowadzenie do aplikacji Docker Desktop dla systemu Windows
https://docs.docker.com/docker-for-windows/Visual Studio 2022
https://visualstudio.microsoft.com/downloads/
Krok 2. Tworzenie pliku Dockerfile powiązanego z istniejącym obrazem podstawowym platformy .NET
Potrzebujesz pliku Dockerfile dla każdego obrazu niestandardowego, który chcesz skompilować; Potrzebujesz również pliku Dockerfile dla każdego kontenera, który ma zostać wdrożony automatycznie z poziomu programu Visual Studio, czy ręcznie przy użyciu interfejsu wiersza polecenia platformy Docker (uruchamianie platformy Docker i polecenia docker-compose). Jeśli aplikacja zawiera jedną usługę niestandardową, potrzebujesz jednego pliku Dockerfile. Jeśli aplikacja zawiera wiele usług (jak w architekturze mikrousług), potrzebujesz jednego pliku Dockerfile dla każdej usługi.
Plik Dockerfile znajduje się w folderze głównym aplikacji lub usługi. Zawiera polecenia, które informują platformę Docker, jak skonfigurować i uruchomić aplikację lub usługę w kontenerze. Możesz ręcznie utworzyć plik Dockerfile w kodzie i dodać go do projektu wraz z zależnościami platformy .NET.
W programie Visual Studio i jego narzędziach dla platformy Docker to zadanie wymaga tylko kilku kliknięć myszą. Podczas tworzenia nowego projektu w programie Visual Studio 2022 istnieje opcja o nazwie Włącz obsługę platformy Docker, jak pokazano na rysunku 5–3.
Rysunek 5–3. Włączanie obsługi platformy Docker podczas tworzenia nowego projektu ASP.NET Core w programie Visual Studio 2022
Możesz również włączyć obsługę platformy Docker w istniejącym projekcie aplikacji internetowej ASP.NET Core, klikając prawym przyciskiem myszy projekt w Eksplorator rozwiązań i wybierając polecenie Dodaj>obsługę platformy Docker..., jak pokazano na rysunku 5–4.
Rysunek 5–4. Włączanie obsługi platformy Docker w istniejącym projekcie programu Visual Studio 2022
Ta akcja dodaje plik Dockerfile do projektu z wymaganą konfiguracją i jest dostępny tylko w projektach ASP.NET Core.
W podobny sposób program Visual Studio może również dodać docker-compose.yml
plik dla całego rozwiązania z opcją Dodaj > obsługę orkiestratora kontenerów.... W kroku 4 zapoznamy się z tą opcją bardziej szczegółowo.
Korzystanie z istniejącego oficjalnego obrazu platformy Docker platformy .NET
Zwykle tworzysz obraz niestandardowy dla kontenera na podstawie obrazu podstawowego, który można uzyskać z oficjalnego repozytorium, takiego jak rejestr usługi Docker Hub . Właśnie tak dzieje się w obszarze okładek po włączeniu obsługi platformy Docker w programie Visual Studio. Plik Dockerfile będzie używać istniejącego dotnet/core/aspnet
obrazu.
Wcześniej wyjaśniliśmy, których obrazów i repozytoriów platformy Docker można używać, w zależności od wybranej platformy i systemu operacyjnego. Jeśli na przykład chcesz użyć ASP.NET Core (Linux lub Windows), obraz do użycia to mcr.microsoft.com/dotnet/aspnet:8.0
. W związku z tym wystarczy określić podstawowy obraz platformy Docker, który będzie używany dla kontenera. Można to zrobić, dodając FROM mcr.microsoft.com/dotnet/aspnet:8.0
do pliku Dockerfile. Jest to wykonywane automatycznie przez program Visual Studio, ale jeśli chcesz zaktualizować wersję, zaktualizujesz tę wartość.
Użycie oficjalnego repozytorium obrazów platformy .NET z usługi Docker Hub z numerem wersji gwarantuje, że te same funkcje językowe są dostępne na wszystkich maszynach (w tym na komputerach programistycznych, testowych i produkcyjnych).
Poniższy przykład przedstawia przykładowy plik Dockerfile dla kontenera ASP.NET Core.
FROM mcr.microsoft.com/dotnet/aspnet:8.0
ARG source
WORKDIR /app
EXPOSE 80
COPY ${source:-obj/Docker/publish} .
ENTRYPOINT ["dotnet", " MySingleContainerWebApp.dll "]
W tym przypadku obraz jest oparty na wersji 8.0 oficjalnego obrazu platformy Docker ASP.NET Core (multi-arch dla systemów Linux i Windows). To jest ustawienie FROM mcr.microsoft.com/dotnet/aspnet:8.0
. (Aby uzyskać więcej informacji na temat tego obrazu podstawowego, zobacz stronę ASP.NET Core Docker Image (Obraz podstawowego platformy Docker). W pliku Dockerfile należy również poinstruować platformę Docker, aby nasłuchiwać na porcie TCP, który będzie używany w czasie wykonywania (w tym przypadku port 80, zgodnie z konfiguracją ustawienia EXPOSE).
Możesz określić dodatkowe ustawienia konfiguracji w pliku Dockerfile, w zależności od używanego języka i platformy. Na przykład wiersz ENTRYPOINT z ["dotnet", "MySingleContainerWebApp.dll"]
poleceniem informuje platformę Docker o uruchomieniu aplikacji .NET. Jeśli używasz zestawu SDK i interfejsu wiersza polecenia platformy .NET (dotnet CLI) do kompilowania i uruchamiania aplikacji .NET, to ustawienie będzie inne. Najważniejsze jest to, że wiersz ENTRYPOINT i inne ustawienia będą się różnić w zależności od języka i platformy wybranej dla aplikacji.
Dodatkowe zasoby
Tworzenie obrazów platformy Docker dla aplikacji ASP.NET Core
https://learn.microsoft.com/dotnet/core/docker/building-net-docker-imagesKompilowanie obrazów kontenerów. W oficjalnej dokumentacji platformy Docker.
https://docs.docker.com/get-started/docker-concepts/building-images/Bądź na bieżąco z obrazami kontenerów platformy .NET
https://devblogs.microsoft.com/dotnet/staying-up-to-date-with-net-container-images/Używanie platformy .NET i platformy Docker Together — aktualizacja platformy DockerCon 2018
https://devblogs.microsoft.com/dotnet/using-net-and-docker-together-dockercon-2018-update/
Korzystanie z repozytoriów obrazów z wieloma łukami
Pojedyncze repozytorium może zawierać warianty platformy, takie jak obraz systemu Linux i obraz systemu Windows. Ta funkcja umożliwia dostawcom takim jak Microsoft (twórcy obrazów bazowych) utworzenie pojedynczego repozytorium w celu pokrycia wielu platform (czyli systemów Linux i Windows). Na przykład repozytorium .NET dostępne w rejestrze usługi Docker Hub zapewnia obsługę systemów Linux i Windows Nano Server przy użyciu tej samej nazwy repozytorium.
Jeśli określisz tag, określania wartości docelowej platformy, która jest jawna w następujących przypadkach:
mcr.microsoft.com/dotnet/aspnet:8.0-bullseye-slim
Cele: środowisko uruchomieniowe platformy .NET 8 w systemie Linuxmcr.microsoft.com/dotnet/aspnet:8.0-nanoserver-ltsc2022
Cele: środowisko uruchomieniowe .NET 8 tylko w systemie Windows Nano Server
Jeśli jednak określisz tę samą nazwę obrazu, nawet przy użyciu tego samego tagu, obrazy z wieloma łukami (na przykład aspnet
obraz) będą używać wersji systemu Linux lub Windows w zależności od wdrażanego systemu operacyjnego hosta platformy Docker, jak pokazano w poniższym przykładzie:
mcr.microsoft.com/dotnet/aspnet:8.0
Wiele łuków: środowisko uruchomieniowe platformy .NET 8 tylko w systemie Linux lub Windows Nano Server w zależności od systemu operacyjnego hosta platformy Docker
W ten sposób, gdy ściągniesz obraz z hosta systemu Windows, pobierze wariant systemu Windows, a ściąganie tej samej nazwy obrazu z hosta z systemem Linux spowoduje ściągnięcie wariantu systemu Linux.
Kompilacje wieloetapowe w pliku Dockerfile
Plik Dockerfile jest podobny do skryptu wsadowego. Podobnie jak w przypadku konieczności skonfigurowania maszyny z poziomu wiersza polecenia.
Zaczyna się od obrazu podstawowego, który konfiguruje kontekst początkowy, jest jak system plików startowych, który znajduje się na górze systemu operacyjnego hosta. Nie jest to system operacyjny, ale można o nim myśleć jak "system operacyjny" wewnątrz kontenera.
Wykonanie każdego wiersza polecenia tworzy nową warstwę w systemie plików ze zmianami z poprzedniej, tak aby w połączeniu wygenerować wynikowy system plików.
Ponieważ każda nowa warstwa "spoczywa" na początku poprzedniego i wynikowy rozmiar obrazu zwiększa się wraz z każdym poleceniem, obrazy mogą być bardzo duże, jeśli muszą zawierać na przykład zestaw SDK potrzebny do kompilowania i publikowania aplikacji.
Jest to miejsce, w którym kompilacje wieloetapowe są wprowadzane do wykresu (z platformy Docker 17.05 i nowszych) w celu wykonania magii.
Podstawowym pomysłem jest oddzielenie procesu wykonywania pliku Dockerfile na etapach, gdzie etap jest obrazem początkowym, po którym następuje co najmniej jedno polecenie, a ostatni etap określa ostateczny rozmiar obrazu.
Krótko mówiąc, kompilacje wieloetapowe umożliwiają podzielenie tworzenia w różnych "fazach", a następnie zebranie końcowego obrazu, wykonując tylko odpowiednie katalogi z etapów pośrednich. Ogólna strategia korzystania z tej funkcji jest następująca:
Użyj obrazu podstawowego zestawu SDK (nie ma znaczenia, jak duży rozmiar), a wszystko, co jest potrzebne do skompilowania i opublikowania aplikacji w folderze, a następnie
Użyj obrazu podstawowego, małego, tylko w czasie wykonywania i skopiuj folder publikowania z poprzedniego etapu, aby utworzyć mały obraz końcowy.
Prawdopodobnie najlepszym sposobem zrozumienia wieloetapowego jest szczegółowe przejście przez plik Dockerfile, wiersz po wierszu, więc zacznijmy od początkowego pliku Dockerfile utworzonego przez program Visual Studio podczas dodawania obsługi platformy Docker do projektu i przejdziemy do niektórych optymalizacji później.
Początkowy plik Dockerfile może wyglądać mniej więcej tak:
1 FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
2 WORKDIR /app
3 EXPOSE 80
4
5 FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
6 WORKDIR /src
7 COPY src/Services/Catalog/Catalog.API/Catalog.API.csproj …
8 COPY src/BuildingBlocks/HealthChecks/src/Microsoft.AspNetCore.HealthChecks …
9 COPY src/BuildingBlocks/HealthChecks/src/Microsoft.Extensions.HealthChecks …
10 COPY src/BuildingBlocks/EventBus/IntegrationEventLogEF/ …
11 COPY src/BuildingBlocks/EventBus/EventBus/EventBus.csproj …
12 COPY src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.csproj …
13 COPY src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.csproj …
14 COPY src/BuildingBlocks/WebHostCustomization/WebHost.Customization …
15 COPY src/BuildingBlocks/HealthChecks/src/Microsoft.Extensions …
16 COPY src/BuildingBlocks/HealthChecks/src/Microsoft.Extensions …
17 RUN dotnet restore src/Services/Catalog/Catalog.API/Catalog.API.csproj
18 COPY . .
19 WORKDIR /src/src/Services/Catalog/Catalog.API
20 RUN dotnet build Catalog.API.csproj -c Release -o /app
21
22 FROM build AS publish
23 RUN dotnet publish Catalog.API.csproj -c Release -o /app
24
25 FROM base AS final
26 WORKDIR /app
27 COPY --from=publish /app .
28 ENTRYPOINT ["dotnet", "Catalog.API.dll"]
A oto szczegóły, wiersz według wiersza:
Wiersz 1: Rozpocznij etap z "małym" obrazem podstawowym tylko dla środowiska uruchomieniowego, wywołaj go jako bazę w celu uzyskania odwołania.
Wiersz 2: Utwórz katalog /app na obrazie.
Wiersz 3: Uwidaczniaj port 80.
Wiersz 5: Rozpocznij nowy etap z obrazem "duży" do kompilowania/publikowania. Wywołaj ją w celu uzyskania informacji referencyjnych.
Wiersz nr 6: Utwórz katalog /src na obrazie.
Wiersz 7: Do wiersza 16 skopiuj odwołania do plików projektu csproj , aby można było przywrócić pakiety później.
Wiersz 17: Przywracanie pakietów dla projektu Catalog.API i przywołynych projektów.
Wiersz 18: Skopiuj wszystkie drzewa katalogów dla rozwiązania (z wyjątkiem plików/katalogów zawartych w pliku .dockerignore ) do katalogu /src na obrazie.
Wiersz 19: Zmień bieżący folder na projekt Catalog.API .
Wiersz 20: Skompiluj projekt (i inne zależności projektu) i dane wyjściowe do katalogu /app na obrazie.
Wiersz nr 22: Rozpocznij nowy etap kontynuując kompilację. Wywołaj go w celu uzyskania informacji referencyjnych.
Wiersz 23: Publikowanie projektu (i zależności) oraz danych wyjściowych do katalogu /app na obrazie.
Wiersz nr 25: Rozpocznij nowy etap kontynuując od podstawy i nazywając go ostatnim.
Wiersz 26: Zmień bieżący katalog na /app.
Wiersz 27: Skopiuj katalog /app z etapu publikowania do bieżącego katalogu.
Wiersz nr 28: Zdefiniuj polecenie do uruchomienia po uruchomieniu kontenera.
Teraz przyjrzyjmy się niektórym optymalizacjom, aby poprawić wydajność całego procesu, która w przypadku modułów eShopOnContainers oznacza około 22 minut lub więcej w celu utworzenia kompletnego rozwiązania w kontenerach systemu Linux.
Skorzystasz z funkcji pamięci podręcznej warstwy platformy Docker, która jest dość prosta: jeśli obraz podstawowy i polecenia są takie same jak niektóre wcześniej wykonane, może po prostu użyć warstwy wynikowej bez konieczności wykonywania poleceń, co pozwala zaoszczędzić trochę czasu.
Dlatego skoncentrujmy się na etapie kompilacji , wiersze 5-6 są w większości takie same, ale wiersze 7-17 są inne dla każdej usługi od eShopOnContainers, więc muszą być wykonywane za każdym razem, jednak w przypadku zmiany wierszy 7-16 na:
COPY . .
Następnie byłoby to samo dla każdej usługi, skopiowałoby całe rozwiązanie i utworzyłoby większą warstwę, ale:
Proces kopiowania będzie wykonywany tylko po raz pierwszy (i podczas ponownego kompilowania, jeśli plik zostanie zmieniony) i będzie używać pamięci podręcznej dla wszystkich innych usług i
Ponieważ większy obraz występuje na etapie pośrednim, nie ma wpływu na ostateczny rozmiar obrazu.
Kolejna znacząca optymalizacja obejmuje restore
wykonanie polecenia w wierszu 17, który jest również inny dla każdej usługi eShopOnContainers. Jeśli zmienisz ten wiersz na tylko:
RUN dotnet restore
Spowoduje to przywrócenie pakietów dla całego rozwiązania, ale następnie ponownie zrobiłoby to tylko raz, zamiast 15 razy z bieżącą strategią.
Jednak działa tylko wtedy, dotnet restore
gdy w folderze znajduje się pojedynczy plik projektu lub rozwiązania, więc osiągnięcie tego celu jest nieco bardziej skomplikowane i sposób jego rozwiązania, bez uzyskiwania zbyt wielu szczegółów, jest to:
Dodaj następujące wiersze do pliku .dockerignore:
*.sln
, aby zignorować wszystkie pliki rozwiązania w głównym drzewie folderów!eShopOnContainers-ServicesAndWebApps.sln
, aby uwzględnić tylko ten plik rozwiązania.
/ignoreprojectextensions:.dcproj
Dołącz argument dodotnet restore
elementu , więc ignoruje również projekt docker-compose i przywraca tylko pakiety dla rozwiązania eShopOnContainers-ServicesAndWebApps.
W przypadku ostatniej optymalizacji dzieje się tak, że wiersz 20 jest nadmiarowy, ponieważ wiersz 23 również kompiluje aplikację i jest w istocie bezpośrednio po wierszu 20, więc istnieje kolejne czasochłonne polecenie.
Wynikowy plik to:
1 FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
2 WORKDIR /app
3 EXPOSE 80
4
5 FROM mcr.microsoft.com/dotnet/sdk:8.0 AS publish
6 WORKDIR /src
7 COPY . .
8 RUN dotnet restore /ignoreprojectextensions:.dcproj
9 WORKDIR /src/src/Services/Catalog/Catalog.API
10 RUN dotnet publish Catalog.API.csproj -c Release -o /app
11
12 FROM base AS final
13 WORKDIR /app
14 COPY --from=publish /app .
15 ENTRYPOINT ["dotnet", "Catalog.API.dll"]
Tworzenie obrazu podstawowego od podstaw
Możesz utworzyć własny obraz podstawowy platformy Docker od podstaw. Ten scenariusz nie jest zalecany dla osoby, która zaczyna korzystać z platformy Docker, ale jeśli chcesz ustawić określone bity własnego obrazu podstawowego, możesz to zrobić.
Dodatkowe zasoby
Obrazy platformy .NET Core z wieloma łukami.
https://github.com/dotnet/announcements/issues/14Utwórz obraz podstawowy. Oficjalna dokumentacja platformy Docker.
https://docs.docker.com/develop/develop-images/baseimages/
Krok 3. Tworzenie niestandardowych obrazów platformy Docker i osadzanie w nich aplikacji lub usługi
Dla każdej usługi w aplikacji należy utworzyć powiązany obraz. Jeśli aplikacja składa się z jednej usługi lub aplikacji internetowej, wystarczy jeden obraz.
Pamiętaj, że obrazy platformy Docker są tworzone automatycznie w programie Visual Studio. Poniższe kroki są wymagane tylko w przypadku przepływu pracy edytora/interfejsu wiersza polecenia i wyjaśniono, co się dzieje poniżej.
Jako deweloper musisz opracowywać i testować lokalnie, dopóki nie wypchniesz ukończonej funkcji lub zmienisz ją do systemu kontroli źródła (na przykład do usługi GitHub). Oznacza to, że musisz utworzyć obrazy platformy Docker i wdrożyć kontenery na lokalnym hoście platformy Docker (maszynie wirtualnej z systemem Windows lub Linux) oraz uruchomić, przetestować i debugować względem tych kontenerów lokalnych.
Aby utworzyć obraz niestandardowy w środowisku lokalnym przy użyciu interfejsu wiersza polecenia platformy Docker i pliku Dockerfile, możesz użyć polecenia docker build, jak na rysunku 5-5.
Rysunek 5–5. Tworzenie niestandardowego obrazu platformy Docker
Opcjonalnie zamiast bezpośrednio uruchamiać kompilację platformy Docker z folderu projektu, można najpierw wygenerować folder możliwy do wdrożenia z wymaganymi bibliotekami i plikami binarnymi platformy .NET, uruchamiając dotnet publish
polecenie , a następnie użyj docker build
polecenia .
Spowoduje to utworzenie obrazu platformy Docker o nazwie cesardl/netcore-webapi-microservice-docker:first
. W tym przypadku :first
jest to tag reprezentujący określoną wersję. Ten krok można powtórzyć dla każdego obrazu niestandardowego, który należy utworzyć dla utworzonej aplikacji platformy Docker.
Gdy aplikacja składa się z wielu kontenerów (czyli jest to aplikacja z wieloma kontenerami), możesz również użyć docker-compose up --build
polecenia , aby skompilować wszystkie powiązane obrazy za pomocą jednego polecenia przy użyciu metadanych uwidocznionych w powiązanych plikach docker-compose.yml.
Istniejące obrazy można znaleźć w repozytorium lokalnym przy użyciu polecenia docker images, jak pokazano na rysunku 5–6.
Rysunek 5–6. Wyświetlanie istniejących obrazów przy użyciu polecenia docker images
Tworzenie obrazów platformy Docker za pomocą programu Visual Studio
Jeśli używasz programu Visual Studio do tworzenia projektu z obsługą platformy Docker, nie tworzysz jawnie obrazu. Zamiast tego obraz jest tworzony po naciśnięciu F5 (lub Ctrl+F5), aby uruchomić aplikację lub usługę dockerized. Ten krok jest automatyczny w programie Visual Studio i nie będzie widoczny, ale ważne jest, aby wiedzieć, co się dzieje poniżej.
Krok 4. Definiowanie usług w docker-compose.yml podczas kompilowania aplikacji platformy Docker z wieloma kontenerami
Plik docker-compose.yml umożliwia zdefiniowanie zestawu powiązanych usług, które mają być wdrażane jako skomponowana aplikacja z poleceniami wdrażania. Konfiguruje również relacje zależności i konfigurację środowiska uruchomieniowego.
Aby użyć pliku docker-compose.yml, należy utworzyć plik w głównym lub głównym folderze rozwiązania z zawartością podobną do tej w poniższym przykładzie:
version: '3.4'
services:
webmvc:
image: eshop/web
environment:
- CatalogUrl=http://catalog-api
- OrderingUrl=http://ordering-api
ports:
- "80:80"
depends_on:
- catalog-api
- ordering-api
catalog-api:
image: eshop/catalog-api
environment:
- ConnectionString=Server=sqldata;Port=1433;Database=CatalogDB;…
ports:
- "81:80"
depends_on:
- sqldata
ordering-api:
image: eshop/ordering-api
environment:
- ConnectionString=Server=sqldata;Database=OrderingDb;…
ports:
- "82:80"
extra_hosts:
- "CESARDLBOOKVHD:10.0.75.1"
depends_on:
- sqldata
sqldata:
image: mcr.microsoft.com/mssql/server:latest
environment:
- SA_PASSWORD=[PLACEHOLDER]
- ACCEPT_EULA=Y
ports:
- "5433:1433"
Ważne
Firma Microsoft zaleca korzystanie z najbezpieczniejszego dostępnego przepływu uwierzytelniania. Jeśli łączysz się z usługą Azure SQL, tożsamości zarządzane dla zasobów platformy Azure to zalecana metoda uwierzytelniania.
Ten plik docker-compose.yml jest uproszczoną i scaloną wersją. Zawiera statyczne dane konfiguracji dla każdego kontenera (na przykład nazwę obrazu niestandardowego), które są zawsze wymagane, oraz informacje o konfiguracji, które mogą zależeć od środowiska wdrażania, takiego jak parametry połączenia. W kolejnych sekcjach dowiesz się, jak podzielić konfigurację docker-compose.yml na wiele plików docker-compose i zastąpić wartości w zależności od środowiska i typu wykonywania (debugowanie lub wydanie).
Przykładowy plik docker-compose.yml definiuje cztery usługi: webmvc
usługę (aplikację internetową), dwie mikrousługi (ordering-api
i basket-api
) oraz jeden kontener źródła danych, sqldata
na podstawie programu SQL Server dla systemu Linux działającego jako kontener. Każda usługa zostanie wdrożona jako kontener, więc dla każdego z nich jest wymagany obraz platformy Docker.
Plik docker-compose.yml określa nie tylko używane kontenery, ale także sposób ich indywidualnego konfigurowania. Na przykład definicja kontenera webmvc
w pliku .yml:
Używa wstępnie utworzonego
eshop/web:latest
obrazu. Można jednak również skonfigurować obraz do skompilowania w ramach wykonywania narzędzia docker-compose z dodatkową konfiguracją opartą na kompilacji: sekcji w pliku docker-compose.Inicjuje dwie zmienne środowiskowe (CatalogUrl i OrderingUrl).
Przekazuje uwidoczniony port 80 w kontenerze do zewnętrznego portu 80 na maszynie hosta.
Łączy aplikację internetową z katalogiem i usługą zamawiania przy użyciu ustawienia depends_on. Powoduje to, że usługa czeka na uruchomienie tych usług.
Ponownie omówimy plik docker-compose.yml w późniejszej sekcji, gdy omówimy sposób implementowania mikrousług i aplikacji wielokontenerowych.
Praca z docker-compose.yml w programie Visual Studio 2022
Oprócz dodawania pliku Dockerfile do projektu, jak wspomniano wcześniej, program Visual Studio 2017 (z wersji 15.8 w systemie) może dodać obsługę orkiestratora dla narzędzia Docker Compose do rozwiązania.
Po dodaniu obsługi orkiestratora kontenerów, jak pokazano na rysunku 5–7, po raz pierwszy program Visual Studio tworzy plik Dockerfile dla projektu i tworzy nowy projekt (sekcja usługi) w rozwiązaniu z kilkoma plikami globalnymi docker-compose*.yml
, a następnie dodaje projekt do tych plików. Następnie możesz otworzyć pliki docker-compose.yml i zaktualizować je przy użyciu dodatkowych funkcji.
Powtórz tę operację dla każdego projektu, który chcesz uwzględnić w pliku docker-compose.yml.
W momencie pisania tego tekstu program Visual Studio obsługuje orkiestratory docker Compose .
Rysunek 5–7. Dodawanie obsługi platformy Docker w programie Visual Studio 2022 przez kliknięcie prawym przyciskiem myszy projektu ASP.NET Core
Po dodaniu obsługi orkiestratora do rozwiązania w programie Visual Studio zobaczysz również nowy węzeł (w pliku projektu) w Eksplorator rozwiązań zawierający dodane pliki docker-compose.yml, jak pokazano na rysunku docker-compose.dcproj
5–8.
Rysunek 5–8. Węzeł drzewa docker-compose dodany w programie Visual Studio 2022 Eksplorator rozwiązań
Aplikację z wieloma kontenerami można wdrożyć przy użyciu jednego pliku docker-compose.yml za pomocą docker-compose up
polecenia . Jednak program Visual Studio dodaje grupę z nich, aby można było zastąpić wartości w zależności od środowiska (programowania lub produkcji) i typu wykonywania (wydanie lub debugowanie). Ta funkcja zostanie wyjaśniona w kolejnych sekcjach.
Krok 5. Kompilowanie i uruchamianie aplikacji platformy Docker
Jeśli aplikacja ma tylko jeden kontener, możesz ją uruchomić, wdrażając ją na hoście platformy Docker (maszynie wirtualnej lub serwerze fizycznym). Jeśli jednak aplikacja zawiera wiele usług, możesz wdrożyć ją jako skomponowaną aplikację przy użyciu jednego polecenia interfejsu wiersza polecenia (docker-compose up)
lub programu Visual Studio, które będzie używać tego polecenia w ramach okładek. Przyjrzyjmy się różnym opcjom.
Opcja A: Uruchamianie aplikacji z jednym kontenerem
Korzystanie z interfejsu wiersza polecenia platformy Docker
Kontener platformy Docker można uruchomić przy użyciu polecenia , jak pokazano na rysunku docker run
5–9:
docker run -t -d -p 80:5000 cesardl/netcore-webapi-microservice-docker:first
Powyższe polecenie spowoduje utworzenie nowego wystąpienia kontenera na podstawie określonego obrazu przy każdym uruchomieniu. Możesz użyć parametru --name
, aby nadać nazwę kontenerowi, a następnie użyć docker start {name}
(lub użyć identyfikatora kontenera lub nazwy automatycznej), aby uruchomić istniejące wystąpienie kontenera.
Rysunek 5–9. Uruchamianie kontenera platformy Docker przy użyciu polecenia docker run
W takim przypadku polecenie wiąże wewnętrzny port 5000 kontenera z portem 80 maszyny hosta. Oznacza to, że host nasłuchuje na porcie 80 i przekazuje do portu 5000 w kontenerze.
Pokazany skrót to identyfikator kontenera i jest również przypisywana losowa nazwa do odczytu, jeśli --name
opcja nie jest używana.
Korzystanie z programu Visual Studio
Jeśli nie dodano obsługi orkiestratora kontenerów, możesz również uruchomić pojedynczą aplikację kontenera w programie Visual Studio, naciskając Ctrl+F5, a także użyć F5 do debugowania aplikacji w kontenerze. Kontener działa lokalnie przy użyciu uruchamiania platformy Docker.
Opcja B: uruchamianie aplikacji z wieloma kontenerami
W większości scenariuszy przedsiębiorstwa aplikacja platformy Docker będzie składać się z wielu usług, co oznacza, że musisz uruchomić aplikację z wieloma kontenerami, jak pokazano na rysunku 5–10.
Rysunek 5–10. Maszyna wirtualna z wdrożonym kontenerem platformy Docker
Korzystanie z interfejsu wiersza polecenia platformy Docker
Aby uruchomić aplikację z wieloma kontenerami za pomocą interfejsu wiersza polecenia platformy Docker, użyj docker-compose up
polecenia . To polecenie używa pliku docker-compose.yml , który jest na poziomie rozwiązania, aby wdrożyć aplikację z wieloma kontenerami. Rysunek 5–11 przedstawia wyniki podczas uruchamiania polecenia z głównego katalogu rozwiązań, który zawiera plik docker-compose.yml.
Rysunek 5–11. Przykładowe wyniki podczas uruchamiania polecenia docker-compose up
Po uruchomieniu polecenia docker-compose up aplikacja i powiązane z nią kontenery są wdrażane na hoście platformy Docker, jak pokazano na rysunku 5–10.
Korzystanie z programu Visual Studio
Uruchamianie aplikacji wielokontenerowej przy użyciu programu Visual Studio 2019 nie może być prostsze. Wystarczy nacisnąć Ctrl+F5, aby uruchomić polecenie lub F5 w celu debugowania, jak zwykle, skonfigurowania projektu docker-compose jako projektu startowego. Program Visual Studio obsługuje całą wymaganą konfigurację, dzięki czemu można tworzyć punkty przerwania w zwykły sposób i debugować, co ostatecznie stanie się niezależnymi procesami uruchomionymi na "serwerach zdalnych", a debuger jest już dołączony.
Jak wspomniano wcześniej, za każdym razem, gdy dodasz obsługę rozwiązania platformy Docker do projektu w ramach rozwiązania, ten projekt jest skonfigurowany w pliku globalnym (na poziomie rozwiązania) docker-compose.yml, który umożliwia uruchamianie lub debugowanie całego rozwiązania jednocześnie. Program Visual Studio uruchomi jeden kontener dla każdego projektu z włączoną obsługą rozwiązania Platformy Docker i wykona wszystkie kroki wewnętrzne (dotnet publish, docker build itp.).
Jeśli chcesz przyjrzeć się w ogóle drudgery, spójrz na plik:
{root solution folder}\obj\Docker\docker-compose.vs.debug.g.yml
Ważnym punktem jest to, że, jak pokazano na rysunku 5-12, w programie Visual Studio 2019 istnieje dodatkowe polecenie platformy Docker dla akcji F5. Ta opcja umożliwia uruchamianie lub debugowanie aplikacji z wieloma kontenerami przez uruchomienie wszystkich kontenerów zdefiniowanych w plikach docker-compose.yml na poziomie rozwiązania. Możliwość debugowania rozwiązań z wieloma kontenerami oznacza, że można ustawić kilka punktów przerwania, każdy punkt przerwania w innym projekcie (kontenerze), a podczas debugowania z programu Visual Studio zatrzymasz punkty przerwania zdefiniowane w różnych projektach i uruchomione w różnych kontenerach.
Rysunek 5–12. Uruchamianie aplikacji wielokontenerowych w programie Visual Studio 2022
Dodatkowe zasoby
- Wdrażanie kontenera ASP.NET na zdalnym hoście platformy Docker
https://learn.microsoft.com/visualstudio/containers/hosting-web-apps-in-docker
Uwaga dotycząca testowania i wdrażania za pomocą orkiestratorów
Polecenia docker-compose up i docker run (lub uruchamiania i debugowania kontenerów w programie Visual Studio) są odpowiednie do testowania kontenerów w środowisku projektowym. Nie należy jednak używać tego podejścia do wdrożeń produkcyjnych, w których należy kierować koordynatorów, takich jak Kubernetes lub Service Fabric. Jeśli używasz platformy Kubernetes, musisz użyć zasobników do organizowania kontenerów i usług w celu ich sieci. Wdrożenia są również używane do organizowania tworzenia i modyfikowania zasobnika.
Krok 6. Testowanie aplikacji platformy Docker przy użyciu lokalnego hosta platformy Docker
Ten krok będzie się różnić w zależności od tego, co robi aplikacja. W prostej aplikacji internetowej platformy .NET wdrożonej jako pojedynczy kontener lub usługa można uzyskać dostęp do usługi, otwierając przeglądarkę na hoście platformy Docker i przechodząc do tej witryny, jak pokazano na rysunku 5–13. (Jeśli konfiguracja w pliku Dockerfile mapuje kontener na port na hoście innym niż 80, dołącz port hosta w adresie URL).
Rysunek 5–13. Przykład testowania aplikacji platformy Docker lokalnie przy użyciu hosta lokalnego
Jeśli localhost nie wskazuje na adres IP hosta platformy Docker (domyślnie w przypadku korzystania z usługi Docker CE), aby przejść do usługi, użyj adresu IP karty sieciowej twojej maszyny.
Ten adres URL w przeglądarce używa portu 80 dla omawianego przykładu określonego kontenera. Jednak wewnętrznie żądania są przekierowywane do portu 5000, ponieważ było to sposób wdrażania za pomocą polecenia docker run, jak wyjaśniono w poprzednim kroku.
Aplikację można również przetestować przy użyciu narzędzia curl z poziomu terminalu, jak pokazano na rysunku 5–14. W instalacji platformy Docker w systemie Windows domyślny adres IP hosta platformy Docker to zawsze 10.0.75.1 oprócz rzeczywistego adresu IP maszyny.
Rysunek 5–14. Przykład testowania aplikacji platformy Docker lokalnie przy użyciu narzędzia curl
Testowanie i debugowanie kontenerów za pomocą programu Visual Studio 2022
Podczas uruchamiania i debugowania kontenerów za pomocą programu Visual Studio 2022 można debugować aplikację .NET w taki sam sposób, jak w przypadku uruchamiania bez kontenerów.
Testowanie i debugowanie bez programu Visual Studio
Jeśli tworzysz rozwiązanie przy użyciu edytora/interfejsu wiersza polecenia, debugowanie kontenerów jest trudniejsze i prawdopodobnie chcesz debugować, generując ślady.
Dodatkowe zasoby
Szybki start: platforma Docker w programie Visual Studio.
https://learn.microsoft.com/visualstudio/containers/container-toolsDebugowanie aplikacji w lokalnym kontenerze platformy Docker
https://learn.microsoft.com/visualstudio/containers/edit-and-refresh
Uproszczony przepływ pracy podczas tworzenia kontenerów za pomocą programu Visual Studio
W rzeczywistości przepływ pracy w przypadku korzystania z programu Visual Studio jest znacznie prostszy niż w przypadku korzystania z podejścia edytora/interfejsu wiersza polecenia. Większość kroków wymaganych przez platformę Docker związanych z plikiem Dockerfile i docker-compose.yml jest ukryta lub uproszczona przez program Visual Studio, jak pokazano na rysunku 5–15.
Proces programowania aplikacji platformy Docker: 1 — Kodowanie aplikacji, 2 — Pisanie pliku Dockerfile/s, 3 — Tworzenie obrazów zdefiniowanych w pliku Dockerfile/s, 4 — (opcjonalnie) Tworzenie usług w pliku docker-compose.yml, 5 — Uruchamianie kontenera lub aplikacji docker-compose, 6 — Testowanie aplikacji lub mikrousług, 7 — Wypychanie do repozytorium i powtarzanie.
Rysunek 5–15. Uproszczony przepływ pracy podczas opracowywania za pomocą programu Visual Studio
Ponadto należy wykonać krok 2 (dodanie obsługi platformy Docker do projektów) tylko raz. W związku z tym przepływ pracy jest podobny do zwykłych zadań programistycznych podczas korzystania z platformy .NET w przypadku dowolnego innego programowania. Musisz wiedzieć, co się dzieje w ramach okładek (proces kompilacji obrazu, jakie obrazy podstawowe są używane, wdrażanie kontenerów itp.), a czasami trzeba będzie również edytować plik Dockerfile lub docker-compose.yml w celu dostosowania zachowań. Jednak większość pracy jest znacznie uproszczona dzięki użyciu programu Visual Studio, co znacznie bardziej wydajne.
Konfigurowanie kontenerów systemu Windows przy użyciu poleceń programu PowerShell w pliku Dockerfile
Kontenery systemu Windows umożliwiają konwertowanie istniejących aplikacji systemu Windows na obrazy platformy Docker i wdrażanie ich przy użyciu tych samych narzędzi co reszta ekosystemu platformy Docker. Aby użyć kontenerów systemu Windows, uruchom polecenia programu PowerShell w pliku Dockerfile, jak pokazano w poniższym przykładzie:
FROM mcr.microsoft.com/windows/servercore
LABEL Description="IIS" Vendor="Microsoft" Version="10"
RUN powershell -Command Add-WindowsFeature Web-Server
CMD [ "ping", "localhost", "-t" ]
W tym przypadku używamy obrazu podstawowego systemu Windows Server Core (ustawienie FROM) i instalujemy usługi IIS za pomocą polecenia programu PowerShell (ustawienie URUCHOM). W podobny sposób można również użyć poleceń programu PowerShell, aby skonfigurować dodatkowe składniki, takie jak ASP.NET 4.x, .NET Framework 4.6 lub inne oprogramowanie systemu Windows. Na przykład następujące polecenie w pliku Dockerfile konfiguruje ASP.NET 4.5:
RUN powershell add-windowsfeature web-asp-net45
Dodatkowe zasoby
- aspnet-docker/Dockerfile. Przykładowe polecenia programu PowerShell do uruchamiania z plików dockerfile w celu uwzględnienia funkcji systemu Windows.
https://github.com/Microsoft/aspnet-docker/blob/master/4.7.1-windowsservercore-ltsc2016/runtime/Dockerfile