要在容器中執行.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/