Udostępnij za pośrednictwem


Omówienie tworzenia kontenera zestawu SDK platformy .NET

Chociaż istnieje możliwość konteneryzowania aplikacji platformy .NET przy użyciu Dockerfile, istnieją przekonujące powody, dla których konteneryzowanie aplikacji bezpośrednio za pomocą zestawu SDK platformy .NET. Ten artykuł zawiera omówienie funkcji tworzenia kontenera zestawu .NET SDK ze szczegółami związanymi z telemetrią, zagadnieniami dotyczącymi publikowania, właściwościami kompilacji i uwierzytelnianiem w rejestrach kontenerów.

Zagadnienia dotyczące publikowania projektu

Teraz, gdy masz aplikację platformy .NET, możesz opublikować ją jako kontener. Przed wykonaniem tej czynności należy pamiętać o kilku ważnych kwestiach. Przed zestawem .NET SDK w wersji 8.0.200 potrzebne są 📦 pakiet Microsoft.NET.Build.Containers NuGet. Ten pakiet nie jest wymagany dla zestawu .NET SDK w wersji 8.0.200 lub nowszej, ponieważ obsługa kontenerów jest domyślnie dołączona.

Aby włączyć publikowanie aplikacji .NET jako kontenera, wymagane są następujące właściwości kompilacji:

  • IsPublishable: ustaw wartość na true. Ta właściwość jest niejawnie ustawiona na true dla typów projektów wykonywalnych, takich jak console, webappi worker.
  • EnableSdkContainerSupport: ustaw wartość na true, gdy typ projektu jest aplikacją konsolową.

Aby jawnie włączyć obsługę kontenera zestawu SDK, rozważ następujący fragment kodu pliku projektu:

<PropertyGroup>
  <IsPublishable>true</IsPublishable>
  <EnableSdkContainerSupport>true</EnableSdkContainerSupport>
</PropertyGroup>

Publikowanie przełączników i właściwości kompilacji

Podobnie jak w przypadku wszystkich poleceń .NET CLI, można określić właściwości MSBuild w wierszu polecenia. Dostępnych jest wiele prawidłowych formularzy składni, takich jak:

  • /p:PropertyName=Value
  • -p:PropertyName=Value
  • -p PropertyName=Value
  • --property PropertyName=Value

Możesz używać dowolnej preferowanej składni, ale w dokumentacji przedstawiono przykłady korzystające z formularza -p.

Napiwek

Aby ułatwić rozwiązywanie problemów, rozważ użycie dzienników MSBuid. Aby wygenerować plik dziennika binarnego (binlog), dodaj przełącznik -bl do polecenia dotnet publish. Pliki binlog są przydatne do diagnozowania problemów z kompilacją i można je otworzyć w MSBuild Structured Log Viewer. Zapewniają one szczegółowy ślad procesu kompilacji, niezbędne do analizy programu MSBuild. Aby uzyskać więcej informacji, zobacz Rozwiązywanie problemów i tworzenie dzienników dla programu MSBuild.

Publikowanie profilów i obiektów docelowych

W przypadku korzystania z dotnet publishokreślenie profilu z -p PublishProfile=DefaultContainer może ustawić właściwość, która powoduje, że zestaw SDK wyzwoli inny element docelowy po procesie publikowania. Jest to pośredni sposób osiągnięcia żądanego wyniku. Z drugiej strony użycie dotnet publish /t:PublishContainer bezpośrednio wywołuje cel PublishContainer, osiągając ten sam wynik, ale w prostszy sposób.

Innymi słowy, następujące polecenie interfejsu wiersza polecenia platformy .NET:

dotnet publish -p PublishProfile=DefaultContainer

Ustawienie właściwości PublishProfile na DefaultContainerjest odpowiednikiem następującego polecenia:

dotnet publish /t:PublishContainer

Różnica między dwiema metodami polega na tym, że pierwszy używa profilu do ustawiania właściwości, podczas gdy ten ostatni bezpośrednio wywołuje obiekt docelowy. Przyczyną jest to, że profile są funkcją programu MSBuild i mogą służyć do ustawiania właściwości w bardziej złożony sposób niż tylko ich bezpośrednie ustawianie.

Jednym z kluczowych problemów jest to, że nie wszystkie typy projektów obsługują profile lub mają ten sam zestaw profilów. Ponadto istnieje różnica w poziomie obsługi profilów między różnymi narzędziami, takimi jak Program Visual Studio i interfejs wiersza polecenia platformy .NET. W związku z tym użycie celów jest ogólnie jaśniejszą i szerzej popieraną metodą osiągnięcia tego samego wyniku.

Logowanie do rejestrów kontenerów

Interakcja z prywatnymi rejestrami kontenerów wymaga uwierzytelnienia w tych rejestrach.

Platforma Docker ma ustalony wzorzec za pomocą polecenia docker login, które jest sposobem interakcji z plikiem konfiguracji platformy Docker zawierającym reguły uwierzytelniania przy użyciu określonych rejestrów. Ten plik i typy uwierzytelniania, które koduje, są obsługiwane przez microsoft.Net.Build.Containers na potrzeby uwierzytelniania rejestru. Powinno to zapewnić, że ten pakiet będzie działać bezproblemowo z dowolnym rejestrem, z którego można docker pull i docker push. Ten plik jest zwykle przechowywany w ~/.docker/config.json, ale można go określić dodatkowo za pomocą zmiennej DOCKER_CONFIG, która wskazuje katalog zawierający plik config.json.

Rodzaje uwierzytelniania

Plik config.json zawiera trzy rodzaje uwierzytelniania:

Jawna nazwa użytkownika/hasło

Sekcja auths pliku config.json jest mapą klucz/wartość między nazwami rejestru a ciągami w formacie Base64, które zawierają nazwę użytkownika i hasło. W typowym scenariuszu platformy Docker uruchomienie docker login <registry> -u <username> -p <password> tworzy nowe elementy na tej mapie. Te poświadczenia są popularne w systemach ciągłej integracji, gdzie logowanie odbywa się przy użyciu tokenów na początku uruchomienia. Jednak są one mniej popularne w przypadku maszyn deweloperskich użytkowników końcowych ze względu na ryzyko związane z przechowywaniem niezaszyfrowanych poświadczeń w pliku.

Pomocnicy do zarządzania poświadczeniami

Sekcja credHelpers pliku config.json jest mapą klucz/wartość między nazwami rejestru a nazwami określonych programów, których można użyć do tworzenia i pobierania poświadczeń dla tego rejestru. Jest to często używane, gdy określone rejestry mają złożone wymagania dotyczące uwierzytelniania. Aby tego rodzaju uwierzytelnianie działało, musisz mieć aplikację o nazwie docker-credential-{name} w PATHsystemu. Tego rodzaju poświadczenia są zwykle bezpieczne, ale mogą być trudne do skonfigurowania na maszynach deweloperskich lub maszynach CI.

Łańcucha kluczy systemowych

Sekcja credsStore jest pojedynczą właściwością ciągu, której wartością jest nazwa programu pomocnika poświadczeń platformy Docker, który wie, jak połączyć się z menedżerem haseł systemu. W przypadku systemu Windows może to być na przykład wincred. Są one popularne w przypadku instalatorów platformy Docker dla systemów macOS i Windows.

Uwierzytelnianie za pomocą zmiennych środowiskowych

W niektórych scenariuszach standardowy mechanizm uwierzytelniania Docker opisany powyżej po prostu nie spełnia oczekiwań. To narzędzie ma dodatkowy mechanizm udostępniania poświadczeń do rejestrów: poprzez zmienne środowiskowe. Jeśli używane są zmienne środowiskowe, mechanizm dostarczania poświadczeń nie będzie w ogóle używany. Obsługiwane są następujące zmienne środowiskowe:

  • DOTNET_CONTAINER_REGISTRY_UNAME: powinna to być nazwa użytkownika rejestru. Jeśli hasło rejestru jest tokenem, nazwa użytkownika powinna być "<token>".
  • DOTNET_CONTAINER_REGISTRY_PWORD: powinno to być hasło lub token dla rejestru.

Notatka

Od zestawu .NET SDK 8.0.400 zmienne środowiskowe dla operacji kontenera zostały zaktualizowane. Zmienne SDK_CONTAINER_* mają teraz prefiks DOTNET_CONTAINER_*.

Ten mechanizm jest potencjalnie narażony na wyciek poświadczeń, dlatego powinien być używany tylko w scenariuszach, w których drugi mechanizm nie jest dostępny. Jeśli na przykład używasz narzędzi zestawu SDK dla kontenerów wewnątrz samego kontenera platformy Docker. Ponadto ten mechanizm nie korzysta z przestrzeni nazw — próbuje użyć tych samych poświadczeń zarówno dla rejestru źródłowego (gdzie znajduje się obraz podstawowy), jak i rejestru docelowego (gdzie przesyłasz obraz końcowy).

Używanie niezabezpieczonych rejestrów

Zakłada się, że większość dostępu do rejestru jest bezpieczna, co oznacza, że protokół HTTPS jest używany do interakcji z rejestrem. Jednak nie wszystkie rejestry są konfigurowane przy użyciu certyfikatów TLS — szczególnie w sytuacjach takich jak prywatny rejestr firmowy za siecią VPN. Aby obsługiwać te przypadki użycia, narzędzia kontenera zapewniają sposoby deklarowania, że określony rejestr używa niezabezpieczonej komunikacji.

Począwszy od platformy .NET 8.0.400, zestaw SDK rozumie te pliki konfiguracji i formaty i automatycznie użyje tej konfiguracji, aby określić, czy należy używać protokołu HTTP lub HTTPS. Konfigurowanie rejestru dla niezabezpieczonej komunikacji zależy od wybranego narzędzia kontenera.

Doker

Platforma Docker przechowuje konfigurację rejestru w konfiguracji demona . Aby dodać nowe niezabezpieczone rejestry, nowe hosty są dodawane do właściwości tablicy "insecure-registries":

{
  "insecure-registries": [
    "registry.mycorp.net"
  ]
}

Notatka

Aby zastosować zmiany do tego pliku, należy ponownie uruchomić demona platformy Docker.

Podman

Narzędzie Podman używa pliku registries.conf TOML do przechowywania informacji o połączeniu z rejestrem. Ten plik zazwyczaj znajduje się w /etc/containers/registries.conf. Aby dodać nowe niezabezpieczone rejestry, do przechowywania ustawień rejestru zostanie dodana sekcja TOML, a następnie należy ustawić opcję insecure na wartość true.

[[registry]]
location = "registry.mycorp.net"
insecure = true

Notatka

Aby zastosować wszelkie zmiany w pliku registries.conf, należy ponownie uruchomić narzędzie Podman.

Zmienne środowiskowe

Począwszy od wersji 9.0.100, zestaw .NET SDK rozpoznaje niezabezpieczone rejestry przekazywane przez zmienną środowiskową DOTNET_CONTAINER_INSECURE_REGISTRIES. Ta zmienna przyjmuje rozdzieloną przecinkami listę domen do traktowania jako niezabezpieczonych w taki sam sposób, jak w powyższych przykładach platformy Docker i narzędzia Podman.

$Env:DOTNET_CONTAINER_INSECURE_REGISTRIES=localhost:5000,registry.mycorp.com; dotnet publish -t:PublishContainer -p:ContainerRegistry=registry.mycorp.com -p:ContainerBaseImage=localhost:5000/dotnet/runtime:9.0

Telemetria

Podczas publikowania aplikacji .NET jako kontenera, narzędzia kontenerowe zestawu SDK .NET zbierają i wysyłają dane telemetryczne dotyczące sposobu używania narzędzi. Zebrane dane są dodatkiem do danych telemetrycznych wysyłanych przez .NET CLI, ale używają tych samych mechanizmów i, co ważne, stosują te same zasady rezygnacji.

Zebrane dane telemetryczne mają być ogólne i nie wyciekają żadnych danych osobowych — zamierzonym celem jest pomoc w zmierzeniu następujących elementów:

  • Ogólne użycie funkcji konteneryzacji zestawu .NET SDK.
  • Współczynniki sukcesów i niepowodzeń wraz z ogólnymi informacjami na temat tego, jakie rodzaje awarii występują najczęściej.
  • Użycie określonych funkcji technologii, takich jak publikowanie w różnych rodzajach rejestru, lub jak było wywoływane publikowanie.

Aby zrezygnować z telemetrii, ustaw zmienną środowiskową DOTNET_CLI_TELEMETRY_OPTOUT na true. Aby uzyskać więcej informacji, zobacz telemetrię interfejsu wiersza komend platformy .NET.

Telemetria wnioskowania

Zostają zarejestrowane następujące informacje o przebiegu procesu wnioskowania dotyczącego obrazu podstawowego:

Znacznik czasu Wyjaśnienie Przykładowa wartość
InferencePerformed Jeśli użytkownicy ręcznie określają obrazy podstawowe zamiast używania wnioskowania. true
TargetFramework TargetFramework wybrany podczas wnioskowania obrazu podstawowego. net8.0
BaseImage Wartość wybranego obrazu podstawowego, ale tylko wtedy, gdy ten obraz podstawowy jest jednym z obrazów utworzonych przez firmę Microsoft. Jeśli użytkownik określi dowolny obraz inny niż obrazy utworzone przez firmę Microsoft na mcr.microsoft.com, ta wartość ma wartość null. mcr.microsoft.com/dotnet/aspnet
BaseImageTag Wartość wybranego tagu, ale tylko wtedy, gdy jest to tag dla jednego z obrazów utworzonych przez firmę Microsoft. Jeśli użytkownik określi dowolny obraz inny niż obrazy utworzone przez firmę Microsoft na mcr.microsoft.com, ta wartość ma wartość null. 8.0
ContainerFamily Wartość właściwości ContainerFamily, jeśli użytkownik użył funkcji ContainerFamily do wybrania "smaku" jednego z naszych obrazów podstawowych. Jest to ustawiane tylko wtedy, gdy użytkownik wybrał lub wywnioskował jeden z obrazów platformy .NET utworzonych przez firmę Microsoft z mcr.microsoft.com jammy-chiseled
ProjectType Rodzaj projektu, który jest konteneryzowany. AspNetCore lub Console
PublishMode Jak aplikacja została spakowana. Aot, Trimmed, SelfContainedlub FrameworkDependent
IsInvariant Jeśli wybrany obraz wymaga niezmiennej globalizacji lub użytkownik wybrał go ręcznie. true
TargetRuntime Identyfikator RID, dla którego opublikowano tę aplikację. linux-x64

Telemetria tworzenia obrazu

Zostają zapisane następujące informacje o przebiegu procesu tworzenia i publikowania kontenera:

Punkt czasowy Wyjaśnienie Przykładowa wartość
RemotePullType Jeśli obraz podstawowy pochodzi z rejestru zdalnego, jakiego rodzaju rejestr był? Azure, AWS, Google, GitHub, DockerHub, MRC lub inne
LocalPullType Jeśli obraz podstawowy pochodzi z lokalnego źródła, takiego jak demon kontenera lub tarball. Docker, Podman, Tarball
RemotePushType Jeśli obraz został wypchnięty do rejestru zdalnego, jakiego rodzaju rejestr był? Azure, AWS, Google, GitHub, DockerHub, MRC lub inne
LocalPushType Co to było, jeśli obraz został wypchnięty do lokalnego miejsca docelowego? Docker, Podman, Tarball

Ponadto w przypadku wystąpienia różnych rodzajów błędów podczas procesu zbierane są dane o rodzaju błędu:

Punkt czasowy Wyjaśnienie Przykładowa wartość
Error Rodzaj błędu, który wystąpił unknown_repository, credential_failure, rid_mismatch, local_load.
Direction Jeśli błąd jest credential_failure, czy dotyczył rejestru wypychania czy ściągania? push
Docelowy identyfikator RID Jeśli błąd był typu rid_mismatch, jakiego identyfikatora RID zażądano? linux-x64
Dostępne identyfikatory RID Jeśli błąd był rid_mismatch, które identyfikatory RID były obsługiwane przez obraz podstawowy? linux-x64,linux-arm64

Zobacz też