.NET SDK 容器建立概觀
雖然 使用 Dockerfile將 .NET 應用程式容器化,但 直接使用 .NET SDK將應用程式容器化的原因非常引人注目。 本文提供 .NET SDK 容器建立功能的概觀,其中包含與遙測、發佈考慮、組建屬性和容器登錄驗證相關的詳細數據。
出版專案考量
現在您已擁有 .NET 應用程式,您可以將它發佈為容器。 這麼做之前,請記住幾個重要的考慮。 在 .NET SDK 8.0.200 版之前,您需要 📦 Microsoft.NET.Build.Containers NuGet 套件。 .NET SDK 8.0.200 版和更新版本不需要此套件,因為預設會包含容器支援。
若要啟用將 .NET 應用程式發佈為容器,需要下列組建屬性:
-
IsPublishable
:設定為true
。 此屬性會隱含地設定為true
用於可執行專案類型,例如console
、webapp
和worker
。 -
EnableSdkContainerSupport
:當您的項目類型是控制台應用程式時,設定為true
。
若要明確啟用 SDK 容器支援,請考慮下列專案檔代碼段:
<PropertyGroup>
<IsPublishable>true</IsPublishable>
<EnableSdkContainerSupport>true</EnableSdkContainerSupport>
</PropertyGroup>
發行選項和建置屬性
如同所有 .NET CLI 命令,您可以在命令行上指定 MSBuild 屬性。 有許多有效的語法形式可用來提供屬性,例如:
/p:PropertyName=Value
-p:PropertyName=Value
-p PropertyName=Value
--property PropertyName=Value
您可以隨意使用您偏好的語法,但文件顯示使用 -p
表單的範例。
提示
若要協助進行疑難排解,請考慮使用 MSBuild 記錄。 若要產生二進位記錄檔 (binlog) 檔案,請將 -bl
參數新增至 dotnet publish
命令。 Binlog 檔案可用於診斷建置問題,而且可以在 MSBuild 結構化記錄檔檢視器中開啟。 它們提供建置程式的詳細追蹤,對於 MSBuild 分析而言至關重要。 如需詳細資訊,請參閱針對 MSBuild進行疑難解答和建立記錄
發佈設定檔和目標
當使用 dotnet publish
時,指定一個包含 -p PublishProfile=DefaultContainer
的配置檔可以設置一個屬性,使得 SDK 在發佈過程完成後觸發另一個目標。 這是達成所需結果的間接方式。 另一方面,使用 dotnet publish /t:PublishContainer
直接呼叫 PublishContainer
目標,以更簡單的方式達成相同的結果。
換句話說,下列 .NET CLI 命令:
dotnet publish -p PublishProfile=DefaultContainer
這會將 PublishProfile
屬性設定為 DefaultContainer
,相當於下列命令:
dotnet publish /t:PublishContainer
這兩種方法之間的差異在於,前者會使用配置文件來設定 屬性,而後者則直接叫用目標。 之所以這點重要,是因為配置檔是 MSBuild 的一項功能,它們可以用來以比直接設定屬性更複雜的方式來設定屬性。
其中一個關鍵問題是,並非所有項目類型都支援配置檔,或有一組相同的配置檔可供使用。 此外,不同工具之間的配置檔支援層級差異,例如 Visual Studio 和 .NET CLI。 因此,使用目標通常是更清楚且更廣受支援的方法,以達到相同的結果。
向容器登錄進行驗證
與私人容器註冊表互動需要對這些註冊表進行身份驗證。
Docker 透過 docker login
命令建立此模式,這是與 Docker 組態檔互動的方式,其中包含向特定登錄進行驗證的規則。 此檔案及其編碼的驗證類型受到Microsoft.Net.Build.Containers的支援,用於登錄驗證。 這應該可確保此套件能與您可以從 docker pull
的任何登錄順暢地運作,docker push
。 此檔案通常儲存在 ~/.docker/config.json
驗證種類
config.json 檔案包含三種驗證:
明確使用者名稱/密碼
config.json 檔案 auths
區段是登錄名稱和Base64編碼username:password字串之間的機碼/值對應。 在常見的 Docker 案例中,執行 docker login <registry> -u <username> -p <password>
會在此映射中建立新項目。 這些認證在持續整合 (CI) 系統中很受歡迎,其中登入是在執行開始時由令牌完成。 不過,由於檔案中有明文憑證帶來的安全風險,因此這樣的開發機器對於最終使用者來說較不受歡迎。
認證協助程式
config.json 檔案的 credHelpers
區段是登錄名稱與特定程式名稱之間的鍵值對映,用於建立和擷取該登錄的憑證。 當特定登錄具有複雜的驗證需求時,通常會使用此方式。 若要讓這類驗證能夠運作,您必須在系統的 PATH
上具有名為 docker-credential-{name}
的應用程式。 這類認證通常很安全,但很難在開發或 CI 計算機上設定。
系統金鑰鏈
credsStore
區段是單一字串屬性,其值是知道如何與系統密碼管理員互動的 Docker 認證協助程式程式名稱。 例如,對於 Windows,這可能是 wincred
。 這些適用於 macOS 和 Windows 的 Docker 安裝程式很受歡迎。
透過環境變數進行驗證
在某些情況下,上述標準的 Docker 驗證機制並不夠有效。 此工具有一個額外的機制,可透過環境變數提供憑證給註冊表。 如果使用環境變數,認證提供機制完全不會使用。 支援下列環境變數:
-
DOTNET_CONTAINER_REGISTRY_UNAME
:這應該是登錄的用戶名稱。 如果註冊密碼是令牌,那麼使用者名稱應該是"<token>"
。 -
DOTNET_CONTAINER_REGISTRY_PWORD
:這應該是登錄的密碼或令牌。
注意
自 .NET SDK 8.0.400 起,容器作業的環境變數已更新。
SDK_CONTAINER_*
變數現在前面會加上 DOTNET_CONTAINER_*
。
此機制可能容易受到認證外泄的影響,因此應該只在無法使用其他機制的情況下使用。 例如,如果您使用 Docker 容器本身內的 SDK 容器工具。 此外,此機制不是以命名空間隔離的,它會嘗試使用相同的憑證來存取 來源 倉庫(您的基礎映像檔所在的位置)和 目的地 倉庫(您推送最終映像檔的位置)。
使用不安全的註冊伺服器
大部分的登錄存取都是安全的,這表示 HTTPS 是用來與登錄互動。 不過,並非所有登錄都使用 TLS 憑證進行設定,特別是在 VPN 後方的私人公司登錄這類情況下。 為了支持這些使用案例,容器工具會提供宣告特定登錄使用不安全通訊的方式。
從 .NET 8.0.400 開始,SDK 會瞭解這些組態檔和格式,並會自動使用該組態來判斷是否應該使用 HTTP 或 HTTPS。 設定登錄以進行不安全的通訊會根據您選擇的容器工具而有所不同。
Docker
Docker 會將其登入設定儲存在 精靈組態中,。 若要新增不安全的註冊檔,請將新的主機新增至 "insecure-registries"
陣列屬性:
{
"insecure-registries": [
"registry.mycorp.net"
]
}
注意
您必須重新啟動 Docker 精靈,才能將任何變更套用至此檔案。
Podman
Podman 會使用 registries.conf
TOML 檔案來儲存登錄連線資訊。 此檔案通常位於 /etc/containers/registries.conf
。 若要新增不安全的登錄,會新增 TOML 區段來儲存登錄的設定,則 insecure
選項必須設定為 true
。
[[registry]]
location = "registry.mycorp.net"
insecure = true
注意
您必須重新啟動 Podman,才能將任何變更套用至 registries.conf 檔案。
環境變數
從 9.0.100 開始,.NET SDK 會辨識通過 DOTNET_CONTAINER_INSECURE_REGISTRIES
環境變數傳遞的不安全登錄。 此變數會採用以逗號分隔的網域清單,以與上述 Docker 和 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
遙測
當您將 .NET 應用程式發佈為容器時,.NET SDK 容器工具會收集及傳送有關工具使用方式的使用量遙測。 收集的數據,除了由 .NET CLI所傳送的
收集的遙測是一般性質,而不是洩漏任何個人資訊,其用途是協助測量:
- .NET SDK 容器化功能的整體使用情況。
- 成功和失敗率,以及最常發生何種失敗類型的一般資訊。
- 使用技術的特定功能,例如發佈至各種註冊類型,或如何開始發佈。
若要退出遙測,請將 DOTNET_CLI_TELEMETRY_OPTOUT
環境變數設定為 true
。 如需詳細資訊,請參閱 .NET CLI 遙測。
推斷遙測
記錄基底映射推斷程序發生方式的下列資訊:
日期時間點 | 解釋 | 範例值 |
---|---|---|
InferencePerformed |
如果使用者手動指定基底映像與使用推斷。 | true |
TargetFramework |
執行基底映像推斷時所選擇的 TargetFramework 。 |
net8.0 |
BaseImage |
所選基礎映像的值,僅限於該基礎映像是Microsoft製作的其中一張映像。 如果使用者在 mcr.microsoft.com 上指定 Microsoft 產生影像以外的任何影像,則此值為 null。 | mcr.microsoft.com/dotnet/aspnet |
BaseImageTag |
所選標記的值,但前提是該標記適用於其中一個Microsoft製作的影像。 如果使用者在 mcr.microsoft.com 上指定任何非由 Microsoft 製作的影像,此值為空值。 | 8.0 |
ContainerFamily |
如果使用者使用 ContainerFamily 功能來挑選我們一個基底影像的「變體」,則為 ContainerFamily 屬性的值。 只有當使用者從 mcr.microsoft.com 挑選或推斷出其中一個由 Microsoft 製作的 .NET 映像檔時,才會設定此情況。 |
jammy-chiseled |
ProjectType |
正在容器化的專案種類。 |
AspNetCore 或 Console |
PublishMode |
應用程式的封裝方式。 |
Aot 、Trimmed 、SelfContained 或 FrameworkDependent |
IsInvariant |
如果選擇的影像需要全球化不變性或用戶手動選擇了加入該選項。 | true |
TargetRuntime |
此應用程式為之發行的 RID。 | linux-x64 |
圖像創建遙測
以下是關於容器創建和發佈過程的記錄資訊:
日期參考點 | 解釋 | 範例值 |
---|---|---|
RemotePullType |
如果基底映像來自遠端登錄,則它是哪種登錄? | Azure、AWS、Google、GitHub、DockerHub、MRC 或其他 |
LocalPullType |
如果基底映像來自本機來源,例如容器精靈或 tarball。 | Docker、Podman、Tarball |
RemotePushType |
如果映像推送至遠端登錄,則它是哪種登錄? | Azure、AWS、Google、GitHub、DockerHub、MRC 或其他 |
LocalPushType |
如果影像被推送到本機目的地,那麼它是什麼? | Docker、Podman、Tarball |
此外,如果在處理期間發生各種錯誤,則會收集數據,以瞭解其錯誤類型:
時間點 | 解釋 | 範例值 |
---|---|---|
Error |
發生的錯誤種類 |
unknown_repository 、credential_failure 、rid_mismatch local_load 。 |
Direction |
如果錯誤是 credential_failure ,它是不是發生在推送的註冊表或提取的註冊表? |
push |
目標 RID | 如果錯誤是 rid_mismatch ,那麼請求的是哪個 RID? |
linux-x64 |
可用的 RID | 如果錯誤是 rid_mismatch ,基底映像支援哪些 RID? |
linux-x64,linux-arm64 |