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í zauser/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
nebolinux-musl-arm64
, automaticky zvolí variantyalpine
imagí, aby se zajistilo, že váš projekt běží:- Pokud projekt používá
PublishAot=true
paknightly/runtime-deps
jammy-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.
- Pokud projekt používá
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-arm64
a 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):
- služby Azure Container Registry
- Amazon Elastic Container Registry
- registru artefaktů Google
- Centra Dockeru
- GitHub Packages
- Container Registry hostovaného v GitLabu
- Quay.io
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í hodnotatcp
, platné hodnoty jsoutcp
neboudp
.
<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
, ContainerDefaultArgs
a ContainerAppCommandInstruction
ale 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
naDefaultArgs
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
, ContainerAppCommandArgs
a 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
,ContainerAppCommandArgs
aContainerDefaultArgs
.
- V tomto režimu je vstupní bod definován pomocí
-
None
:- V tomto režimu je vstupní bod definován pomocí
ContainerEntrypoint
,ContainerEntrypointArgs
aContainerDefaultArgs
.
- V tomto režimu je vstupní bod definován pomocí
-
DefaultArgs
:- Jedná se o nejsložitější režim – pokud nejsou k dispozici žádné položky
ContainerEntrypoint[Args]
,ContainerAppCommand[Args]
aContainerDefaultArgs
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
iContainerAppCommand
,ContainerEntrypoint
se stane vstupním bodem aContainerAppCommand
se stane příkazem.
- Jedná se o nejsložitější režim – pokud nejsou k dispozici žádné položky
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:groupname
a 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.
- v Linuxu se používá
- 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ů.