Teilen über


Übersicht über die Erstellung von .NET SDK-Containern

Obwohl es möglich ist, .NET-Apps mit einem Dockerfile zu containerisieren, gibt es zwingende Gründe für Containerisierung von Apps direkt mit dem .NET SDK. Dieser Artikel enthält eine Übersicht über die .NET SDK-Container-Erstellungsfunktion mit Details zu Telemetrie, Veröffentlichungsaspekte, Build-Eigenschaften und Authentifizierung bei Container-Registrierungen.

Überlegungen zum Veröffentlichen von Projekten

Nachdem Sie nun über eine .NET-App verfügen, können Sie sie als Container veröffentlichen. Bevor Sie dies tun, gibt es mehrere wichtige Überlegungen, die Sie berücksichtigen sollten. Früher, vor der .NET SDK Version 8.0.200, benötigten Sie das 📦 Microsoft.NET.Build.Containers NuGet-Paket. Dieses Paket ist für .NET SDK Version 8.0.200 und höher nicht erforderlich, da die Containerunterstützung standardmäßig enthalten ist.

Zum Aktivieren der Veröffentlichung einer .NET-App als Container sind die folgenden Buildeigenschaften erforderlich:

  • IsPublishable: Stellen Sie auf true ein. Diese Eigenschaft wird implizit auf true für ausführbare Projekttypen festgelegt, z. B. console, webappund worker.
  • EnableSdkContainerSupport: Auf true festlegen, wenn der Projekttyp eine Konsolen-App ist.

Um die SDK-Containerunterstützung explizit zu aktivieren, berücksichtigen Sie den folgenden Projektdateiausschnitt:

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

Veröffentlichung von Schaltern und Build-Eigenschaften

Wie bei allen .NET CLI-Befehlen können Sie MSBuild-Eigenschaften in der Befehlszeile angeben. Es stehen viele gültige Syntaxformen zur Verfügung, um Eigenschaften bereitzustellen, z. B.:

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

Sie können die gewünschte Syntax verwenden, aber in der Dokumentation werden Beispiele mit dem -p Formular gezeigt.

Tipp

Zur Problembehandlung sollten Sie die MSBuild-Protokolle verwenden. Um eine Binärprotokolldatei zu generieren, fügen Sie den -bl Schalter zum Befehl dotnet publish hinzu. Binlog-Dateien sind nützlich für die Diagnose von Buildproblemen und können im MSBuild Structured Log Viewergeöffnet werden. Sie bieten eine detaillierte Ablaufverfolgung des Buildprozesses, die für die MSBuild-Analyse unerlässlich ist. Weitere Informationen finden Sie unter Problembehandlung und Erstellen von Protokollen für MSBuild.

Profile und Ziele veröffentlichen

Wenn Sie dotnet publish verwenden, kann das Angeben eines Profils mit -p PublishProfile=DefaultContainer eine Eigenschaft festlegen, die bewirkt, dass das SDK nach dem Veröffentlichungsprozess ein anderes Ziel auslöst. Dies ist eine indirekte Möglichkeit, das gewünschte Ergebnis zu erreichen. Andererseits ruft die direkte Verwendung von dotnet publish /t:PublishContainer das Zielobjekt PublishContainer auf, und erzielt dadurch dasselbe Ergebnis auf einfachere Weise.

Mit anderen Worten: Der folgende .NET CLI-Befehl:

dotnet publish -p PublishProfile=DefaultContainer

Die Eigenschaft PublishProfile wird auf DefaultContainer festgelegt und ist äquivalent zu folgendem Befehl:

dotnet publish /t:PublishContainer

Der Unterschied zwischen den beiden Methoden besteht darin, dass erstere ein Profil verwendet, um die Eigenschaft festzulegen, während letztere das Ziel direkt aufruft. Der Grund dafür, warum dies wichtig ist, besteht darin, dass Profile ein Merkmal von MSBuild sind und auf komplexere Weise zum Festlegen von Eigenschaften verwendet werden können, als es durch direktes Setzen der Eigenschaften möglich wäre.

Ein wichtiges Problem besteht darin, dass nicht alle Projekttypen Profile unterstützen oder denselben Satz von Profilen zur Verfügung haben. Darüber hinaus gibt es eine Diskrepanz bei der Unterstützung für Profile zwischen verschiedenen Tools wie Visual Studio und der .NET CLI. Daher ist die Verwendung von Zielen im Allgemeinen eine klarere und breiter unterstützte Methode, um dasselbe Ergebnis zu erzielen.

Authentifizieren bei Containerregistrierungen

Die Interaktion mit privaten Containerregistrierungen erfordert eine Authentifizierung mit diesen Registern.

Docker verwendet hierfür ein etabliertes Muster mit dem docker login-Befehl, der eine Möglichkeit bietet, mit einer Docker-Konfigurationsdatei zu interagieren, die Regeln für die Authentifizierung mit bestimmten Registries enthält. Diese Datei und die codierten Authentifizierungstypen werden von Microsoft.Net.Build.Containers für die Registrierungsauthentifizierung unterstützt. Dadurch sollte sichergestellt werden, dass dieses Paket nahtlos mit jeder Registrierung funktioniert, aus der Sie docker pull und in die Sie docker push können. Diese Datei wird normalerweise bei ~/.docker/config.jsongespeichert, kann aber zusätzlich über die variable DOCKER_CONFIG angegeben werden, die auf ein Verzeichnis verweist, das eine config.json Datei enthält.

Authentifizierungsarten

Die datei config.json enthält drei Arten von Authentifizierung:

Expliziter Benutzername/Kennwort

Der Abschnitt auths der Datei config.json ist eine Schlüssel-Wertzuordnung zwischen Registrierungsnamen und Base64-codierten Benutzernamen:Kennwortzeichenfolgen. In einem gängigen Docker-Szenario erstellt das Ausführen von docker login <registry> -u <username> -p <password> neue Elemente in dieser Karte. Diese Anmeldeinformationen sind in CI-Systemen (Continuous Integration) beliebt, in denen die Anmeldung zu Beginn eines Durchlaufs mit Tokens erfolgt. Sie sind jedoch aufgrund des Sicherheitsrisikos, dass in einer Datei ungeschützte Anmeldeinformationen gespeichert werden, für Endbenutzerentwicklungscomputer weniger beliebt.

Anmeldeinformationshilfsprogramme

Der Abschnitt credHelpers der Datei config.json ist eine Schlüssel-Wert-Zuordnung zwischen Registrierungsnamen und den Namen bestimmter Programme, die zur Erstellung und zum Abrufen von Anmeldeinformationen für diese Registrierung verwendet werden können. Dies wird häufig verwendet, wenn bestimmte Registrierungen komplexe Authentifizierungsanforderungen aufweisen. Damit diese Art der Authentifizierung funktioniert, müssen Sie über eine Anwendung mit dem Namen docker-credential-{name} im PATHIhres Systems verfügen. Diese Arten von Zugangsdaten sind tendenziell sicher, können aber schwer auf Entwicklungs- oder CI-Geräten eingerichtet werden.

System-Keychains

Der Abschnitt credsStore ist eine einzelne Zeichenfolge, deren Wert der Name eines Docker-Hilfsprogramms für Anmeldeinformationen ist, das mit dem Passwortmanager des Systems kommunizieren kann. Für Windows kann dies z. B. wincred sein. Diese sind beliebt bei Docker-Installern für macOS und Windows.

Authentifizierung über Umgebungsvariablen

In einigen Szenarien ist der oben beschriebene Standard-Docker-Authentifizierungsmechanismus einfach nicht ausreichend. Dieses Tool verfügt über einen zusätzlichen Mechanismus zum Bereitstellen von Anmeldeinformationen für Registrierungen: Umgebungsvariablen. Wenn Umgebungsvariablen verwendet werden, wird der Mechanismus zur Bereitstellung von Anmeldeinformationen überhaupt nicht verwendet. Die folgenden Umgebungsvariablen werden unterstützt:

  • DOTNET_CONTAINER_REGISTRY_UNAME: Dies sollte der Benutzername für die Registrierung sein. Wenn das Kennwort für die Registrierung ein Token ist, sollte der Benutzername "<token>"werden.
  • DOTNET_CONTAINER_REGISTRY_PWORD: Dies sollte das Kennwort oder das Token für die Registrierung sein.

Anmerkung

Ab .NET SDK 8.0.400 wurden die Umgebungsvariablen für Containervorgänge aktualisiert. Die Variablen SDK_CONTAINER_* erhalten jetzt das Präfix DOTNET_CONTAINER_*.

Dieser Mechanismus ist potenziell anfällig für Credential-Lecks, daher sollte er nur in Szenarien verwendet werden, in denen der andere Mechanismus nicht verfügbar ist. Wenn Sie beispielsweise das SDK-Containertool innerhalb eines Docker-Containers verwenden. Darüber hinaus ist dieser Mechanismus nicht an einen Namespace gebunden – er versucht, die gleichen Anmeldeinformationen für die Quell-Registrierung (wo sich Ihr Basisimage befindet) und die Ziel-Registrierung zu verwenden (wo Sie das endgültige Image pushen).

Verwenden unsicherer Registrierungen

Die meisten Registrierungszugriffe werden als sicher angenommen, was bedeutet, dass HTTPS für die Interaktion mit der Registrierung verwendet wird. Allerdings sind nicht alle Registrierungen mit TLS-Zertifikaten konfiguriert – insbesondere in Situationen wie einer privaten Unternehmensregistrierung hinter einem VPN. Um diese Anwendungsfälle zu unterstützen, bieten Containertools Möglichkeiten, zu deklarieren, dass eine bestimmte Registrierung unsichere Kommunikation verwendet.

Ab .NET 8.0.400 versteht das SDK diese Konfigurationsdateien und -formate und verwendet diese Konfiguration automatisch, um festzustellen, ob HTTP oder HTTPS verwendet werden soll. Das Konfigurieren einer Registrierung für unsichere Kommunikation variiert je nach Ihrem Containertool.

Docker

Docker speichert seine Registry-Konfiguration in der Daemon-Konfiguration. Um neue unsichere Registrierungen hinzuzufügen, werden der "insecure-registries"-Array-Eigenschaft neue Hosts hinzugefügt:

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

Anmerkung

Sie müssen den Docker-Daemon neu starten, um alle Änderungen auf diese Datei anzuwenden.

Podman

Podman verwendet eine registries.conf TOML-Datei zum Speichern von Registrierungsverbindungsinformationen. Diese Datei befindet sich in der Regel bei /etc/containers/registries.conf. Um neue unsichere Registrierungen hinzuzufügen, wird ein TOML-Abschnitt hinzugefügt, der die Einstellungen für die Registrierung enthält, und die option insecure muss auf truefestgelegt werden.

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

Anmerkung

Sie müssen Podman neu starten, um änderungen an der datei registries.conf anzuwenden.

Umgebungsvariablen

Ab 9.0.100 erkennt das .NET SDK unsichere Registrierungen, die über die DOTNET_CONTAINER_INSECURE_REGISTRIES Umgebungsvariable übergeben werden. Diese Variable verwendet eine kommagetrennte Liste von Domains, um diese auf die gleiche Weise wie in den oben genannten Docker- und Podman-Beispielen als unsicher zu behandeln.

$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

Telemetrie

Wenn Sie eine .NET-App als Container veröffentlichen, sammelt und sendet das .NET SDK-Containertool Nutzungs-Telemetrie darüber, wie die Tools verwendet werden. Die zusätzlich zu den Telemetriedaten, die von der .NET CLI gesendet werden, gesammelten Daten nutzen jedoch dieselben Mechanismen und vor allem die gleichen Opt-Out-Kontrollen.

Die gesammelte Telemetrie soll allgemeiner Natur sein und keine persönlichen Informationen preisgeben – der beabsichtigte Zweck besteht darin, Folgendes zu messen:

  • Die Verwendung der Containerisierungsfunktion des .NET SDK insgesamt.
  • Erfolgs- und Fehlerraten sowie allgemeine Informationen dazu, welche Arten von Fehlern am häufigsten auftreten.
  • Verwendung bestimmter Features der Technik, z. B. veröffentlichen in verschiedenen Registrierungstypen oder wie die Veröffentlichung aufgerufen wurde.

Um sich von der Telemetrie abzumelden, setzen Sie die DOTNET_CLI_TELEMETRY_OPTOUT-Umgebungsvariable auf true. Weitere Informationen finden Sie in der .NET CLI-Telemetrie.

Inferenz-Telemetrie

Die folgenden Informationen dazu, wie der Basisbild-Inferenzprozess durchgeführt wurde, werden protokolliert:

Datumspunkt Erklärung Beispielwert
InferencePerformed Wenn Benutzer Basisimages manuell angeben, anstatt Ableitungen zu verwenden. true
TargetFramework Die TargetFramework, die bei der Basisbild-Ableitung ausgewählt wurde. net8.0
BaseImage Der Wert des ausgewählten Basisimages, aber nur, wenn es sich bei diesem Basisbild um eines der von Microsoft erzeugten Bilder handelt. Wenn ein Benutzer ein anderes Bild als die von Microsoft erzeugten Bilder auf mcr.microsoft.com angibt, ist dieser Wert null. mcr.microsoft.com/dotnet/aspnet
BaseImageTag Der Wert des ausgewählten Tags, aber nur, wenn dieses Tag für eines der von Microsoft produzierten Bilder bestimmt ist. Wenn ein Benutzer ein anderes Bild als die von Microsoft erzeugten Bilder auf mcr.microsoft.com angibt, ist dieser Wert null. 8.0
ContainerFamily Der Wert der ContainerFamily-Eigenschaft, wenn ein Benutzer die Funktion ContainerFamily verwendet hat, um eine Variante eines unserer Basisbilder auszuwählen. Dies wird nur festgelegt, wenn der Benutzer eines der von Microsoft produzierten .NET-Images aus mcr.microsoft.com ausgewählt oder abgeleitet hat. jammy-chiseled
ProjectType Die Art des Projekts, das containerisiert wird. AspNetCore oder Console
PublishMode Wie die Anwendung verpackt wurde. Aot, Trimmed, SelfContained oder FrameworkDependent
IsInvariant Wenn für das ausgewählte Bild eine invariante Globalisierung erforderlich ist oder der Benutzer sich manuell dafür entschieden hat. true
TargetRuntime Die RID, für die diese Anwendung veröffentlicht wurde. linux-x64

Telemetrie zur Bilderstellung

Die folgenden Informationen dazu, wie der Erstellungs- und Veröffentlichungsprozess des Containers aufgetreten ist, wird protokolliert:

Datumspunkt Erklärung Beispielwert
RemotePullType Wenn das Basisimage aus einer Remoteregistrierung stammte, welche Art von Registrierung war es? Azure, AWS, Google, GitHub, DockerHub, MRC oder andere
LocalPullType Wenn das Basisimage von einer lokalen Quelle stammt, z. B. einem Container-Daemon oder einem Tarball. Docker, Podman, Tarball
RemotePushType Wenn das Bild an eine Remote-Registrierung übertragen wurde, um welche Art von Registrierung handelt es sich? Azure, AWS, Google, GitHub, DockerHub, MRC oder andere
LocalPushType Wenn das Bild an ein lokales Ziel übertragen wurde, welches war es? Docker, Podman, Tarball

Darüber hinaus werden, wenn während des Prozesses verschiedene Arten von Fehlern auftreten, Daten darüber gesammelt, um welche Art von Fehler es sich handelt.

Datumspunkt Erklärung Beispielwert
Error Die Art des aufgetretenen Fehlers unknown_repository, credential_failure, rid_mismatch, local_load.
Direction Wenn der Fehler ein credential_failure ist, bezog er sich auf die Push- oder Pull-Registrierung? push
Ziel-RID Wenn es sich bei dem Fehler um eine rid_mismatch handelte, welche RID wurde angefordert? linux-x64
Verfügbare RIDs Wenn der Fehler ein rid_mismatch war, welche RIDs hat das Basisimage unterstützt? linux-x64,linux-arm64

Weitere Informationen