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ść natrue
. Ta właściwość jest niejawnie ustawiona natrue
dla typów projektów wykonywalnych, takich jakconsole
,webapp
iworker
. -
EnableSdkContainerSupport
: ustaw wartość natrue
, 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 publish
okreś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 DefaultContainer
jest 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
- pomocnicy uwierzytelniania
- łańcucha kluczy systemu
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 PATH
systemu. 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 , SelfContained lub 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 |