Sdílet prostřednictvím


Odkaz na kontejnerizaci aplikace .NET

V tomto referenčním článku se dozvíte, jak nakonfigurovat image kontejneru, která se vygeneruje při publikování aplikace .NET jako kontejneru. Tento článek popisuje různé vlastnosti, které můžete nastavit pro řízení image, spouštěcího prostředí a příkazů, které se spustí při spuštění kontejneru.

Konfigurace image kontejneru

Pomocí vlastností NÁSTROJE MSBuild můžete řídit mnoho aspektů vygenerovaného kontejneru. Obecně platí, že pokud můžete použít příkaz v souboru Dockerfile nastavit určitou konfiguraci, můžete to udělat pomocí nástroje MSBuild.

Poznámka

Jedinou výjimkou jsou příkazy RUN. Vzhledem k tomu, jak se kontejnery vytvářejí, není možné je emulovat. Pokud tuto funkci potřebujete, můžete zvážit použití souboru Dockerfile k sestavení imagí kontejneru.

V sadě .NET SDK neexistuje způsob, jak provádět příkazy RUN. Tyto příkazy se často používají k instalaci některých balíčků operačního systému nebo k vytvoření nového uživatele operačního systému nebo libovolného počtu věcí. Pokud chcete dál používat funkci vytváření kontejnerů sady .NET SDK, můžete místo toho vytvořit vlastní základní image s těmito změnami a pak použít tuto základní image. Další informace najdete v tématu ContainerBaseImage.

ContainerArchiveOutputPath

Pokud chcete vytvořit image kontejneru v tar.gz archivu, použijte vlastnost ContainerArchiveOutputPath. Tato funkce je užitečná, pokud pracovní postup není jednoduchý a vyžaduje, abyste například před nasdílením obrázků spustili nástroj pro skenování. Po vytvoření archivu ho můžete přesunout, zkontrolovat nebo načíst do místní sady nástrojů Dockeru.

Pokud chcete publikovat do archivu, přidejte do příkazu ContainerArchiveOutputPath vlastnost dotnet publish, například:

dotnet publish \
  -p PublishProfile=DefaultContainer \
  -p ContainerArchiveOutputPath=./images/sdk-container-demo.tar.gz

Můžete zadat název složky nebo cestu s určitým názvem souboru. Pokud zadáte název složky, název souboru vygenerovaný pro soubor archivu obrázku má název $(ContainerRepository).tar.gz. Tyto archivy mohou obsahovat více značek uvnitř, pouze když je vytvořen jeden soubor pro všechny ContainerImageTags.

Konfigurace pojmenování imagí kontejneru

Image kontejnerů se řídí konkrétní konvencí vytváření názvů. Název image se skládá z několika částí, registru, volitelného portu, úložiště a volitelné značky a rodiny.

REGISTRY[:PORT]/REPOSITORY[:TAG[-FAMILY]]

Představte si například plně kvalifikovaný název mcr.microsoft.com/dotnet/runtime:8.0-alpine image:

  • mcr.microsoft.com je registr (a v tomto případě představuje registr kontejneru Microsoftu).
  • dotnet/runtime je úložiště (některé to ale považují za user/repository).
  • 8.0-alpine je značka a rodina (rodina je volitelný specifikátor, který pomáhá nejednoznačný obal operačního systému).

Některé vlastnosti popsané v následujících částech odpovídají správě částí vygenerovaného názvu image. Představte si následující tabulku, která mapuje vztah mezi názvem image a vlastnostmi sestavení:

Část název obrázku Vlastnost MSBuild Ukázkové hodnoty
REGISTRY[:PORT] ContainerRegistry mcr.microsoft.com:443
PORT ContainerPort :443
REPOSITORY ContainerRepository dotnet/runtime
TAG ContainerImageTag 8.0
FAMILY ContainerFamily -alpine

Následující části popisují různé vlastnosti, které lze použít k řízení vygenerované image kontejneru.

ContainerBaseImage

Vlastnost základní image kontejneru řídí image použitou jako základ pro vaši image. Ve výchozím nastavení se na základě vlastností projektu odvozují následující hodnoty:

  • Pokud je projekt samostatný, použije se mcr.microsoft.com/dotnet/runtime-deps image jako základní image.
  • Pokud je váš projekt ASP.NET Core, použije se jako základní image image mcr.microsoft.com/dotnet/aspnet.
  • V opačném případě se jako základní image použije image mcr.microsoft.com/dotnet/runtime.

Značka obrázku je odvozena jako číselná součást zvoleného TargetFramework. Například projekt, který cílí na net6.0, má za následek značku 6.0 odvozené základní image a net7.0-linux projekt používá značku 7.0 atd.

Pokud tady nastavíte hodnotu, měli byste nastavit plně kvalifikovaný název image, který se má použít jako základ, včetně libovolné značky, kterou dáváte přednost:

<PropertyGroup>
    <ContainerBaseImage>mcr.microsoft.com/dotnet/runtime:8.0</ContainerBaseImage>
</PropertyGroup>

V sadě .NET SDK verze 8.0.200 je ContainerBaseImage odvození vylepšeno, aby se optimalizovala velikost a zabezpečení:

  • Cílení na identifikátory modulu runtime linux-musl-x64 nebo linux-musl-arm64, automaticky zvolí varianty alpine imagí, aby se zajistilo, že váš projekt běží:
    • Pokud projekt používá PublishAot=true pak nightly/runtime-depsjammy-chiseled-aot variantu základní image pro nejlepší velikost a zabezpečení.
    • Pokud projekt používá InvariantGlobalization=false, použije se -extra varianty k zajištění toho, aby lokalizace stále fungovala.

Další informace o velikostech a vlastnostech variant imagí najdete v sestavě velikosti imagí kontejneru .NET 8.0.

ContainerFamily

Počínaje rozhraním .NET 8 můžete pomocí vlastnosti ContainerFamily MSBuild zvolit jinou řadu imagí kontejnerů poskytovaných Microsoftem jako základní image pro vaši aplikaci. Při nastavení se tato hodnota připojí na konec vybrané značky specifické pro TFM a změní zadanou značku. Pokud chcete například použít varianty Alpine Linux základních imagí .NET, můžete nastavit ContainerFamily na alpine:

<PropertyGroup>
    <ContainerFamily>alpine</ContainerFamily>
</PropertyGroup>

Předchozí konfigurace projektu má za následek konečnou značku 8.0-alpine pro aplikaci zacílenou na .NET 8.

Toto pole je volné a často se dá použít k výběru různých distribucí operačního systému, výchozích konfigurací balíčků nebo jiných příchuť změn základní image. Toto pole se při nastavení ContainerBaseImage ignoruje. Další informace najdete v tématu image kontejneru .NET.

ContainerRuntimeIdentifier

Vlastnost ContainerRuntimeIdentifier určuje operační systém a architekturu kontejneru, pokud ContainerBaseImage podporuje více platforem. Image mcr.microsoft.com/dotnet/runtime například podporuje linux-x64, linux-arm, linux-arm64a win10-x64. Ve výchozím nastavení je tato možnost nastavená na RuntimeIdentifier, která se používá při publikování kontejneru. Obvykle nemusíte tuto vlastnost explicitně nastavovat; místo toho použijte možnost -r s příkazem dotnet publish. Pokud zvolený obrázek nepodporuje zadaný RuntimeIdentifier, zobrazí se chyba označující podporované identifikátory.

Vlastnost ContainerBaseImage můžete vždy nastavit na plně kvalifikovaný název image, včetně značky, abyste nemuseli tuto vlastnost vůbec používat.

<PropertyGroup>
    <ContainerRuntimeIdentifier>linux-arm64</ContainerRuntimeIdentifier>
</PropertyGroup>

Další informace o identifikátorech modulu runtime podporovaných rozhraním .NET najdete v tématukatalogu identifikátorů RID .

ContainerRegistry

Vlastnost registru kontejneru řídí cílový registr, místo, do kterého se nově vytvořená image odešle. Ve výchozím nastavení se nasdílí do místního démona Dockeru, ale můžete také zadat vzdálený registr. Při použití vzdáleného registru, který vyžaduje ověřování, se ověřuje pomocí známých mechanismů docker login. Další informace najdete v tématu ověřování v registrech kontejnerů další podrobnosti. Pro konkrétní příklad použití této vlastnosti zvažte následující příklad XML:

<PropertyGroup>
    <ContainerRegistry>registry.mycorp.com:1234</ContainerRegistry>
</PropertyGroup>

Tento nástroj podporuje publikování do libovolného registru, který podporuje docker Registry HTTP API V2. To zahrnuje následující registry explicitně (a pravděpodobně mnohem implicitněji):

Poznámky k práci s těmito registry najdete v poznámky specifické pro registr.

ContainerRepository

Úložiště kontejneru je název samotné image, například dotnet/runtime nebo my-app. Ve výchozím nastavení se používá AssemblyName projektu.

<PropertyGroup>
    <ContainerRepository>my-app</ContainerRepository>
</PropertyGroup>

Názvy obrázků se skládají z jednoho nebo více segmentů oddělených lomítkem, z nichž každý může obsahovat jenom malá písmena alfanumerických znaků, tečky, podtržítka a pomlčky a musí začínat písmenem nebo číslicí. Všechny ostatní znaky způsobí vyvolání chyby.

ContainerImageTag(s)

Vlastnost značky image kontejneru řídí značky, které jsou pro image generovány. Pokud chcete zadat jednu značku, použijte ContainerImageTag a pro více značek použijte ContainerImageTags.

Důležitý

Když použijete ContainerImageTags, skončíte s více obrázky, jednou za jedinečnou značku.

Značky se často používají k odkazování na různé verze aplikace, ale mohou také odkazovat na různé distribuce operačního systému nebo dokonce různé konfigurace.

Počínaje rozhraním .NET 8 platí, že pokud není zadána výchozí značka, latest.

Chcete-li přepsat výchozí nastavení, zadejte jednu z následujících možností:

<PropertyGroup>
    <ContainerImageTag>1.2.3-alpha2</ContainerImageTag>
</PropertyGroup>

Pokud chcete zadat více značek, použijte ve vlastnosti ContainerImageTags sadu značek oddělených středníkem, podobně jako nastavení více TargetFrameworks:

<PropertyGroup>
    <ContainerImageTags>1.2.3-alpha2;latest</ContainerImageTags>
</PropertyGroup>

Značky můžou obsahovat maximálně 127 alfanumerických znaků, tečk, podtržítka a pomlčky. Musí začínat alfanumerickým znakem nebo podtržítkem. Výsledkem jakéhokoli jiného formuláře je vyvolána chyba.

Poznámka

Při použití ContainerImageTags nebo jakékoli vlastnosti NÁSTROJE MSBuild, která potřebuje konfigurovat ; hodnoty s oddělovači. Pokud voláte dotnet publish z příkazového řádku (stejně jako u většiny prostředí CI/CD), je potřeba pochopit omezení nemožnosti prostředí nejednoznačných oddělovačů a uvozovek, což vyžaduje správné uvozovky. To se liší mezi PowerShellem a Bashem. V příslušných prostředích zvažte následující příkazy dotnet publish:

dotnet publish --os linux --arch x64 /t:PublishContainer /p:ContainerImageTags=`"1.2.3-alpha2`;latest`"

V PowerShellu musí být řídicí znaky ; i ".

dotnet publish --os linux --arch x64 /t:PublishContainer /p:ContainerImageTags=\"1.2.3-alpha2;latest\"

V Bashu musí být řídicí znak pouze ".

Výsledkem je generování dvou obrázků: my-app:1.2.3-alpha2 a my-app:latest.

Spropitné

Pokud dochází k problémům s vlastností ContainerImageTags, zvažte místo toho nastavení rozsahu proměnné prostředí ContainerImageTags:

$Env:ContainerImageTags='1.2.3;latest'; dotnet publish --os linux --arch x64 /t:PublishContainer

ContainerLabel

Popisek kontejneru přidá do kontejneru popisek metadat. Popisky se často používají k ukládání verzí a metadat vytváření pro použití skenery zabezpečení a dalšími nástroji infrastruktury. Můžete zadat libovolný počet popisků kontejnerů.

Uzel ContainerLabel má dva atributy:

  • Include: Klíč popisku.
  • Value: Hodnota popisku (může být prázdná).
<ItemGroup>
    <ContainerLabel Include="org.contoso.businessunit" Value="contoso-university" />
</ItemGroup>

Seznam popisků vytvořených ve výchozím nastavení najdete v tématu výchozí popisky kontejneru.

Konfigurace spouštění kontejnerů

K řízení provádění kontejneru můžete použít následující vlastnosti NÁSTROJE MSBuild.

ContainerWorkingDirectory

Uzel pracovního adresáře kontejneru řídí pracovní adresář kontejneru, adresář, v rámci kterého se spouští příkazy, pokud není spuštěn jiný příkaz.

Ve výchozím nastavení se jako pracovní adresář používá hodnota adresáře /app.

<PropertyGroup>
    <ContainerWorkingDirectory>/bin</ContainerWorkingDirectory>
</PropertyGroup>

ContainerPort

Port kontejneru přidá porty TCP (Transmission Control Protocol) nebo UDP (User Datagram Protocol) do seznamu známých portů pro kontejner. To umožňuje, aby moduly runtime kontejnerů, jako je Docker, automaticky mapují tyto porty na hostitelský počítač. Často se používá jako dokumentace pro kontejner, ale dá se použít také k povolení automatického mapování portů.

Uzel ContainerPort má dva atributy:

  • Include: Číslo portu, které se má zveřejnit.
  • Type: Výchozí hodnota tcp, platné hodnoty jsou tcp nebo udp.
<ItemGroup>
    <ContainerPort Include="80" Type="tcp" />
</ItemGroup>

Počínaje rozhraním .NET 8 se ContainerPort odvodí, pokud nejsou explicitně poskytovány na základě několika dobře známých ASP.NET proměnných prostředí:

  • ASPNETCORE_URLS
  • ASPNETCORE_HTTP_PORTS
  • ASPNETCORE_HTTPS_PORTS

Pokud jsou tyto proměnné prostředí přítomny, jejich hodnoty se analyzují a převedou na mapování portů TCP. Tyto proměnné prostředí se čtou z vaší základní image, pokud existují, nebo z proměnných prostředí definovaných v projektu prostřednictvím ContainerEnvironmentVariable položek. Další informace naleznete v tématu ContainerEnvironmentVariable.

ContainerEnvironmentVariable

Uzel proměnné prostředí kontejneru umožňuje přidat do kontejneru proměnné prostředí. Proměnné prostředí jsou přístupné pro aplikaci spuštěnou v kontejneru okamžitě a často se používají ke změně chování spuštěné aplikace za běhu.

Uzel ContainerEnvironmentVariable má dva atributy:

  • Include: Název proměnné prostředí.
  • Value: Hodnota proměnné prostředí.
<ItemGroup>
  <ContainerEnvironmentVariable Include="LOGGER_VERBOSITY" Value="Trace" />
</ItemGroup>

Další informace najdete v tématu proměnné prostředí .NET.

Poznámka

Při publikování image kontejneru v současné době není možné nastavit proměnné prostředí z rozhraní příkazového řádku .NET CLI. Další informace najdete v tématu GitHubu: Sestavení kontejnerů .NET SDK.

Konfigurace příkazů kontejneru

Ve výchozím nastavení nástroje kontejneru spustí vaši aplikaci buď pomocí vygenerovaného binárního souboru AppHost pro vaši aplikaci (pokud vaše aplikace používá AppHost), nebo pomocí příkazu dotnet a knihovny DLL vaší aplikace.

Pomocí kombinace ContainerAppCommand, ContainerAppCommandArgs, ContainerDefaultArgsa ContainerAppCommandInstructionale můžete řídit, jak se aplikace spouští.

Tyto různé konfigurační body existují, protože různé základní image používají různé kombinace vlastností kontejneru ENTRYPOINT a COMMAND a chcete mít možnost podporovat všechny. Výchozí hodnoty by měly být použitelné pro většinu aplikací, ale pokud chcete přizpůsobit chování při spuštění aplikace, měli byste:

  • Identifikujte binární soubor, který se má spustit, a nastavte ho jako ContainerAppCommand
  • Určete, které argumenty požadované pro spuštění aplikace, a nastavte je jako ContainerAppCommandArgs
  • Určete, které argumenty (pokud existují) jsou volitelné a uživatel je může přepsat a nastavit je jako ContainerDefaultArgs
  • Nastavení ContainerAppCommandInstruction na DefaultArgs

Další informace najdete v následujících položkách konfigurace.

ContainerAppCommand

Položka konfigurace příkazu aplikace je logický vstupní bod vaší aplikace. U většiny aplikací se jedná o AppHost, vygenerovaný spustitelný binární soubor pro vaši aplikaci. Pokud vaše aplikace negeneruje AppHost, je tento příkaz obvykle dotnet <your project dll>. Tyto hodnoty se použijí po jakémkoli ENTRYPOINT v základním kontejneru nebo přímo v případě, že není definován žádný ENTRYPOINT.

Konfigurace ContainerAppCommand má jednu vlastnost Include, která představuje příkaz, možnost nebo argument pro použití v příkazu vstupního bodu:

<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

Tato položka konfigurace příkazu aplikace představuje všechny logicky požadované argumenty pro vaši aplikaci, které by se měly použít na ContainerAppCommand. Ve výchozím nastavení se pro aplikaci negenerují žádné. Pokud jsou k dispozici, použijí sergy v kontejneru při jeho spuštění.

Konfigurace ContainerAppCommandArgs má jednu vlastnost Include, která představuje možnost nebo argument, který se má použít pro příkaz ContainerAppCommand.

<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

Tato výchozí položka konfigurace args představuje všechny argumenty přepisovatelné uživatelem pro vaši aplikaci. To je dobrý způsob, jak poskytnout výchozí hodnoty, které může vaše aplikace potřebovat spustit způsobem, který usnadňuje spuštění, ale i tak snadné přizpůsobení.

Konfigurace ContainerDefaultArgs má jednu vlastnost Include, která představuje možnost nebo argument, který se má použít pro příkaz ContainerAppCommand.

<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

Konfigurace instrukcí příkazů aplikace pomáhá řídit způsob, jakým se ContainerEntrypoint, ContainerEntrypointArgs, ContainerAppCommand, ContainerAppCommandArgsa ContainerDefaultArgs zkombinují, aby se vytvořil konečný příkaz, který se spustí v kontejneru. To velmi závisí na tom, jestli je v základní imagi ENTRYPOINT. Tato vlastnost má jednu ze tří hodnot: "DefaultArgs", "Entrypoint"nebo "None".

  • Entrypoint:
    • V tomto režimu je vstupní bod definován pomocí ContainerAppCommand, ContainerAppCommandArgsa ContainerDefaultArgs.
  • None:
    • V tomto režimu je vstupní bod definován pomocí ContainerEntrypoint, ContainerEntrypointArgsa ContainerDefaultArgs.
  • DefaultArgs:
    • Jedná se o nejsložitější režim – pokud nejsou k dispozici žádné položky ContainerEntrypoint[Args], ContainerAppCommand[Args] a ContainerDefaultArgs slouží k vytvoření vstupního bodu a příkazu. Vstupní bod základní image pro základní image, které mají pevně zakódované dotnet nebo /usr/bin/dotnet, se přeskočí, abyste měli úplnou kontrolu.
    • Pokud jsou k dispozici ContainerEntrypoint i ContainerAppCommand, ContainerEntrypoint se stane vstupním bodem a ContainerAppCommand se stane příkazem.

Poznámka

Položky konfigurace ContainerEntrypoint a ContainerEntrypointArgs jsou zastaralé jako .NET 8.

Důležitý

To je pro pokročilé uživatele, které většina aplikací nemusí přizpůsobovat jejich vstupní bod do tohoto stupně. Další informace a pokud chcete poskytnout případy použití pro vaše scénáře, najdete v tématu GitHubu: Kontejner .NET SDK vytváří diskuze.

ContainerUser

Vlastnost konfigurace uživatele řídí výchozího uživatele, který kontejner spouští jako. Často se používá ke spuštění kontejneru jako uživatele, který není root, což je osvědčený postup zabezpečení. Pro tuto konfiguraci existuje několik omezení, o které je potřeba vědět:

  • Může to mít různé formy – uživatelské jméno, ID uživatelů linuxu, název skupiny, ID skupiny linuxu, username:groupnamea další varianty ID.
  • Neexistuje žádné ověření, že zadaný uživatel nebo skupina na obrázku existuje.
  • Změna uživatele může změnit chování aplikace, zejména pokud jde o věci, jako je systém souborů oprávnění.

Výchozí hodnota tohoto pole se liší podle projektu TFM a cílového operačního systému:

  • Pokud cílíte na .NET 8 nebo novější a používáte image modulu runtime Microsoftu, postupujte takhle:
    • v Linuxu se používá app uživatele bez rootu (i když na něj odkazuje jeho ID uživatele).
    • v systému Windows se používá ContainerUser uživatele bez rootu.
  • Jinak se nepoužívá výchozí ContainerUser.
<PropertyGroup>
  <ContainerUser>my-existing-app-user</ContainerUser>
</PropertyGroup>

Spropitné

Proměnná prostředí APP_UID slouží k nastavení informací o uživatelích v kontejneru. Tato hodnota může pocházet z proměnných prostředí definovaných v základní imagi (například z imagí Microsoft .NET), nebo ji můžete nastavit sami pomocí syntaxe ContainerEnvironmentVariable.

Pokud chcete nakonfigurovat aplikaci tak, aby běžela jako uživatel root, nastavte vlastnost ContainerUser na root. Do souboru projektu přidejte následující:

<PropertyGroup>
  <ContainerUser>root</ContainerUser>
</PropertyGroup>

Alternativně můžete tuto hodnotu nastavit při volání dotnet publish z příkazového řádku:

dotnet publish -p ContainerUser=root

Výchozí popisky kontejnerů

Popisky se často používají k poskytování konzistentních metadat u imagí kontejnerů. Tento balíček obsahuje některé výchozí popisky, které podporují lepší udržovatelnost vygenerovaných imagí.

  • org.opencontainers.image.created je nastaven na formát ISO 8601 aktuální hodnoty DateTime.UtcNow.

Další informace najdete v tématu Implementace konvenčních popisků nad stávající infrastrukturou popisků.

Viz také