通过 .NET 生成服务器端容器化 Docker 应用程序时,有两种支持的框架:.NET Framework 和 .NET Core。 这两者共享许多 .NET 平台组件,可在它们之间共享代码。 但两者之间存在根本差异,可根据需要实现的目标选择框架。

 

 

.NET Framework项目在容器上运行

限制:

1.对比 .NET Core 项目在容器上运行,.NET Framework项目无法跨平台运行(e.g不支持Linux)

2.对Windows系统有要求(较老的windows系统,虚拟化做的不好,可能不支持 & windows系统需要花钱)

 

何时为 Docker 容器选择 .NET Framework

  • 可能只想使用 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。

 

 

决策表:用于 Docker 的 .NET Framework

对于 Linux 容器,你需要基于 Linux 的 Docker 主机(VM 或服务器);对于 Windows 容器,你需要基于 Windows Server 的 Docker 主机(VM 或服务器)。

 

体系结构/应用类型 Linux 容器 Windows 容器
容器上的微服务 .NET Core .NET Core
单一应用程序 .NET Core .NET Framework
.NET Core
一流性能和可扩展性 .NET Core .NET Core
到容器的 Windows Server 旧应用程序(“棕色字段”)迁移 -- .NET Framework
基于容器的新开发(“绿色字段”) .NET Core .NET Core
ASP.NET Core .NET Core .NET Core(推荐)
.NET Framework
ASP.NET 4(MVC 5、Web API 2 和 Web 窗体) -- .NET Framework
SignalR 服务 .NET Core 2.1 或更高版本 .NET Framework
.NET Core 2.1 或更高版本
WCF、WF 和其他旧框架 .NET Core 中的 WCF(仅客户端库) .NET Framework
.NET Core 中的 WCF(仅客户端库)
Azure 服务的消耗 .NET Core
(最终大部分 Azure 服务都将为 .NET Core 提供客户端 SDK)
.NET Framework
.NET Core
(最终大部分 Azure 服务都将为 .NET Core 提供客户端 SDK)

 

何时为 Docker 容器选择 .NET Core

.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 容器选择_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 版本)

 

适用于开发与生产的 .NET Core 和 Docker 映像优化

为开发人员生成 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 发布时需要。

在此优化的映像中,只放置运行应用程序所需的二进制文件和其他内容。 例如,由 dotnet publish 创建的内容仅包含已编译的.NET 二进制文件、映像、.js 和 .css 文件。 随着时间推移,将推出包含预实时编译(在运行时进行从中间语言到本机语言的编译)包的映像

虽然 .NET Core 和 ASP.NET Core 映像有多个版本,但它们全都共享一个或多个层,包括基本层。 因此,存储映像所需的磁盘空间量很小;它仅包含自定义映像和其基础映像之间的增量。 结果,从注册表中提取映像速度会很快

在 Docker 中心浏览 .NET 映像存储库时,会发现已使用标记将多个映像版本进行分类或标记。 这些标记有助于决定使用哪一个,具体取决于需要的版本,如下表所示:

 

Image 注释
mcr.microsoft.com/dotnet/core/aspnet:3.1 ASP.NET Core,包含仅运行时和 ASP.NET Core 优化,适用于 Linux 和 Windows(多体系结构)
mcr.microsoft.com/dotnet/core/sdk:3.1 .NET Core,包含 SDK,适用于 Linux 和 Windows(多体系结构)