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:

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 ContainerImageTagselementó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 za user/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 TargetFrameworkelementu . 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ść ContainerFamilyalpine:

<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-x64obecnie obrazy , linux-arm64linux-armi 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):

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 ContainerImageTagstagó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 to tcp, prawidłowe wartości to tcp lub udp.
<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, ContainerDefaultArgsi 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 ContainerEntrypointpolecenia , ContainerEntrypointArgs, ContainerAppCommand, ContainerAppCommandArgsi 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, ContainerAppCommandArgsi ContainerDefaultArgs.
  • None:
    • W tym trybie punkt wejścia jest definiowany przez ContainerEntrypoint, ContainerEntrypointArgsi ContainerDefaultArgs.
  • DefaultArgs:
    • Jest to najbardziej złożony tryb — jeśli żaden z ContainerEntrypoint[Args] elementów nie istnieje, element ContainerAppCommand[Args] i ContainerDefaultArgs 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 lub dotnet/usr/bin/dotnet został pominięty, aby mieć pełną kontrolę.
    • Jeśli oba ContainerEntrypoint elementy i ContainerAppCommand są obecne, ContainerEntrypoint staje się punktem wejścia i ContainerAppCommand staje się poleceniem .

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:groupnamei 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 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 poleceniu ContainerEntrypoint .

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 do ContainerEntrypoint 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 UTC DateTime.

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