天天看點

.NET Framework & .NET Core & Docker 容器選擇

通過 .NET 生成伺服器端容器化 Docker 應用程式時,有兩種支援的架構:.NET Framework 和 .NET Core。 這兩者共享許多 .NET 平台元件,可在它們之間共享代碼。 但兩者之間存在根本差異,可根據需要實作的目标選擇架構。

.NET Framework項目在容器上運作

限制:

1.對比 .NET Core 項目在容器上運作,.NET Framework項目無法跨平台運作(e.g不支援Linux)

2.對Windows系統有要求(較老的windows系統,虛拟化做的不好,可能不支援 & windows系統需要花錢)

可能隻想使用 Docker 容器來簡化部署(即便未建立微服務)。

對于此方案,大多數情況下無需将現有應用程式遷移到 .NET Core;可以使用包含傳統 .NET Framework 的 Docker 容器。 

不過,在擴充現有的應用程式(例如,在 ASP.NET Core 中編寫新服務)時,建議使用 .NET Core。

 例如,你可能希望使用 Docker 改進 DevOps 工作流 — 容器可以提供更好的獨立測試環境,并且還可以消除在遷移到生産環境時由于缺少依賴關系而導緻的部署問題。 在這種情況下,即使部署的是整體式應用程式,也可以為目前的 .NET Framework 應用程式使用 Docker 和 Windows 容器。

使用不可用于 .NET Core 的第三方 .NET 庫或 NuGet 包。

Windows 相容包擴充可供 Windows 上的 .NET Standard 2.0 使用的 API 接口。 通過此包,隻需略微修改或無需修改即可将大多數現有代碼重新編譯到 .NET Standard 2.x 以在 Windows 上運作; 

在 .NET Standard 2.0 及更高版本中,跨不同架構的 API 接口相容性已大大提高。 甚至 .NET Core 2.x 和更新版本的應用程式也可以直接引用現有的 .NET Framework 庫(請參閱支援 .NET Standard 2.0 的 .NET Framework 4.6.1)。

但即使 .NET Standard 2.0 和 .NET Core 2.1 取得了如此重大的進展,也可能出現某些 NuGet 包需要在 Windows 上運作并且可能不支援 .NET Core 的情況。 如果這些軟體包對于應用程式至關重要,那麼将需要在 Windows 容器上使用 .NET Framework。

使用不可用于 .NET Core 的 .NET 技術

目前版本的 .NET Core(撰寫本文時為 3.1 版)中沒有提供某些 .NET Framework 技術。 雖然某些技術将在更高版本中可用,但其他技術不适用于 .NET Core 面向的新應用程式模式,是以可能永遠不可用。

以下清單展示了在 .NET Core 3.1 中不可用的大多數技術:

ASP.NET Web 窗體。 該技術僅在 .NET Framework 上可用。 目前沒有将 ASP.NET Web 窗體引入 .NET Core 的計劃。

WCF 服務。 雖然 WCF 用戶端庫可從 .NET Core 使用 WCF 服務,但從 2020 年 2 月起,WCF 伺服器實作僅在 .NET Framework 上可用。 未來版本的 .NET Core 可能會考慮此方案,甚至會考慮将某些 API 包含在 Windows 相容包中。

與工作流相關的服務。 Windows Workflow Foundation (WF)、工作流服務(WCF + 單個服務中的 WF)和 WCF Data Services(以前稱為 ADO.NET Data Services)僅在 .NET Framework 上可用。 尚未計劃将其引入 .NET Core。

除了官方 .NET Core 路線圖中列出的技術之外,可能還會将其他功能移植到 .NET Core 或新的統一 .NET 平台中。 

使用不支援 .NET Core 的平台或 API

 某些 Microsoft 和第三方平台不支援 .NET Core。

如果 Azure 中的任何平台或服務仍然不支援 .NET Core 及其用戶端 API,則可以使用 Azure 服務中的等效 REST API 或 .NET Framework 上的用戶端 SDK。

例如,某些 Azure 服務提供尚不可用于 .NET Core 的 SDK。 大多數 Azure SDK 最終應移植到 .NET Core/Standard,但有些可能因各種原因而未移植。 可在 Azure SDK 最新版本頁中檢視可用的 Azure SDK。

對于 Linux 容器,你需要基于 Linux 的 Docker 主機(VM 或伺服器);對于 Windows 容器,你需要基于 Windows Server 的 Docker 主機(VM 或伺服器)。

體系結構/應用類型

Linux 容器

Windows 容器

容器上的微服務

.NET Core

單一應用程式

.NET Framework

一流性能和可擴充性

到容器的 Windows Server 舊應用程式(“棕色字段”)遷移

--

基于容器的新開發(“綠色字段”)

ASP.NET Core

.NET Core(推薦)

ASP.NET 4(MVC 5、Web API 2 和 Web 窗體)

SignalR 服務

.NET Core 2.1 或更高版本

WCF、WF 和其他舊架構

.NET Core 中的 WCF(僅用戶端庫)

Azure 服務的消耗

(最終大部分 Azure 服務都将為 .NET Core 提供用戶端 SDK)

.NET Core 的子產品化和輕量級特點使其特别适用于容器。 在部署和啟動容器時,使用 .NET Core 時容器的映像大小要遠小于使用 .NET Framework 時的大小。 

與此相反,若要為某個容器使用 .NET Framework,必須以 Windows Server Core 映像作為映像的基礎,此映像在體量上遠大于用于 .NET Core 的 Windows Nano Server 或 Linux 映像。

此外,.NET 核心可跨平台應用,這樣便可使用 Linux 或 Windows 容器映像部署伺服器應用。 

但如果使用傳統的 .NET Framework,隻能夠基于 Windows Server Core 部署映像。

 顯然,如果目标是獲得可在 Docker 支援的多個平台(Linux 和 Windows)上運作的應用程式(Web 應用或服務),正确的選擇是 .NET Core,因為 .NET Framework 僅支援 Windows。

.NET Core 還支援将 macOS 用作開發平台。 但如果要将容器部署到 Docker 主機,該主機必須(目前)基于 Linux 或 Windows。 例如,在開發環境中,可使用 Mac 上運作的 Linux VM。

還可在 macOS、Linux 和 Windows 中使用 Visual Studio Code。 Visual Studio Code 完全支援 .NET Core,包括 IntelliSense 和調試。 由于 VS Code 是輕量型編輯器,可以使用它,同時結合使用 Docker CLI 和 .NET Core CLI 在計算機上開發容器化應用。 還可以使用大多數第三方編輯器(如 Sublime、Emacs、VI)和同時提供 IntelliSense 支援的開源 OmniSharp 項目來面向 .NET Core。

Visual Studio 提供用于 Windows 的內建開發環境 (IDE) 并支援 Docker 開發。

Visual Studio for Mac 是一個 IDE,由 Xamarin Studio 演變而來,在 macOS 上運作并支援基于 Docker 的應用程式環境。 對于使用 Mac 計算機工作而又希望使用功能強大的 IDE 的開發者而言,這應當是理想之選。

除了 IDE 和編輯器,還可為所有支援的平台使用 .NET Core CLI。.NET Core 指令行接口 (CLI) 工具是用于開發、生成、運作和釋出 .NET Core 應用程式的跨平台工具鍊。.NET Core CLI 包含在 .NET Core SDK 中。 若要了解如何安裝 .NET Core SDK,請參閱安裝 .NET Core SDK。

雖然容器通常與微服務體系結構結合使用,但是也可用于對遵循任何體系結構模式的 Web 應用或服務進行容器化。 雖然能夠将 .NET Framework 用于 Windows 容器,但 .NET Core 的子產品化和輕型特點使之成為容器和微服務體系結構的最佳選擇。 在建立和部署容器時,使用 .NET Core 時容器的映像大小要遠小于使用 .NET Framework 時的大小。

可使用傳統 .NET Framework,通過使用普通程序建構基于微服務的應用程式(不含容器)。 通過這種方式,由于已安裝 .NET Framework 并在程序之間共享,程序變得輕量,進而可快速啟動。 但如果使用容器,傳統 .NET Framework 的映像便也基于 Windows Server Core,這樣的話,它對于“容器上微服務”方法,就顯得體量過于龐大。 但是,團隊也一直在尋找機會來改善 .NET Framework 使用者體驗。 最近,Windows Server Core 容器映像的大小已減小 40% 以上。

另一方面,如果要使用基于容器的面向微服務的系統,.NET Core 是最佳選擇,因為它體量輕。 此外,與之相關的容器映像,無論是 Linux 還是 Windows Nano Server,都精簡而小巧,讓容器變得輕量,進而能夠快速啟動。

微服務意味着盡可能得小:可輕松通路、占用空間小、小型的界定上下文(檢查 DDD、域驅動設計)、較少的關注度、能夠快速啟動和停止。 為滿足這些要求,需要使用可快速執行個體化的輕量型容器映像,例如 .NET Core 容器映像。

微服務體系結構還允許跨服務邊界,組合使用技術。 這樣,在其他微服務或服務使用 Node.js、 Python、 Java、 GoLang 或其他技術開發的一起工作的新微服務的逐漸遷移到.NET 核心。

如果基于容器的系統需要實作最佳密度、粒度和性能,.NET Core 和 ASP.NET Core 是最佳選擇。 ASP.NET Core 的運作速度比傳統 .NET Framework 中的 ASP.NET 高出 10 倍,領先于其他用于微服務的行業技術(例如 Java servlets、Go 和 node.js)。

這一點對微服務體系結構尤為重要,可以運作數百個微服務(容器)。 在 Linux 或 Windows Nano 上使用 ASP.NET Core 映像(基于 .NET Core 運作時),運作系統時所需的伺服器或 VM 數量要少得多,最終可以節省基礎結構和托管的費用。

使用 .NET 容器時定位的作業系統

由于 Docker 支援多種作業系統,且鑒于 .NET Framework 和 .NET Core 之間的差異,應根據所使用的架構,面向特定作業系統和特定版本。

對于 Windows,可使用 Windows Server Core 或 Windows Nano Server。 這兩種 Windows 版本分别提供 .NET Framework 和 .NET Core 各自所需的特征(Windows Server Core 中的 IIS 與 Nano Server 中自承載的 web 伺服器,如 Kestrel)。

對于 Linux,正式的 .NET Docker 映像(如 Debian)中提供并支援多個發行版本。

.NET Framework & .NET Core & Docker 容器選擇

部署舊的 .NET Framework 應用程式時,必須以與舊應用程式和 IIS 相容但具有更大映像的 Windows Server Core 為目标。 

部署 .NET Core 應用程式時,可以針對已經過雲優化、使用 Kestrel、更小且啟動速度更快的 Windows Nano Server。

還可以面向 Linux,支援 Debian、Alpine 和其他作業系統。 也使用 Kestrel、更小且啟動速度更快。

如果想使用不同的 Linux 發行版本或要使用 Microsoft 不支援的映像版本,還可以建立自己的 Docker 映像。 例如,可以使用 ASP.NET Core 建立一個在傳統 .NET Framework 和 Windows Server Core 上運作的映像,但這不是常見的 Docker 方案。

與完整的 Windows 映像相比,使用 Windows Server Core 映像時,你可能會發現缺少某些 DLL。 可以通過建立自定義 Server Core 映像,在映像建構時添加缺失的檔案來解決此問題,如本 GitHub 注釋中所述。

将映像名稱添加到 Dockerfile 檔案後,可根據所使用的标記選擇作業系統和版本,如下例所示:

圖像

注釋

mcr.microsoft.com/dotnet/core/runtime:3.1

.NET Core 3.1 多體系結構:支援 Linux 和 Windows Nano Server,具體取決于 Docker 主機。

mcr.microsoft.com/dotnet/core/aspnet:3.1

ASP.NET Core 3.1 多體系結構:支援 Linux 和 Windows Nano Server,具體取決于 Docker 主機。

ASP.NET Core 的 aspnetcore 映像具有多個優化。

mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim

Linux Debian 發行版上的 .NET Core 3.1 僅運作時

mcr.microsoft.com/dotnet/core/aspnet:3.1-nanoserver-1809

Windows Nano Server(Windows Server 版本 1809)上的 .NET Core 3.1 僅運作時

官方 .NET Docker 映像

官方 .NET Docker 映像是由 Microsoft 建立和優化的 Docker 映像。 這些映像在 Docker 中心的 Microsoft 存儲庫中公開提供。 

每個存儲庫可以包含多個映像,具體取決于 .NET 版本以及作業系統和版本(Linux Debian、Linux Alpine、Windows Nano Server、Windows Server Core 等)。

自 .NET Core 2.1 起,包括 ASP.NET Core 在内的所有 .NET Core 映像都在 .NET Core 映像存儲庫的 Docker Hub (https://hub.docker.com/_/microsoft-dotnet-core/) 提供。

自 2018 年 5 月起,Microsoft 映像将聯合到 Microsoft 容器系統資料庫中。 官方目錄仍然僅在 Docker 中心中提供,可在此處找到更新的位址以拉取映像。

大多數映像存儲庫提供廣泛的标記,以幫助選擇特定的架構版本以及 OS(Linux 發行版或 Windows 版本)。

為開發人員生成 Docker 映像時,Microsoft 側重于以下主要方案:

用于開發和生成 .NET Core 應用的映像 。

用于運作 .NET Core 應用的映像 。

為什麼是多個映像? 因為在開發、生成和運作容器化應用程式時,通常具有不同的優先級。 通過為這些單獨的任務提供不同的映像,Microsoft 有助于優化開發、生成和部署應用程式的單獨程序。

在開發期間,重要的是可循環通路更改的速度以及調試更改的能力。 與更改代碼的能力和快速檢視更改相比,映像的大小不是那麼重要。 某些工具和“build-agent 容器”在開發和生成程序中使用開發 .NET Core 映像 (mcr.microsoft.com/dotnet/core/sdk:3.1 )。 在 Docker 容器中生成時,重要方面是為了編譯應用所需要的元素。 這包括編譯器和任何其他 .NET 依賴項。

為什麼此類型的生成映像很重要? 不能将此映像部署到生産中。 相反,它是用于生成放置在生産映像中的内容的映像。 此映像将用于持續內建 (CI) 環境,或在使用 Docker 多階段生成時用于生成環境。

在生産中重要的是基于生産 .NET Core 映像部署和啟動容器的速度。 是以,基于 mcr.microsoft.com/dotnet/core/aspnet:3.1 的僅運作時映像很小,以便它可以通過網絡從 Docker 系統資料庫快速傳輸到 Docker 主機 。 已準備運作内容,以此實作從啟動容器到處理結果的最快時間。 在 Docker 模型中,不需要編譯 C# 代碼,但在使用生成容器運作 dotnet 生成或 dotnet 釋出時需要。

在此優化的映像中,隻放置運作應用程式所需的二進制檔案和其他内容。 例如,由 <code>dotnet publish</code> 建立的内容僅包含已編譯的.NET 二進制檔案、映像、.js 和 .css 檔案。 随着時間推移,将推出包含預實時編譯(在運作時進行從中間語言到本機語言的編譯)包的映像。

雖然 .NET Core 和 ASP.NET Core 映像有多個版本,但它們全都共享一個或多個層,包括基本層。 是以,存儲映像所需的磁盤空間量很小;它僅包含自定義映像和其基礎映像之間的增量。 結果,從系統資料庫中提取映像速度會很快。

在 Docker 中心浏覽 .NET 映像存儲庫時,會發現已使用标記将多個映像版本進行分類或标記。 這些标記有助于決定使用哪一個,具體取決于需要的版本,如下表所示:

Image

ASP.NET Core,包含僅運作時和 ASP.NET Core 優化,适用于 Linux 和 Windows(多體系結構)

mcr.microsoft.com/dotnet/core/sdk:3.1

.NET Core,包含 SDK,适用于 Linux 和 Windows(多體系結構)