Konteneryzowanie aplikacji .NET za pomocą polecenia dotnet publish
Kontenery mają wiele funkcji i korzyści, takich jak niezmienna infrastruktura, zapewniając przenośną architekturę i umożliwiająca skalowalność. Obraz może służyć do tworzenia kontenerów dla lokalnego środowiska deweloperskiego, chmury prywatnej lub chmury publicznej. Z tego samouczka dowiesz się, jak konteneryzować aplikację .NET przy użyciu polecenia dotnet publish .
Wymagania wstępne
Zainstaluj następujące wymagania wstępne:
- Zestaw .NET 8+ SDK
Jeśli masz zainstalowaną platformędotnet --info
.NET, użyj polecenia , aby określić, którego zestawu SDK używasz. - Docker Community Edition
- Zestaw .NET 7+ SDK
Jeśli masz zainstalowaną platformędotnet --info
.NET, użyj polecenia , aby określić, którego zestawu SDK używasz. - Docker Community Edition
Oprócz tych wymagań wstępnych zaleca się zapoznanie się z usługami roboczymi na platformie .NET.
Tworzenie aplikacji .NET
Potrzebujesz aplikacji .NET do konteneryzowania, więc zacznij od utworzenia nowej aplikacji na podstawie szablonu. Otwórz terminal, utwórz folder roboczy (sample-directory), jeśli jeszcze tego nie zrobiono, i zmień katalogi, aby się w nim znajdować. W folderze roboczym uruchom następujące polecenie, aby utworzyć nowy projekt w podkatalogu o nazwie Worker:
dotnet new worker -o Worker -n DotNet.ContainerImage
Drzewo folderów wygląda następująco:
📁 sample-directory
└──📂 Worker
├──appsettings.Development.json
├──appsettings.json
├──DotNet.ContainerImage.csproj
├──Program.cs
├──Worker.cs
└──📂 obj
├── DotNet.ContainerImage.csproj.nuget.dgspec.json
├── DotNet.ContainerImage.csproj.nuget.g.props
├── DotNet.ContainerImage.csproj.nuget.g.targets
├── project.assets.json
└── project.nuget.cache
Polecenie dotnet new
tworzy nowy folder o nazwie Worker i generuje usługę procesu roboczego, która po uruchomieniu rejestruje komunikat co sekundę. Z poziomu sesji terminalu zmień katalogi i przejdź do folderu Proces roboczy . dotnet run
Użyj polecenia , aby uruchomić aplikację.
dotnet run
Building...
info: DotNet.ContainerImage.Worker[0]
Worker running at: 10/18/2022 08:56:00 -05:00
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path: .\Worker
info: DotNet.ContainerImage.Worker[0]
Worker running at: 10/18/2022 08:56:01 -05:00
info: DotNet.ContainerImage.Worker[0]
Worker running at: 10/18/2022 08:56:02 -05:00
info: DotNet.ContainerImage.Worker[0]
Worker running at: 10/18/2022 08:56:03 -05:00
info: Microsoft.Hosting.Lifetime[0]
Application is shutting down...
Attempting to cancel the build...
Szablon procesu roboczego zapętla się w nieskończoność. Użyj polecenia anuluj Ctrl+C , aby go zatrzymać.
Dodawanie pakietu NuGet
Pakiet NuGet Microsoft.NET.Build.Containers jest obecnie wymagany do publikowania projektów innych niż web jako kontener. Aby dodać Microsoft.NET.Build.Containers
pakiet NuGet do szablonu procesu roboczego, uruchom następujące polecenie dotnet add package :
dotnet add package Microsoft.NET.Build.Containers
Napiwek
Jeśli tworzysz aplikację internetową i używasz zestawu .NET SDK 7.0.300 lub nowszego, pakiet nie jest wymagany — zestaw SDK zawiera te same funkcje gotowe do użycia.
Ustawianie nazwy obrazu kontenera
Podczas publikowania aplikacji jako kontenera są dostępne różne opcje konfiguracji.
Domyślnie nazwa obrazu kontenera to AssemblyName
projekt. Jeśli ta nazwa jest nieprawidłowa jako nazwa obrazu kontenera, możesz ją zastąpić, określając element ContainerRepository
, jak pokazano w następującym pliku projektu:
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>dotnet-DotNet.ContainerImage-2e40c179-a00b-4cc9-9785-54266210b7eb</UserSecretsId>
<ContainerRepository>dotnet-worker-image</ContainerRepository>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
</ItemGroup>
</Project>
Aby uzyskać więcej informacji, zobacz ContainerRepository.
Domyślnie nazwa obrazu kontenera to AssemblyName
projekt. Jeśli ta nazwa jest nieprawidłowa jako nazwa obrazu kontenera, możesz ją zastąpić, określając wartość (ContainerImageName
przestarzałą) lub preferowaną ContainerRepository
, jak pokazano w następującym pliku projektu:
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>dotnet-DotNet.ContainerImage-2e40c179-a00b-4cc9-9785-54266210b7eb</UserSecretsId>
<ContainerImageName>dotnet-worker-image</ContainerImageName>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
<PackageReference Include="Microsoft.NET.Build.Containers" Version="7.0.401" />
</ItemGroup>
</Project>
Aby uzyskać więcej informacji, zobacz ContainerImageName.
Publikowanie aplikacji .NET
Aby opublikować aplikację .NET jako kontener, użyj następującego polecenia dotnet publish :
dotnet publish --os linux --arch x64 /t:PublishContainer -c Release
Poprzednie polecenie interfejsu wiersza polecenia platformy .NET publikuje aplikację jako kontener:
- Określanie wartości docelowej systemu operacyjnego Linux (
--os linux
). - Określanie architektury x64 (
--arch x64
). - Przy użyciu konfiguracji wydania (
-c Release
).
Ważne
Aby utworzyć kontener lokalnie, musisz mieć uruchomiony demon platformy Docker. Jeśli nie jest uruchomiona podczas próby opublikowania aplikacji jako kontenera, wystąpi błąd podobny do następującego:
..\build\Microsoft.NET.Build.Containers.targets(66,9): error MSB4018:
The "CreateNewImage" task failed unexpectedly. [..\Worker\DotNet.ContainerImage.csproj]
Napiwek
W zależności od typu aplikacji, którą konteneryzujesz, przełączniki wiersza polecenia (opcje) mogą się różnić. Na przykład /t:PublishContainer
argument jest wymagany tylko dla aplikacji platformy .NET innych niż internetowe, takich jak console
i worker
szablony. W przypadku szablonów internetowych zastąp /t:PublishContainer
argument argumentem -p:PublishProfile=DefaultContainer
. Aby uzyskać więcej informacji, zobacz kompilacje kontenerów zestawu SDK platformy .NET, problem nr 141.
Polecenie generuje dane wyjściowe podobne do przykładowych danych wyjściowych:
Determining projects to restore...
All projects are up-to-date for restore.
DotNet.ContainerImage -> .\Worker\bin\Release\net8.0\linux-x64\DotNet.ContainerImage.dll
DotNet.ContainerImage -> .\Worker\bin\Release\net8.0\linux-x64\publish\
Building image 'dotnet-worker-image' with tags latest on top of base image mcr.microsoft.com/dotnet/aspnet:8.0
Pushed container 'dotnet-worker-image:latest' to Docker daemon
Determining projects to restore...
All projects are up-to-date for restore.
DotNet.ContainerImage -> .\Worker\bin\Release\net7.0\linux-x64\DotNet.ContainerImage.dll
DotNet.ContainerImage -> .\Worker\bin\Release\net7.0\linux-x64\publish\
Building image 'dotnet-worker-image' with tags 1.0.0 on top of base image mcr.microsoft.com/dotnet/aspnet:7.0
Pushed container 'dotnet-worker-image:1.0.0' to Docker daemon
To polecenie kompiluje aplikację procesu roboczego do folderu publikowania i wypycha kontener do lokalnego rejestru platformy Docker.
Konfigurowanie obrazu kontenera
Możesz kontrolować wiele aspektów wygenerowanego kontenera za pomocą właściwości programu MSBuild. Ogólnie rzecz biorąc, jeśli możesz użyć polecenia w pliku Dockerfile w celu ustawienia konfiguracji, możesz to zrobić za pośrednictwem programu MSBuild.
Uwaga
Jedynymi wyjątkami od tego są RUN
polecenia. Ze względu na sposób tworzenia kontenerów nie można ich emulować. Jeśli potrzebujesz tej funkcji, musisz użyć pliku Dockerfile do skompilowania obrazów kontenerów.
ContainerArchiveOutputPath
Począwszy od platformy .NET 8, można utworzyć kontener bezpośrednio jako archiwum tar.gz . Ta funkcja jest przydatna, jeśli przepływ pracy nie jest prosty i wymaga na przykład uruchomienia narzędzia do skanowania obrazów przed ich wypchnięciem. Po utworzeniu archiwum można go przenieść, zeskanować lub załadować do lokalnego łańcucha narzędzi platformy Docker.
Aby opublikować w archiwum, dodaj ContainerArchiveOutputPath
właściwość do polecenia dotnet publish
, na przykład:
dotnet publish \
-p PublishProfile=DefaultContainer \
-p ContainerArchiveOutputPath=./images/sdk-container-demo.tar.gz
Możesz określić nazwę folderu lub ścieżkę o określonej nazwie pliku. Jeśli określisz nazwę folderu, nazwa pliku wygenerowana dla pliku archiwum obrazów będzie mieć wartość $(ContainerRepository).tar.gz
. Te archiwa mogą zawierać wiele tagów wewnątrz nich, tylko w przypadku utworzenia pojedynczego pliku dla wszystkich ContainerImageTags
elementów .
Konfiguracja nazewnictwa obrazów kontenera
Obrazy kontenerów są zgodne z konkretną konwencją nazewnictwa. Nazwa obrazu składa się z kilku części, rejestru, opcjonalnego portu, repozytorium oraz opcjonalnego tagu i rodziny.
REGISTRY[:PORT]/REPOSITORY[:TAG[-FAMILY]]
Rozważmy na przykład w pełni kwalifikowaną mcr.microsoft.com/dotnet/runtime:8.0-alpine
nazwę obrazu:
mcr.microsoft.com
jest rejestrem (a w tym przypadku reprezentuje rejestr kontenerów firmy Microsoft).dotnet/runtime
to repozytorium (ale niektórzy uważają to zauser/repository
).8.0-alpine
to tag i rodzina (rodzina jest opcjonalnym specyfikatorem, który pomaga uściślać pakowanie systemu operacyjnego).
Niektóre właściwości opisane w poniższych sekcjach odpowiadają zarządzaniu częściami wygenerowanej nazwy obrazu. Rozważmy następującą tabelę, która mapuje relację między nazwą obrazu a właściwościami kompilacji:
Część nazwy obrazu | Właściwość MSBuild | Przykładowe wartości |
---|---|---|
REGISTRY[:PORT] |
ContainerRegistry |
mcr.microsoft.com:443 |
PORT |
ContainerPort |
:443 |
REPOSITORY |
ContainerRepository |
dotnet/runtime |
TAG |
ContainerImageTag |
8.0 |
FAMILY |
ContainerFamily |
-alpine |
Część nazwy obrazu | Właściwość MSBuild | Przykładowe wartości |
---|---|---|
REGISTRY[:PORT] |
ContainerRegistry |
mcr.microsoft.com:443 |
PORT |
ContainerPort |
:443 |
REPOSITORY |
ContainerImageName |
dotnet/runtime |
TAG |
ContainerImageTag |
8.0 |
W poniższych sekcjach opisano różne właściwości, których można użyć do kontrolowania wygenerowanego obrazu kontenera.
ContainerBaseImage
Właściwość obrazu podstawowego kontenera kontroluje obraz używany jako podstawa obrazu. Domyślnie następujące wartości są wnioskowane na podstawie właściwości projektu:
- Jeśli projekt jest samodzielny,
mcr.microsoft.com/dotnet/runtime-deps
obraz jest używany jako obraz podstawowy. - Jeśli projekt jest projektem ASP.NET Core,
mcr.microsoft.com/dotnet/aspnet
obraz jest używany jako obraz podstawowy. mcr.microsoft.com/dotnet/runtime
W przeciwnym razie obraz jest używany jako obraz podstawowy.
Tag obrazu jest wnioskowany jako składnik liczbowy wybranego TargetFramework
elementu . Na przykład docelowy projekt net6.0
powoduje wyświetlenie 6.0
tagu wnioskowanego obrazu podstawowego, a net7.0-linux
projekt używa tagu 7.0
itd.
Jeśli ustawisz tutaj wartość, należy ustawić w pełni kwalifikowaną nazwę obrazu, która będzie używana jako podstawa, w tym dowolny tag:
<PropertyGroup>
<ContainerBaseImage>mcr.microsoft.com/dotnet/runtime:8.0</ContainerBaseImage>
</PropertyGroup>
<PropertyGroup>
<ContainerBaseImage>mcr.microsoft.com/dotnet/runtime:7.0</ContainerBaseImage>
</PropertyGroup>
ContainerFamily
Począwszy od platformy .NET 8, możesz użyć ContainerFamily
właściwości MSBuild, aby wybrać inną rodzinę obrazów kontenerów udostępnianych przez firmę Microsoft jako podstawowy obraz aplikacji. Po ustawieniu ta wartość jest dołączana na końcu wybranego tagu specyficznego dla programu TFM, zmieniając podany tag. Aby na przykład użyć wariantów alpine Linux obrazów podstawowych platformy .NET, można ustawić wartość ContainerFamily
alpine
:
<PropertyGroup>
<ContainerFamily>alpine</ContainerFamily>
</PropertyGroup>
Poprzednia konfiguracja projektu powoduje wyświetlenie końcowego tagu 8.0-alpine
dla aplikacji przeznaczonej dla platformy .NET 8.
To pole jest wolne i często może służyć do wybierania różnych dystrybucji systemu operacyjnego, domyślnych konfiguracji pakietów lub innych zmian w obrazie podstawowym. To pole jest ignorowane po ContainerBaseImage
ustawieniu. Aby uzyskać więcej informacji, zobacz Obrazy kontenerów platformy .NET.
ContainerRuntimeIdentifier
Właściwość identyfikatora środowiska uruchomieniowego kontenera kontroluje system operacyjny i architekturę używaną przez kontener, jeśli kontener ContainerBaseImage obsługuje więcej niż jedną platformę. Na przykład mcr.microsoft.com/dotnet/runtime
obraz obsługuje linux-x64
obecnie obrazy , linux-arm64
linux-arm
i i win10-x64
za tym samym tagiem, więc narzędzia wymagają sposobu poinformowania, które z tych wersji mają być używane. Domyślnie jest to ustawienie wartości wybranej RuntimeIdentifier
podczas publikowania kontenera. Ta właściwość rzadko musi być ustawiana jawnie — zamiast tego należy użyć -r
opcji do dotnet publish
polecenia . Jeśli wybrany obraz nie obsługuje wybranego RuntimeIdentifier
obrazu, powoduje wystąpienie błędu opisującego element RuntimeIdentifiers, który obsługuje obraz.
Zawsze można ustawić ContainerBaseImage
właściwość na w pełni kwalifikowaną nazwę obrazu, w tym tag, aby uniknąć konieczności używania tej właściwości w ogóle.
<PropertyGroup>
<ContainerRuntimeIdentifier>linux-arm64</ContainerRuntimeIdentifier>
</PropertyGroup>
Aby uzyskać więcej informacji na temat identyfikatorów środowiska uruchomieniowego obsługiwanych przez platformę .NET, zobacz Wykaz identyfikatorów RID.
ContainerRegistry
Właściwość rejestru kontenerów kontroluje rejestr docelowy. Miejsce, do którego zostanie wypchnięty nowo utworzony obraz. Domyślnie jest on wypychany do lokalnego demona platformy Docker, ale można również określić rejestr zdalny. W przypadku korzystania z rejestru zdalnego, który wymaga uwierzytelniania, należy uwierzytelnić się przy użyciu dobrze znanych docker login
mechanizmów. Aby uzyskać więcej informacji, zobacz Uwierzytelnianie w rejestrach kontenerów , aby uzyskać więcej informacji. Aby uzyskać konkretny przykład użycia tej właściwości, rozważmy następujący przykład XML:
<PropertyGroup>
<ContainerRegistry>registry.mycorp.com:1234</ContainerRegistry>
</PropertyGroup>
To narzędzie obsługuje publikowanie w dowolnym rejestrze, który obsługuje interfejs API HTTP rejestru platformy Docker w wersji 2. Obejmuje to jawnie następujące rejestry (i prawdopodobnie znacznie więcej niejawnie):
- Azure Container Registry
- Amazon Elastic Container Registry
- Rejestr artefaktów Google
- Docker Hub
- Pakiety GitHub
- Usługa GitLab hostowana w usłudze Container Registry
- Quay.io
Uwagi dotyczące pracy z tymi rejestrami można znaleźć w uwagach specyficznych dla rejestru.
ContainerRepository
Repozytorium kontenerów jest nazwą samego obrazu, na przykład dotnet/runtime
lub my-app
. Domyślnie AssemblyName
jest używany projekt.
<PropertyGroup>
<ContainerRepository>my-app</ContainerRepository>
</PropertyGroup>
ContainerImageName
Nazwa obrazu kontenera kontroluje nazwę samego obrazu, na przykład dotnet/runtime
lub my-app
. Domyślnie AssemblyName
jest używany projekt.
<PropertyGroup>
<ContainerImageName>my-app</ContainerImageName>
</PropertyGroup>
Uwaga
Począwszy od platformy .NET 8, ContainerImageName
jest przestarzały na rzecz .ContainerRepository
Nazwy obrazów składają się z co najmniej jednego segmentu rozdzielanego ukośnikiem, z których każda może zawierać tylko małe litery alfanumeryczne znaki, kropki, podkreślenia i kreski, i musi zaczynać się literą lub cyfrą. Wszelkie inne znaki powodują zgłoszenie błędu.
ContainerImageTag(s)
Właściwość tagu obrazu kontenera steruje tagami wygenerowanymi dla obrazu. Aby określić użycie ContainerImageTag
pojedynczego tagu, a w przypadku wielu tagów użyj polecenia ContainerImageTags
.
Ważne
Gdy używasz metody ContainerImageTags
, będziesz mieć wiele obrazów, po jednym na unikatowy tag.
Tagi są często używane do odwoływania się do różnych wersji aplikacji, ale mogą również odwoływać się do różnych dystrybucji systemu operacyjnego, a nawet różnych konfiguracji.
Począwszy od platformy .NET 8, jeśli tag nie jest podany, wartość domyślna to latest
.
Domyślnie Version
projekt jest używany jako wartość tagu.
Aby zastąpić wartość domyślną, określ jedną z następujących wartości:
<PropertyGroup>
<ContainerImageTag>1.2.3-alpha2</ContainerImageTag>
</PropertyGroup>
Aby określić wiele tagów, użyj rozdzielanego średnikami zestawu tagów we ContainerImageTags
właściwości, podobnie jak w przypadku ustawienia wielu TargetFrameworks
:
<PropertyGroup>
<ContainerImageTags>1.2.3-alpha2;latest</ContainerImageTags>
</PropertyGroup>
Tagi mogą zawierać maksymalnie 127 znaków alfanumerycznych, kropki, podkreślenia i kreski. Muszą zaczynać się od znaku alfanumerycznego lub podkreślenia. Każdy inny formularz powoduje zgłoszenie błędu.
Uwaga
W przypadku używania ContainerImageTags
tagów są rozdzielane znakiem ;
. Jeśli wywołujesz wywołanie dotnet publish
z wiersza polecenia (tak jak w przypadku większości środowisk ciągłej integracji/ciągłego wdrażania), musisz owinąć zewnętrzne wartości w jednym '
i wewnętrznym zawijanie podwójnymi cudzysłowami "
, na przykład (='"tag-1;tag-2"'
). Rozważ następujące dotnet publish
polecenie:
dotnet publish -p ContainerImageTags='"1.2.3-alpha2;latest"'
Spowoduje to wygenerowanie dwóch obrazów: my-app:1.2.3-alpha2
i my-app:latest
.
Napiwek
Jeśli wystąpią problemy z ContainerImageTags
właściwością, rozważ określenie zakresu zmiennej ContainerImageTags
środowiskowej:
ContainerImageTags='1.2.3;latest' dotnet publish
ContainerLabel
Etykieta kontenera dodaje etykietę metadanych do kontenera. Etykiety nie mają wpływu na kontener w czasie wykonywania, ale są często używane do przechowywania wersji i tworzenia metadanych do użycia przez skanery zabezpieczeń i inne narzędzia infrastruktury. Można określić dowolną liczbę etykiet kontenera.
Węzeł ContainerLabel
ma dwa atrybuty:
Include
: klucz etykiety.Value
: wartość etykiety (może być pusta).
<ItemGroup>
<ContainerLabel Include="org.contoso.businessunit" Value="contoso-university" />
</ItemGroup>
Aby uzyskać listę etykiet, które są tworzone domyślnie, zobacz domyślne etykiety kontenerów.
Konfigurowanie wykonywania kontenera
Aby kontrolować wykonywanie kontenera, możesz użyć następujących właściwości programu MSBuild.
ContainerWorkingDirectory
Węzeł katalogu roboczego kontenera kontroluje katalog roboczy kontenera, katalog, w ramach którego są wykonywane polecenia, jeśli nie zostanie uruchomione inne polecenie.
Domyślnie /app
wartość katalogu jest używana jako katalog roboczy.
<PropertyGroup>
<ContainerWorkingDirectory>/bin</ContainerWorkingDirectory>
</PropertyGroup>
ContainerPort
Port kontenera dodaje porty TCP lub UDP do listy znanych portów kontenera. Dzięki temu środowiska uruchomieniowe kontenera, takie jak Platforma Docker, automatycznie mapują te porty na maszynę hosta. Jest to często używane jako dokumentacja kontenera, ale może być również używane do włączania automatycznego mapowania portów.
Węzeł ContainerPort
ma dwa atrybuty:
Include
: numer portu do uwidocznienia.Type
: Wartości domyślne totcp
, prawidłowe wartości totcp
lubudp
.
<ItemGroup>
<ContainerPort Include="80" Type="tcp" />
</ItemGroup>
Począwszy od platformy .NET 8, element jest wnioskowany, ContainerPort
gdy nie jest jawnie udostępniany na podstawie kilku dobrze znanych ASP.NET zmiennych środowiskowych:
ASPNETCORE_URLS
ASPNETCORE_HTTP_PORTS
ASPNETCORE_HTTPS_PORTS
Jeśli te zmienne środowiskowe są obecne, ich wartości są analizowane i konwertowane na mapowania portów TCP. Te zmienne środowiskowe są odczytywane z obrazu podstawowego, jeśli istnieje, lub ze zmiennych środowiskowych zdefiniowanych w projekcie za pośrednictwem ContainerEnvironmentVariable
elementów. Aby uzyskać więcej informacji, zobacz ContainerEnvironmentVariable.
ContainerEnvironmentVariable
Węzeł zmiennej środowiskowej kontenera umożliwia dodawanie zmiennych środowiskowych do kontenera. Zmienne środowiskowe są natychmiast dostępne dla aplikacji uruchomionej w kontenerze i często są używane do zmiany zachowania w czasie wykonywania uruchomionej aplikacji.
Węzeł ContainerEnvironmentVariable
ma dwa atrybuty:
Include
: nazwa zmiennej środowiskowej.Value
: wartość zmiennej środowiskowej.
<ItemGroup>
<ContainerEnvironmentVariable Include="LOGGER_VERBOSITY" Value="Trace" />
</ItemGroup>
Aby uzyskać więcej informacji, zobacz Zmienne środowiskowe platformy .NET.
Konfigurowanie poleceń kontenera
Domyślnie narzędzia kontenera uruchamiają aplikację przy użyciu wygenerowanego pliku binarnego AppHost dla aplikacji (jeśli aplikacja używa elementu AppHost) lub dotnet
polecenia oraz biblioteki DLL aplikacji.
Możesz jednak kontrolować sposób wykonywania aplikacji przy użyciu kombinacji elementów ContainerAppCommand
, ContainerAppCommandArgs
, ContainerDefaultArgs
i ContainerAppCommandInstruction
.
Te różne punkty konfiguracji istnieją, ponieważ różne obrazy podstawowe używają różnych kombinacji kontenera ENTRYPOINT
i COMMAND
właściwości i chcesz mieć możliwość obsługi wszystkich z nich. Wartości domyślne powinny być używane dla większości aplikacji, ale jeśli chcesz dostosować zachowanie uruchamiania aplikacji, należy:
- Zidentyfikuj plik binarny do uruchomienia i ustaw go jako
ContainerAppCommand
- Określ, które argumenty są wymagane do uruchomienia aplikacji, i ustaw je jako
ContainerAppCommandArgs
- Zidentyfikuj, które argumenty (jeśli istnieją) są opcjonalne i mogą zostać zastąpione przez użytkownika, i ustaw je jako
ContainerDefaultArgs
- Ustaw element
ContainerAppCommandInstruction
na wartośćDefaultArgs
Aby uzyskać więcej informacji, zobacz następujące elementy konfiguracji.
ContainerAppCommand
Element konfiguracji polecenia aplikacji jest logicznym punktem wejścia aplikacji. W przypadku większości aplikacji jest to host AppHost, wygenerowany plik binarny pliku wykonywalnego dla aplikacji. Jeśli aplikacja nie generuje elementu AppHost, to polecenie zazwyczaj będzie .dotnet <your project dll>
Te wartości są stosowane po dowolnym ENTRYPOINT
kontenerze podstawowym lub bezpośrednio, jeśli nie ENTRYPOINT
jest zdefiniowany.
Konfiguracja ContainerAppCommand
ma jedną Include
właściwość, która reprezentuje polecenie, opcję lub argument do użycia w poleceniu punktu wejścia:
<ItemGroup Label="ContainerAppCommand Assignment">
<!-- This is how you would start the dotnet ef tool in your container -->
<ContainerAppCommand Include="dotnet" />
<ContainerAppCommand Include="ef" />
<!-- This shorthand syntax means the same thing, note the semicolon separating the tokens. -->
<ContainerAppCommand Include="dotnet;ef" />
</ItemGroup>
ContainerAppCommandArgs
To polecenie aplikacji args element konfiguracji reprezentuje wszystkie logicznie wymagane argumenty dla aplikacji, które powinny być stosowane do .ContainerAppCommand
Domyślnie żadna z nich nie jest generowana dla aplikacji. Gdy jest obecny, args są stosowane do kontenera podczas jego uruchamiania.
Konfiguracja ContainerAppCommandArgs
ma jedną Include
właściwość, która reprezentuje opcję lub argument do zastosowania do ContainerAppCommand
polecenia.
<ItemGroup>
<!-- Assuming the ContainerAppCommand defined above,
this would be the way to force the database to update.
-->
<ContainerAppCommandArgs Include="database" />
<ContainerAppCommandArgs Include="update" />
<!-- This is the shorthand syntax for the same idea -->
<ContainerAppCommandArgs Include="database;update" />
</ItemGroup>
ContainerDefaultArgs
Ten domyślny element konfiguracji args reprezentuje wszystkie argumenty, które można zastąpić użytkownika dla aplikacji. Jest to dobry sposób zapewnienia domyślnych ustawień domyślnych, które aplikacja może wymagać uruchomienia w sposób, który ułatwia rozpoczęcie pracy, ale nadal jest łatwy do dostosowania.
Konfiguracja ContainerDefaultArgs
ma jedną Include
właściwość, która reprezentuje opcję lub argument do zastosowania do ContainerAppCommand
polecenia.
<ItemGroup>
<!-- Assuming the ContainerAppCommand defined above,
this would be the way to force the database to update.
-->
<ContainerDefaultArgs Include="database" />
<ContainerDefaultArgs Include="update" />
<!-- This is the shorthand syntax for the same idea -->
<ContainerDefaultArgs Include="database;update" />
</ItemGroup>
ContainerAppCommandInstruction
Konfiguracja instrukcji polecenia aplikacji pomaga kontrolować sposób, w jaki ContainerEntrypoint
polecenia , ContainerEntrypointArgs
, ContainerAppCommand
, ContainerAppCommandArgs
i ContainerDefaultArgs
są łączone w celu utworzenia końcowego polecenia, które jest uruchamiane w kontenerze. Zależy to znacznie od tego, czy element ENTRYPOINT
znajduje się na obrazie podstawowym. Ta właściwość przyjmuje jedną z trzech wartości: "DefaultArgs"
, lub "Entrypoint"
"None"
.
Entrypoint
:- W tym trybie punkt wejścia jest definiowany przez
ContainerAppCommand
,ContainerAppCommandArgs
iContainerDefaultArgs
.
- W tym trybie punkt wejścia jest definiowany przez
None
:- W tym trybie punkt wejścia jest definiowany przez
ContainerEntrypoint
,ContainerEntrypointArgs
iContainerDefaultArgs
.
- W tym trybie punkt wejścia jest definiowany przez
DefaultArgs
:- Jest to najbardziej złożony tryb — jeśli żaden z
ContainerEntrypoint[Args]
elementów nie istnieje, elementContainerAppCommand[Args]
iContainerDefaultArgs
jest używany do tworzenia punktu wejścia i polecenia. Punkt wejścia obrazu podstawowego dla obrazów podstawowych, które mają zakodowane w kodzie lubdotnet
/usr/bin/dotnet
został pominięty, aby mieć pełną kontrolę. - Jeśli oba
ContainerEntrypoint
elementy iContainerAppCommand
są obecne,ContainerEntrypoint
staje się punktem wejścia iContainerAppCommand
staje się poleceniem .
- Jest to najbardziej złożony tryb — jeśli żaden z
Uwaga
ContainerEntrypoint
Elementy konfiguracji i ContainerEntrypointArgs
zostały wycofane z platformy .NET 8.
Ważne
Jest to przeznaczone dla zaawansowanych aplikacji korzystających z większości użytkowników, które nie powinny dostosowywać punktu wejścia do tego stopnia. Aby uzyskać więcej informacji i jeśli chcesz podać przypadki użycia dla Twoich scenariuszy, zobacz GitHub: kontener .NET SDK tworzy dyskusje.
ContainerUser
Właściwość konfiguracji użytkownika steruje domyślnym użytkownikiem, na który działa kontener. Jest to często używane do uruchamiania kontenera jako użytkownik niebędący użytkownikiem głównym, co jest najlepszym rozwiązaniem w zakresie zabezpieczeń. Istnieje kilka ograniczeń dotyczących tej konfiguracji, o których należy pamiętać:
- Może to mieć różne formy — nazwa użytkownika, identyfikatory użytkownika systemu Linux, nazwa grupy, identyfikator grupy systemu Linux,
username:groupname
i inne warianty identyfikatorów. - Nie ma weryfikacji, czy określony użytkownik lub grupa istnieje na obrazie.
- Zmiana użytkownika może zmienić zachowanie aplikacji, zwłaszcza w odniesieniu do takich rzeczy, jak uprawnienia systemu plików.
Wartość domyślna tego pola różni się w zależności od programu PROJECT TFM i docelowego systemu operacyjnego:
- Jeśli wybierasz platformę .NET 8 lub nowszą i używasz obrazów środowiska uruchomieniowego firmy Microsoft, wykonaj następujące działania:
- w systemie Linux jest używany użytkownik
app
bez rootless (choć jest przywołyny przez jego identyfikator użytkownika) - w systemie Windows jest używany użytkownik
ContainerUser
bez rootless
- w systemie Linux jest używany użytkownik
- W przeciwnym razie nie jest używana żadna wartość domyślna
ContainerUser
<PropertyGroup>
<ContainerUser>my-existing-app-user</ContainerUser>
</PropertyGroup>
Napiwek
Zmienna APP_UID
środowiskowa służy do ustawiania informacji o użytkowniku w kontenerze. Ta wartość może pochodzić ze zmiennych środowiskowych zdefiniowanych w obrazie podstawowym (tak jak w przypadku obrazów platformy Microsoft .NET) lub można ustawić ją samodzielnie za pomocą ContainerEnvironmentVariable
składni.
Możesz jednak kontrolować sposób wykonywania aplikacji przy użyciu metod ContainerEntrypoint
i ContainerEntrypointArgs
.
ContainerEntrypoint
Punkt wejścia kontenera może służyć do dostosowywania ENTRYPOINT
kontenera, czyli pliku wykonywalnego wywoływanego podczas uruchamiania kontenera. Domyślnie w przypadku kompilacji, które tworzą hosta aplikacji, jest ono ustawione jako ContainerEntrypoint
. W przypadku kompilacji, które nie tworzą pliku wykonywalnego, dotnet path/to/app.dll
element jest używany jako .ContainerEntrypoint
Węzeł ContainerEntrypoint
ma jeden atrybut:
Include
: polecenie, opcja lub argument do użycia w poleceniuContainerEntrypoint
.
Rozważmy na przykład następującą przykładową grupę elementów projektu .NET:
<ItemGroup Label="Entrypoint Assignment">
<!-- This is how you would start the dotnet ef tool in your container -->
<ContainerEntrypoint Include="dotnet" />
<ContainerEntrypoint Include="ef" />
<!-- This shorthand syntax means the same thing.
Note the semicolon separating the tokens. -->
<ContainerEntrypoint Include="dotnet;ef" />
</ItemGroup>
ContainerEntrypointArgs
Węzeł args punktu wejścia kontenera steruje domyślnymi argumentami podanymi w obiekcie ContainerEntrypoint
. Powinno to być używane, gdy ContainerEntrypoint
jest to program, którego użytkownik może chcieć użyć samodzielnie. Domyślnie żadne nie ContainerEntrypointArgs
są tworzone w Twoim imieniu.
Węzeł ContainerEntrypointArg
ma jeden atrybut:
Include
: opcja lub argument, który ma być stosowany doContainerEntrypoint
polecenia .
Rozważmy następującą przykład grupę elementów projektu .NET:
<ItemGroup>
<!-- Assuming the ContainerEntrypoint defined above,
this would be the way to update the database by
default, but let the user run a different EF command. -->
<ContainerEntrypointArgs Include="database" />
<ContainerEntrypointArgs Include="update" />
<!-- This is the shorthand syntax for the same idea -->
<ContainerEntrypointArgs Include="database;update" />
</ItemGroup>
Domyślne etykiety kontenerów
Etykiety są często używane do zapewnienia spójnych metadanych na obrazach kontenerów. Ten pakiet udostępnia niektóre etykiety domyślne, aby zachęcić do lepszego utrzymania wygenerowanych obrazów.
org.opencontainers.image.created
jest ustawiona na format ISO 8601 bieżącego czasu UTCDateTime
.
Aby uzyskać więcej informacji, zobacz Implementowanie konwencjonalnych etykiet na podstawie istniejącej infrastruktury etykiet.
Czyszczenie zasobów
W tym artykule opublikowano proces roboczy platformy .NET jako obraz kontenera. Jeśli chcesz, usuń ten zasób. Użyj polecenia , docker images
aby wyświetlić listę zainstalowanych obrazów.
docker images
Rozważmy następujące przykładowe dane wyjściowe:
REPOSITORY TAG IMAGE ID CREATED SIZE
dotnet-worker-image 1.0.0 25aeb97a2e21 12 seconds ago 191MB
Napiwek
Pliki obrazów mogą być duże. Zazwyczaj można usunąć tymczasowe kontenery utworzone podczas testowania i tworzenia aplikacji. Zwykle obrazy podstawowe są instalowane przy użyciu środowiska uruchomieniowego, jeśli planujesz kompilowanie innych obrazów na podstawie tego środowiska uruchomieniowego.
Aby usunąć obraz, skopiuj identyfikator obrazu i uruchom docker image rm
polecenie:
docker image rm 25aeb97a2e21
Następne kroki
- Ogłoszenie wbudowanej obsługi kontenerów dla zestawu SDK platformy .NET
- Samouczek: konteneryzowanie aplikacji .NET
- Obrazy kontenerów platformy .NET
- Przejrzyj usługi platformy Azure, które obsługują kontenery
- Przeczytaj o poleceniach dockerfile
- Eksplorowanie narzędzi kontenerów w programie Visual Studio