Google Cloud 上的 .NET 应用的现代化改造路径

本文档介绍单体式应用的常见限制以及对其进行现代化改造的逐步而结构化的流程。

本文档适用于熟悉 Windows 和 .NET 生态系统并希望详细了解现代化改造所涉及的内容的云架构师、系统管理员以及 CTO。虽然本文档重点介绍定制的服务器应用(例如 ASP.NET 或 Windows 服务应用),但您也可以将这些经验应用于其他用例。

旧版应用与现代应用:为何进行现代化改造?

对旧版应用进行现代化改造是一个过程。该过程的起点和终点以及您获得的好处主要取决于应用的状态和您可以投入到现代化改造的时间和精力。

对 .NET 应用而言,何为旧版?何为现代?这个问题很难有详尽或确定的答案。每个应用都有不同的旧版和现代化需求。但是,旧版应用具有一些共同的常见限制。

下图总结了旧版应用和现代云端应用的特性。

单体式应用和现代云端应用之间的区别。

旧版 .NET 应用通常是基于 .NET Framework 构建的单体式应用,托管在本地 Microsoft Windows 服务器上,并连接到运行 Microsoft SQL Server 的本地服务器。您的架构细节可能与这些一般特征不同,但大多数单体式应用具有以下限制:

  • 需要管理运行 Windows 和 SQL Server 的本地服务器。
  • 部署环境有限,需要为 Windows 依赖支付许可费用。
  • 基于单体式架构构建的旧版应用难以升级。
  • 很难灵活地根据本地资源进行规划、预算和扩缩。

为云端架构构建的应用具有以下优势:

  • 通过与代管式服务集成,可最大限度地减少管理开销。
  • 可使用 .NET Core 和容器实现完全移动性,并且不涉及 Windows 依赖或许可费用。
  • 基于可独立部署的微服务的快速升级路径。
  • 借助无服务器架构实现完全灵活的扩缩和预算。

与传统的本地方法相比,云架构让您能够以一种更经济实惠且更具有弹性的方式运行应用。在基于云的方法中,您可以更灵活地选择部署应用的位置和时间。

现代化改造路径

虽然云端架构的优势十分明显,但云迁移路径可能并不如此。从旧版 .NET 架构到云端架构的现代化改造并没有一个通用的模式。如下图所示,现代化改造涉及一系列步骤,其中每个步骤都移除了限制,提升了应用功能,并为未来的现代化阶段提供了可能性。

现代化改造过程涉及的流程、技术和服务。

现代化改造分为三个阶段:

  1. 在云端重新托管(也称为“直接原样迁移”
  2. 改换平台
  3. 重构和重建

进行现代化改造前的评估和学习

在进行现代化改造之前,您必须做好准备。第一步是评估您的应用及其依赖项,以确定哪些应用适合进行现代化改造,哪些应用无法更改或迁移(通常是由于旧版相关原因或监管原因)。如需了解详情,请参阅迁移到 Google Cloud:评估和发现您的工作负载

在进行此评估的同时,您的团队需要了解云端功能。Google Cloud 提供有助于加快学习流程的认证技术指南以及针对 Windows 和 .NET 的 Codelab

确定需要进行现代化改造的应用后,您可以开始将传统应用按原样迁移到云端,或者对应用代码或配置进行少量更改。

第 1 阶段:在云端重新托管

第一阶段的主要目标是将服务器管理工作从本地资源转移到云端基础架构。在此阶段,您需要确保您的基础架构支持云技术,以便稍后针对云端对其进行优化。

手动迁移与基于工具的迁移

要对基于 Windows 的.NET 应用进行直接原样迁移,通常需要首先将本地 Windows Server 和 SQL Server 实例迁移到 Compute Engine 虚拟机实例。您可以手动执行此过程,也可以借助迁移工具自动执行。

在手动迁移中,您可以使用 Compute Engine Windows Server 映像来启动实例。Google Cloud Marketplace 还提供部署到 Compute Engine 的现成解决方案(例如 ASP.NET Framework 解决方案),以获取包含 IIS、SQL Express 和 ASP.NET 的 Windows Server 虚拟机。

同样,您可以从 SQL Server 映像启动 SQL Server 实例,也可以直接使用代管式解决方案:Cloud SQL for SQL Server

Google Cloud 还提供 Migrate for Compute EngineVMware Engine 等迁移工具,可帮助您将本地 VMware 虚拟机迁移到 Google Cloud 中的 VMware 环境。

配置虚拟机后,您通常会创建自定义虚拟机映像,以便按需重新创建新实例。此步骤对于实例模板也很重要,本文档稍后将对此进行讨论。

如果您需要云端网域服务,则可以在 Compute Engine 上使用 Virtual Private Cloud (VPC) 部署容错 Microsoft Active Directory 环境或直接使用 Managed Service for Microsoft Active Directory

本地和云连接

在将虚拟机迁移到云端时,将某些工作负载保留在本地的情况很常见,例如,您的应用需要旧版硬件或软件,或者您需要满足合规性和当地监管要求。您需要 VPN 或互连解决方案来安全地连接本地和云端资源。如需了解创建和管理此连接的各种方法,以及运行混合云和本地工作负载的其他影响,请参阅迁移到 Google Cloud:构建您的基础

初始优势

在阶段 1 结束时,您的基本基础架构将在云端运行,它提供以下优势:

  • 优化费用。您可以创建自定义机器类型(CPU、内存和存储)并按实际用量支付费用;根据需要启动和停止虚拟机和灾难恢复环境并仅在它们运行时付费;以及在迁移之前获取合理容量建议
  • 提高运维效率。您可以将永久性磁盘挂接到虚拟机,并创建快照以简化备份和恢复。
  • 提高可靠性。实时迁移功能使您不再需要安排维护期。

这些初始优势非常有用,但在您开始针对云端进行优化后,可以获得更多好处。

第 2 阶段:改换平台

改换平台时,您可以通过升级应用组件(例如数据库、缓存层或存储系统)来优化应用,无需更改应用架构,只需要对代码库进行最少的更改。第 2 阶段的目标是开始使用云功能来提高应用的管理能、弹性、可扩缩性和弹性,而无需大幅度地重新构建该应用或退出虚拟机环境。

利用 Compute Engine

Compute Engine 提供了一些有用的标准功能。例如,您可以使用 Compute Engine 中的实例模板从现有虚拟机配置创建模板。实例组是一组相同的虚拟机,可让您高效地扩缩应用的性能和冗余。除了简单的负载平衡和冗余之外,代管实例组具有自动扩缩等可扩缩功能,自动修复区域部署等高可用性功能以及自动更新等安全功能。

借助这些功能,您可以继续使用虚拟机环境,但可以提高应用的弹性、冗余和可用性,而无需完全重新构建应用。

查找就地替换选项

在将应用迁移到云端时,您需要寻找机会将托管式基础架构替换为 Cloud Marketplace 上的 Google 和第三方合作伙伴提供的代管式云选项,包括:

  • Cloud SQL,而不是自托管的 SQL Server、MySQL 或 Postgres。借助 Cloud SQL,您可以专注于管理数据库,而无需管理基础架构(例如修补数据库虚拟机以提高安全性或管理备份),同时还能额外获得无需 Windows 许可这一优势。
  • Managed Service for Microsoft Active Directory,而不是自托管的 Active Directory。
  • Memorystore,而不是自托管的 Redis 实例。

这些替换不需要更改代码,只需进行少量配置更改,而且具有极少的管理开销、更强的安全性和可扩缩性的优势。

Windows 容器的起始步骤

针对云端优化基本功能后,您可以开始从虚拟机到容器的迁移。

容器是一个包含应用及其所有依赖项的轻量级软件包。与直接在虚拟机上运行应用相比,容器可让您在各种环境运行应用,并能够以更一致、可预测且更高效的方式运行应用(尤其是在同一主机上运行多个容器时)。Kubernetes、Istio 和 Knative 等容器周围的生态系统还提供了许多管理、弹性和监控功能,可以进一步加快应用从单体式结构到一组专门的微服务的转换。

在很长一段时间内,容器化是一种仅适用于 Linux 的功能。Windows 应用无法从容器中受益。在 Windows 容器及其后续对 Kubernetes 的支持Google Kubernetes Engine (GKE) 出现后,这一情况发生了改变。

如果您不想将.NET Framework 应用迁移到.NET Core,但仍想获得容器的优势(例如敏捷性、可移植性和控制),则可以选择 Windows 容器。您需要根据 .NET Framework 版本选择合适的目标操作系统。需要注意的是,并非所有 Windows 堆栈都受 Windows 容器支持。如需了解此方法和替代方法的限制,请参阅本文档稍后的 .NET Core 和 Linux 容器部分。

将 .NET Framework 应用容器化为 Windows 容器后,我们建议您在 Kubernetes 集群中运行该应用。Kubernetes 提供了许多标准功能,例如检测容器 Pod 故障并重新创建 Pod、自动扩缩 Pod、自动发布或回滚以及运行状况检查。GKE 通过 Anthos 添加了集群自动扩缩、地区级集群、高可用性控制层面以及混合云和多云端支持等功能。 如果您决定使用 GKE 或 Anthos,则可以使用 Migrate for Anthos 来简化和加快 Windows 虚拟机到容器的迁移过程。Migrate for Anthos 可自动将应用从虚拟机提取到容器中,而无需您重写或重新构建应用。

虽然您可以使用 Compute Engine 中的恰当功能实现诸多优势,但迁移到容器和 GKE 后,您可以将多个 Pod 打包到相同的虚拟机,从而帮助您充分利用虚拟机。此策略可以减少虚拟机数量,从而降低 Windows 许可费用。

使用 Kubernetes 和 GKE 以声明方式管理 Windows 和 Linux 容器还可以简化您的基础架构管理。实现容器化后,您的团队已为下一步的现代化改造做好准备。

第 3 阶段:重构和重建

改换平台只是充分获享云端优势的开始。将您的架构转换为云平台具有诸多优势,例如:

  • 使用 Kubernetes 和 Linux 容器(而不是 Windows 容器)并将工作负载迁移到无服务器计算,从而增强成本优化
  • 将自行管理的虚拟机替换为提供多区域可用性、更严格的服务等级协议 (SLA) 和更好的安全性的代管式服务,从而提高可靠性和可用性
  • 通过持续集成工具提高开发者的工作效率和软件质量,从而加速产品交付。您可以使用这些工具在几分钟内创建自动化的构建、运行测试、预配环境并扫描工件中是否有安全漏洞。
  • 通过 PB 级数据仓储强一致性的可全球扩缩的数据库以及多区域和高可用性存储解决方案,应用可以实现更多功能

迁移到代管式服务

当您开始重新编写应用的某些部分时,我们建议您开始从托管式服务迁移到代管式服务。例如,您可以使用以下服务:

虽然您需要额外的代码来将您的应用与这些服务进行集成,但这样做非常值得,因为您可以将平台管理工作转移到 Google Cloud。与 Google Cloud .NET 客户端库适用于 Visual Studio 的工具和适用于 Visual Studio Code 的 Cloud Code 等服务集成后,您仍然可以留在.NET 生态系统中并继续使用相关工具。

代管式服务还支持应用的运维。您可以将应用日志存储在 Cloud Logging 中,并将应用指标发送到 Cloud Monitoring,从而使用服务器和应用指标构建信息中心。Google Cloud 为 Cloud LoggingCloud MonitoringCloud Trace 提供 .NET 客户端库。

.NET Core 和 Linux 容器

如果您的应用是仅在 Windows 上运行的旧版 .NET Framework 应用,您可能希望它在 Compute Engine 上的 Windows 服务器或 GKE 上的 Windows Server 容器中运行。虽然这种方法在短期内可能有效,但从长远来看,它可能会严重限制您。与 Linux 相比,Windows 会产生许可费并且总体资源配额更高,因此从长远来看,这些因素会导致所有权成本更高。

.NET Core 是 .NET Framework 的现代和模块化版本。Microsoft 指南中表示“.NET Core 是 .NET 的未来”。虽然 Microsoft 计划支持 .NET Framework,但新功能将仅添加到 .NET Core(以及 .NET 5)。即使您仍想在 Windows 上运行,也应该在.NET Core 上进行新的开发。

.NET Core 最重要的方面之一是它支持多平台。您可以将.NET Core 应用容器化为 Linux 容器。Linux 容器比 Windows 容器更轻量化,可以更高效地在更多平台上运行。这一因素为 .NET 应用创建了部署选项,使您能够免除对 Windows 的依赖以及相关的许可费用。

将 .NET Framework 应用移植到 .NET Core

迁移到 .NET Core 的一个好的开端是阅读从 .NET Framework 移植到 .NET Core 的概览.NET Portable Analyzer.NET API Analyzer 等工具可帮助您确定组件和 API 是否可移植。其他移植工具(如 dotnet try-convert)也很有帮助。

外部工具可帮助您识别兼容性问题并确定要先迁移的组件。最终,您需要创建.NET Core 项目,逐渐将.NET Framework 代码迁移到新项目中,并修复此过程中出现的任何不兼容问题。在移植代码之前,请务必准备好测试,然后在移植后测试功能。我们建议您使用 A/B 测试来测试旧代码和新代码。通过 A/B 测试,您可以在将部分用户定向到新应用的同时保持旧版应用的运行。通过此方法,您可以测试新应用的输出、可扩缩性和弹性。为了帮助您进行 A/B 测试,Google Cloud 提供负载平衡解决方案,例如 Traffic Director

文化变革

从 .NET Framework 和 Windows 服务器到 .NET Core 和 Linux 容器的转换不仅仅是技术上的。这种转变要求您的组织内部进行文化变革。可能习惯于单一 Windows 环境的员工需要适应多平台环境。这种文化转型需要您为针对 .NET Core、Linux 和容器工具(如 Docker 和 Kubernetes)的培训投入时间和预算。但是,组织从单一 Windows 环境转型为多平台环境后,可获得更多工具和技能。

分解单体式应用

从 .NET Framework 迁移到 .NET Core 可能会引发一些问题,包括:

  • 您是否在 .NET Core 中重写整个应用?
  • 您是否将应用拆分为较小的服务并使用 .NET Core 编写服务?
  • 您是否只是在 .NET Core 中编写新服务?

在确定这些问题时,您需要考虑每种方法相关的优势、时间和费用。最好使用一种平衡的方法,可以让您无需重新编写所有内容,而是仅写入新服务。在适当的情况下,NET Core 会将现有的单体式应用拆分为 .NET Core 中的较小服务。以下白皮书可以帮助您进行规划:

.NET Core 容器的部署选项

在 Google Cloud 上部署 .NET 应用所述,在 Google Cloud 上部署 .NET Core 容器有不同的选项。在将单体式应用解构为微服务时,您可能会决定根据微服务的架构和设计使用多个托管解决方案。

回答以下问题有助于确定最佳托管策略:

  • 什么会触发您的应用?所有托管解决方案都适用于标准 HTTP(S),但如果您的协议是 TCP/UDP 或专有协议,则 GKE 可能是唯一的选项。
  • 您的应用是否需要特定硬件?Cloud Run 为每个请求提供一个合理但有限的 RAM 和 CPU 数量。Cloud Run for Anthos 提供了更多自定义选项,例如 GPU、更多内存和磁盘空间。
  • 您对扩缩的期望是什么?如果应用存在非活动状态的时期,则无服务器解决方案(例如 Cloud Run )可提供缩容至零的选项。
  • 延迟时间有多重要以及您的应用对冷启动的容忍度有多高?如果对冷启动的容忍很低,您需要考虑在 App Engine 柔性环境或自动扩缩的 GKE 上使用最少数量的实例。
  • 您的服务是否与其他服务通信?如果您的应用需要访问 VPC 或对等互连的 VPC,请考虑在 App Engine 柔性环境、Cloud Run for Anthos 或 GKE 中托管您的应用。

建议您阅读每个托管环境的文档,以了解其功能、优缺点以及价格模式。

一般规则是,如果要创建传送 HTTP 请求的微服务,则需要尽可能部署到 Cloud Run;如果想要继续留在 Kubernetes 生态系统中或需要更多自定义选项,则回退至 GKE。如果您有长时间运行的进程(如侦听队列的进程),或使用 HTTP(S) 以外的协议的应用,则 GKE 也是默认选项。我们建议您仅在由于某些限制(例如 WebSocket 支持或连接到 VPC 网络)而无法使用 Cloud Run 时,或者您的应用不适用 Kubernetes 的复杂性时才使用 App Engine 柔性环境。

App Engine 标准环境和 Cloud Functions 也是理想的无服务器部署选项,但此处未讨论这些选项,因为它们目前不支持.NET Core。

App Engine 柔性环境

App Engine 柔性环境是一个可以直接运行以多种语言编写的网络应用,包括 .NET Core。App Engine 会在具有 .NET 运行时的 Docker 容器中安装并运行 .NET Core 应用。如果您想自定义此运行时,则可以向 App Engine 提供您自己的 Dockerfile。App Engine 仍会使用基于虚拟机的 Compute Engine 实例,但 App Engine 会管理这些虚拟机。柔性环境附带自动扩缩、修订版本和流量拆分等功能。柔性环境还允许单个应用中的多项服务,这对微服务架构很有用。

如果您要部署 Web 前端或少量相似的容器,则可以选择使用 App Engine。但是,使用 App Engine 时,部署时间通常比其他选项慢,并且即使您不使用应用,也仍需为每个虚拟机付费。

Kubernetes 和 GKE

如果要在针对容器优化的环境中运行,则该方法可能涉及 Kubernetes 及其代管版本 GKE。如果您计划部署多个具有不同要求的容器,并需要精确控制每个容器的部署和管理方式,Kubernetes 和 GKE 尤其适用。

Kubernetes 适用于大规模运行容器,并提供 Pod、Service、Deployment 和副本集等基础组件。正确地理解和使用这些构造并不容易,但它们允许您将容器的大部分管理任务转移到 Kubernetes。它们还非常适合微服务架构,其中微服务是 Service 后面包含一组负载平衡的 Pod 的 Deployment。

除了 Kubernetes 之外,GKE 提供可以简化 Kubernetes 管理的集群自动扩缩、自动修复和自动升级等功能,以及容器隔离和私有镜像仓库等安全功能。虽然您需要为 GKE 中集群的每个节点付费,但 GKE 支持使用抢占式虚拟机来降低费用。

GKE 可以同时管理 Windows 和 Linux 容器。如果要为基于 Windows 的应用和现代 Linux 的应用维护单个混合环境,此功能会非常有用。

Knative 和 Cloud Run

对于无状态 .NET Core 容器,Knative 及其代管版本 Cloud Run 提供了无服务器容器环境。无服务器容器具有诸多优势,例如预配、自动扩缩和负载平衡功能,并且没有基础架构管理开销。

为了在 Kubernetes 集群中部署容器,Knative 提供了一个比 Kubernetes 层级更高且更小巧的 API 接口。Knative 可以帮助您避免 Kubernetes 的复杂性,从而简化容器部署过程。

Cloud Run 遵循 Knative API,但在 Google 基础架构上运行,因此无需使用 Kubernetes 集群。Cloud Run 为容器提供了无服务器选项。默认情况下,在 Cloud Run 中,容器在请求期间自动扩缩并被收取费用。部署时间以秒计。Cloud Run 还继承了 App Engine 中的一些有用功能,例如修订版本和流量拆分。

Cloud Run for Anthos 是 Cloud Run 更灵活的版本,适合需要 Knative 和 Cloud Run 的简洁性以及 Kubernetes 的操作灵活性的用户。例如,Cloud Run on Anthos 允许将 GPU 添加到运行容器的底层实例上,或者访问同一 VPC 中的其他虚拟机或 GKE 集群。

Cloud Run 可与 Pub/Sub、Cloud Scheduler、Cloud Tasks 等其他服务以及 Cloud SQL 等后端集成。它可用于自动扩缩的 Web 前端或由事件触发的内部微服务。

运营的现代化改造

现代化改造不仅限于应用代码。它适用于应用的整个生命周期,即构建、测试、部署和监控。因此,当您考虑现代化改造时,您需要考虑运维。

Cloud Build 可以帮助您对应用的构建、测试、部署周期进行现代化和自动化改造。Cloud Build 不仅提供适用于 .NET Core 的构建器,还与 Container Registry 的漏洞扫描工具Binary Authorization 集成,防止由未知来源代码构建或来自不安全的镜像仓库的映像在您的部署环境中运行。

Google Cloud 的运维套件(以前称为 Stackdriver)提供了一些服务,可让您对应用的可观察性进行现代化改造:

您可以使用 Google.Cloud.Diagnostics.AspNetCore 库将 Google Cloud 的运维套件轻松集成到您的 ASP.NET Core 应用中。要将 OpenTelemetry 指标导出到该运维套件,您可以使用 OpenTelemetry.Exporter.Google Cloud's operations suite 库。

如需详细了解现代化改造如何应用于团队流程和文化,请参阅Google Cloud 的 DevOps 解决方案

后续步骤