要在容器中運作.net應用程式,你需要在容器鏡像中安裝.net Framework或.net Core 運作時。這不是你需要自己管理的東西,因為微軟提供的Docker鏡像已經安裝了運作時,你可以使用它們作為基礎鏡像來打包你自己的應用程式。
. net鏡像有幾種變體,涵蓋了不同的版本和不同的運作時。本文将指導你為應用程式選擇正确的鏡像。
使用基礎鏡像
你的應用需要運作一堆先決條件,比如作業系統和語言運作時。通常,平台所有者會打包一個安裝了所有預請求的鏡像,并将其釋出到Docker Hub上——你會看到Go, Node.js, Java等都是官方鏡像。
微軟對.net應用程式也做了同樣的事情,是以你可以使用它們的一個鏡像作為基礎鏡像。它們定期更新,是以你可以通過使用最新的微軟鏡像重建它們來修補你的鏡像。
.NET應用程式的Docker鏡像托管在微軟自己的容器系統資料庫mcr.microsoft.com上,但它們仍然列在Docker Hub上,是以你可以在那裡找到它們:
- .NET Core和.NET 5在Docker Hub上的鏡像
- .NET Framework在Docker Hub上的鏡像
這些頁面列出了許多不同的.net鏡像變體,并将它們劃分為SDK鏡像和運作時鏡像。
你可以用一個簡單的Dockerfile來打包.net應用:
FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8
SHELL ["powershell"]
COPY app.msi /
RUN Start-Process msiexec.exe -ArgumentList '/i', 'C:\app.msi', '/quiet', '/norestart' -NoNewWindow -Wait
這是一種進入Docker的簡單方法,擷取一個現有的部署包(在本例中是一個MSI安裝程式),并使用在容器中運作的PowerShell指令安裝它。
這個例子使用了ASP.NET 4.8的基本鏡像,是以你從這個Dockerfile建構的鏡像:
- 擁有IIS, . net Framework 4.8和ASP.NET已經配置。
- 從MSI部署你的應用程式,希望是一個ASP.NET應用程式。
- 需要有一個現有的程序來建立MSI。
這是一個簡單的方法,但它有問題,因為Dockerfile是打包格式,它應該包含部署的所有細節,但所有的安裝步驟都隐藏在MSI中。
相反,你可以使用Docker從源代碼編譯應用程式,這是SDK鏡像的來源。這些SDK鏡像有你的應用程式的所有建構工具:MSBuild和NuGet或dotnet CLI。你可以在一個多階段Docker建構中使用它們,其中階段1從源代碼編譯,階段2從階段1建構:
# the build stage uses the SDK image:
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 as builder
COPY src /src
RUN dotnet publish -c Release -o /out app.csproj
# the final app uses the runtime image:
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
COPY --from=builder /out/ .
ENTRYPOINT ["dotnet", "app.dll"]
這種方法更好,因為:
- 整個建構是可移植的,你隻需要Docker和源代碼來建構和運作應用程式,你不需要在你的機器上安裝任何.net sdk或運作時。
- 你的Dockerfile是部署腳本,每一步都很清晰,并且它在沒有額外的部署工作。
- 你的最終鏡像有它需要的所有運作時要求。
仍然有很多.net Docker鏡像的變體,是以下一個任務是找出哪些可以用于不同的應用程式。
.NET Framework應用程式的Docker鏡像
. net Framework應用程式是最簡單的,因為它們隻運作在Windows上,而且它們需要完整的Windows Server核心功能集。
你可以在任何你想要容器化的. net Framework應用中使用它們——你可以在Docker、Docker Swarm和Kubernetes中使用Windows容器來運作它們。
目前所有的. net Framework Docker鏡像都使用mcr.microsoft.com/windows/servercore:lts2019作為基礎鏡像——這是Windows Server Core 2019的最新長期支援版本。
然後.net鏡像以層次結構的形式從基本的Windows鏡像中擴充出來:
.NET Core應用的Docker鏡像
. net Core有點複雜,因為它是一個跨平台架構,有不同的鏡像可供Windows和Linux容器使用。你将優先使用Linux,因為它們更精簡,而且不需要為主機支付作業系統許可證。
Linux的變體源自Debian,它們使用類似于.net Framework鏡像的分層建構方法和相同的命名标準:
這些鏡像的名字需要再次使用mcr.microsoft.com/字首,現在aspnet: 3.1是aspnet别名:3.1.11,但下個月3.1相同的标簽将被用于一個更新的版本。
- dotnet/core/runtime:3.1包含.net core runtime,是以你可以使用控制台應用;
- dotnet/core/sdk:3.1已經安裝了sdk,是以你可以在建構階段使用它來編譯.net core應用程式;
- dotnet /core/ aspnet: 3.1 ASP.NET Core 3.1已安裝,是以你可以使用它來運作web應用程式。
.NET Core 3.1将支援到2022年12月;2.1也是一個LTS版本,支援到2021年8月,并且有用于2.1運作時的鏡像,使用相同的鏡像名稱和标簽:2.1。你可以在dotnet/dotnet-docker中找到GitHub上的所有Dockerfiles和一些示例應用程式。
還有一些.net core鏡像的Alpine Linux版本,它們更小更精簡。如果你正在建構運作在Linux上的鏡像,而你對跨平台運作在Windows上不感興趣,這些是最好的-但有些依賴不能在Alpine正常工作(Sqlite是其中之一),是以你需要測試你的應用:
- dotnet /core/runtime:3.1-alpine
- dotnet /core/ sdk: 3.1-alpine
- dotnet /core/ aspnet: 3.1-alpine
如果你想用相同的源代碼和dockerfile建構Linux和Windows的鏡像,堅持使用通用的:3.1——這些是多架構的鏡像,是以有針對Linux、Windows、Intel和Arm 64的版本。
Windows版本都是基于Nano伺服器的:
注意,它們有相同的鏡像名稱-多架構的鏡像Docker會拉出正确的版本來比對你使用的作業系統和CPU。你可以通過檢視清單來檢查所有可用的版本:
docker manifest inspect mcr.microsoft.com/dotnet/core/runtime:3.1
你将在響應中看到JSON,其中包括所有版本的詳細資訊——以下是删減後的版本:
"manifests": [
{
"digest": "sha256:6c67be...",
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
{
"digest": "sha256:d50e61...",
"platform": {
"architecture": "arm64",
"os": "linux",
"variant": "v8"
}
},
{
"digest": "sha256:3eb5f6...",
"platform": {
"architecture": "amd64",
"os": "windows",
"os.version": "10.0.17763.1697"
}
},
{
"digest": "sha256:4d53d2d...",
"platform": {
"architecture": "amd64",
"os": "windows",
"os.version": "10.0.18363.1316"
}
}
]
你可以在這裡看到鏡像标簽dotnet/core/runtime:3.1有用于Intel上的Linux、Arm上的Linux和Intel上的多個Windows版本的鏡像版本。
隻要你保持你的dockerfile是通用的——并且在運作指令中不包含特定于作業系統的指令——你就可以基于微軟的鏡像建構你自己的多架構 . net Core應用。
前進吧-.net 5的Docker鏡像
.NET 5是.net Core的新版本,在MCR上有一些常見版本的Docker鏡像:
- dotnet /runtime:5.0
- dotnet / sdk: 5.0
- dotnet / aspnet: 5.0
将.net Core應用遷移到.net 5應該是一個簡單的改變,但是請記住5不是一個LTS版本——你需要等待.net 6,它是LTS的。
歡迎關注我的公衆号,如果你有喜歡的外文技術文章,可以通過公衆号留言推薦給我。
原文連結:https://blog.sixeyed.com/understanding-microsofts-docker-images-for-net-apps/