使用 Windows 容器“容器化”现有应用程序

适用范围:Windows Server 2022、Windows Server 2019、Windows Server 2016

Windows 容器提供一种很棒的机制来实现传统或旧版应用程序的现代化。 尽管你可能听过这种称为“直接迁移到容器”的方法,但直接迁移的比喻源于将工作负载从物理计算机转移到虚拟机,并且最近用于描述将工作负载按原样移动到云(私有或公共)。 现在,此术语更适用于迁移虚拟机 (VM)。 但容器不是 VM,如果将它们视为 VM,可能会导致对如何容器化应用程序产生困惑,或者对是否可以或是否应该进行容器化产生困惑。

本主题提供有关将传统应用程序迁移到 Windows 容器的实用指南。 它旨在通过提前说明特殊注意事项来帮助确定应容器化的应用程序的优先级。

简介

Windows 容器的定义

通用术语“容器”是指一种虚拟化操作系统 (OS) 的技术。 此虚拟化提供与服务器/主机本身的 OS 的隔离级别,从而为应用程序开发人员和运营团队提供了更高的灵活性。

Windows 容器是容器技术的特定实现。 它们提供与 Windows OS 隔离的虚拟化操作系统实例。 但容器和主机之间不可能完全相互依赖:Windows 容器必须与 Windows OS 协调其对资源和函数的需求。 为什么这很重要? 因为 Windows 容器不是一个完整的虚拟化服务器,并且你可能希望对应用程序执行的某些操作不能仅使用虚拟化的 OS 来完成。

你可以在容器与虚拟机中详细了解本主题。 下面提供了可帮助你记住容器与 VM 的区别的几个要点:

  • 容器不是等效于桌面应用程序虚拟化的解决方案。 它们仅支持不需要交互式会话的服务器端应用程序。 由于它们在专用容器映像上运行,因此它们仅支持不需要图形前端的应用程序。
  • 容器本质上是临时容器。 这意味着,默认情况下,没有用于保存容器实例状态的机制。 如果一个实例失败,另一个实例将取代它。

容器技术始于 Linux,以 Docker 作为标准。 Microsoft 与 Docker 紧密合作,以确保容器功能在 Windows 上尽可能保持一致。 Linux 和 Windows 之间的固有差异可能显示为 Windows 容器的局限性,而实际上它们就是 Linux 与 Windows 的差异。 另一方面,Windows 容器提供一些独特的实现(例如 Hyper-V 隔离),稍后会对此进行介绍。 本主题将帮助你了解这些差异以及如何适应它们。

使用容器的好处

类似于在单个物理主机上运行多个 VM,你可以在单个物理或虚拟主机上运行多个容器。 但与 VM 不同,你无需管理容器的 OS,这使你能够灵活地专注于应用程序开发和底层基础结构。 这也意味着你可以隔离应用程序,使其不受由 OS 支持的任何其他进程的影响。

容器提供一种轻量型方法,用于创建和动态停止正常运行的应用程序所需的资源。 虽然可以在应用程序需求增加时创建和部署 VM,但使用容器进行横向扩展会更快。使用容器时,你还可以在发生故障或硬件中断时快速重启。 容器使你能够完成任何应用的从开发到生产过程,而几乎不需要进行代码更改,因为它们“包含”应用程序依赖项,因此可以跨环境运作。 由于跨 Microsoft 开发人员工具的 Docker 集成,通过最少的代码更改容器化现有应用程序的功能也是应用程序开发和维护方面的一个重要因素。

最后,使用容器的最重要优势之一是你在应用开发方面可获得的灵活性,因为你可以在同一主机上运行某个应用的不同版本,且不会发生资源冲突。

可以在 Microsoft .NET 文档页上找到对现有应用程序使用容器的优势的更完整列表。

隔离级别的重要概念

Windows 容器提供与 Windows OS 的隔离,在生成、测试应用以及将应用提升到生产环境时,这种隔离是有利的。 但是,当你考虑容器化应用程序时,请务必了解实现隔离的方式。

Windows 容器提供了两种不同的运行时隔离模式:进程 和 Hyper-V。 在这两种模式下运行的容器在创建、管理和功能方面都是相同的。 那么,它们之间有什么区别呢?你为什么要注意这些呢? 在进程隔离中,可以通过命名空间、资源控制以及其他功能进行隔离,这样多个容器就可以同时在单个主机上运行。 在进行模式下运行的容器与主机之间以及容器与容器之间会共享同一个内核。 这与 Linux 容器的运行方式大致相同。

在 Hyper-V 隔离中,多个容器也可同时在单个主机上运行,但这些容器在高度优化的虚拟机内部运行,每个容器都可有效地获取自己的内核。 由于此虚拟机(实际上是“实用工具”VM)的存在,因此可以在每个容器之间以及容器与容器主机之间进行硬件级别的隔离。

在某种程度上,Hyper-V 隔离模式几乎就像是 VM 与容器的混合,在应用需要多租户时提供额外的安全层,这非常有用。 但是,使用 Hyper-V 隔离模式的弊端包括:

  • 容器的启动时间更长,并且可能会对整体应用性能产生影响。
  • 并非所有工具都以本机方式使用 Hyper-V 隔离。
  • 目前,Azure Kubernetes 服务 (AKS) 和 Azure Stack HCI 上的 AKS 都不支持 Hyper-V 隔离。

可以在隔离模式主题中详细了解如何实现这两种隔离模式。 首次容器化应用时,需要在这两种模式之间进行选择。 幸运的是,之后可以非常轻松地从一种模式更改为另一种模式,因为不需要对应用程序或容器进行任何更改。 但请注意,当你容器化应用时,你要完成的第一件事是在这两种模式之间进行选择。

容器业务流程

无需担心 OS 管理即可在单个或多个主机上运行多个容器,这为你提供了极大的灵活性,从而帮助你转向基于微服务的体系结构。 但是,这种灵活性所带来的代价是,基于容器和微服务的环境可能会迅速发展成许多移动部件 - 由于数量过多而无法跟踪。 幸运的是,管理负载均衡、高可用性、容器计划、资源管理等是容器业务流程协调程序的职责。

业务流程协调程序也许是误称;他们更像是管弦乐队的指挥,因为他们协调多个容器的活动,以保持音乐播放。 从某种意义上说,它们以类似于 OS 功能的方式处理容器的计划和资源分配。 因此,在容器化应用程序时,你需要在支持 Windows 容器的业务流程协调程序之间进行选择。 一些最常见的业务流程协调程序是 Kubernetes 和 Docker Swarm。

无法移动到 Windows 容器的内容

考虑是否可以对某个应用进行容器化处理时,最简单的方法可能是从完全排除 Windows 容器这一选项的因素列表开始。

下表汇总了无法移动到 Windows 容器的应用类型以及原因。 此表后面的子部分中更详细地解释了这些原因。 了解这些限制背后的原因可让你更清楚地了解容器到底是什么,包括它们与 VM 有何不同。 这反过来会帮助你更好地评估 Windows 容器的功能,这些容器可用于可以容器化的现有应用。

注意:下表不是完整列表。 这是 Microsoft 看到客户尝试容器化的应用的汇编。

不支持的应用程序/功能 不支持的原因 你可以解决此问题吗?
需要桌面的应用程序 容器不支持图形用户界面 (GUI) 如果应用程序只需要安装 GUI,则将其更改为无提示安装可能会解决此问题
使用远程桌面协议 (RDP) 的应用程序 RDP 适用于交互式会话,因此上述原则在此处也同样适用 可以使用 Windows Admin Center (WAC) 或远程 PowerShell 作为远程管理的替代方法
有状态应用程序 容器是临时容器 可以,某些应用程序可能需要进行最少的更改,因此它们不会在容器中存储数据或状态
数据库应用程序 容器是临时容器 可以,某些应用程序可能需要进行最少的更改,因此它们不会在容器中存储数据或状态
Active Directory Active Directory 的设计和用途不包括在容器中运行 错误。 但是,依赖于 Active Directory 的应用可以使用组托管服务帐户 (gMSA)。 下面提供了有关 gMSA 的详细信息
较旧的 Windows Server 版本 只支持 Windows Server 2016 或更高版本 错误。 但是,应用程序兼容性可能是一个选项 - 大多数 Windows Server 2008/R2 和较旧的应用都在较新版本的 Windows Server 上运行
使用 .NET Framework 2.0 或更早版本的应用 需要特定的容器映像来支持 .NET Framework,并且仅支持较新版本 完全不支持低于 2.0 的版本,但有关更高版本所需的容器映像,请参阅以下内容
使用其他第三方框架的应用 Microsoft 不会专门认证非 Microsoft 框架或支持在 Windows 容器上使用这些框架 请与特定框架或应用供应商联系,了解 Windows 容器的支持策略。 有关详细信息,请参阅下文

让我们依次了解这些限制。

需要桌面的应用程序

容器适用于从其他应用程序(包括具有用户交互的应用程序)调用的临时函数。 但是,不能将容器用于具有 GUI 的应用程序。 即使应用程序本身没有 GUI,但具有依赖于 GUI 的安装程序,情况也是如此。 一般情况下,可以使用 PowerShell 调用 Windows 安装程序,但如果应用程序需要通过 GUI 进行安装,那么该应用程序无法进行容器化处理。

这不是 Windows 容器实现方式的问题,而是容器工作原理的基本概念。

如果应用需要 GUI API,那就是另一回事了。 尽管由这些 API 提供服务的 GUI 不受支持,但这些 API 是受支持的。 Nano Server x 服务器核心 x 服务器 - 哪种基础映像适合你?主题中更详细地解释了此内容。

使用 RDP 的应用程序

由于远程桌面协议 (RDP) 的全部用途是建立交互式视觉会话,因此刚才所述的 GUI 限制也适用。 无法按原样容器化使用 RDP 的应用程序。

但是,一种不错的替代方法是远程管理工具,例如 Windows Admin Center。 可以使用 Windows Admin Center 来管理 Windows 容器主机和容器本身,而无需在其中添加 RDP。 还可以打开与主机和/或容器的远程 PowerShell 会话来管理它们。

有状态应用程序

仅当将所需数据从一个会话隔离到下一个会话,并将其存储在持久性存储中时,才能容器化需要保留状态数据的应用程序。 这可能需要进行一些“重构”,这也许简单,也许不简单,但继续操作将消除容器化过程中的这一障碍。

状态的一个示例是将图像或音乐文件存储到本地文件夹的 Web 应用程序。 在传统的 Windows 环境中,文件会在写入操作结束时保存到磁盘中,因此,如果实例(在此示例中为 VM)失败,你只需将其恢复,文件仍将存在。 相比之下,如果执行写入操作的容器实例失败,则新容器实例不会包含该文件。 因此,你应考虑使用持久性存储,以便所有容器实例都可以将状态数据或文件存储到一个集中的持久位置。 这种类型的重构不需要更改应用程序代码,只需更改 Windows 实例使用的存储类型。 有关详细信息,请查看有关存储的 Windows 容器文档

然而,这就引出了另一个相关主题…

数据库应用程序

一般来说,数据库应用程序不是容器化的最佳选择。 虽然可以在容器内运行数据库,但容器化现有数据库通常并不理想,有两个原因。

首先,数据库所需的性能可能需要主机可用的全部硬件资源,这会降低合并的益处。 其次,单个数据库层的多个实例需要对其写入操作进行协调。 容器业务流程可以解决此问题,但对于现有数据库,业务流程可能会成为一项开销。 大多数数据库(如 Microsoft SQL Server)都有内置的负载均衡和高可用性机制。

Windows Server 上的基础结构角色

Windows Server 基础结构角色主要处理更接近操作系统的功能(例如 AD、DHCP 和文件服务器)。 因此,它们不适用于运行容器。 因而,需要这些角色的应用程序始终难以容器化。

有一些灰色地带。 例如,某些功能(如 DNS)可能适用于 Windows 容器,尽管它们并非真正打算用于容器。 其他基础结构角色只是从基础容器映像中删除,并且无法安装,例如 Active Directory、DHCP 和其他角色。

Active Directory (AD)

Active Directory 是二十多年前随 Windows 2000 Server 一起发布的。 它使用一种机制,其中每台设备或每位用户由存储在其数据库中的对象表示。 此关系紧密耦合,即使实际用户或设备不再发挥作用,对象也会保留在数据库中。 Active Directory 的这种方法直接与容器的临时性质相矛盾,这些容器应是短期的或在关闭时删除。 与 Active Directory 保持这种一对一关系不适用于这些方案。

因此,Windows 容器无法加入域。 因而,你无法将 Active Directory 域服务作为基础结构角色在 Windows 容器上运行。 可以运行 PowerShell 模块,以便在 Windows 容器内远程管理域控制器。

对于在依赖于 Active Directory 的 Windows 容器上运行的应用程序,你可以使用组托管服务帐户 (gMSA),稍后将对此进行进一步说明。

使用 .NET Framework 2.0 或更早版本的应用

如果应用程序需要 .NET,则容器化功能完全取决于它所使用的 .NET Framework 版本。 .NET Framework 2.0 之前的任何版本均不受支持;更高版本需要使用特定映像,如后文所述。

使用第三方(非 Microsoft)框架的应用

一般来说,Microsoft 无法认证第三方框架或应用程序,或者支持它们在 Windows 容器或物理计算机和虚拟机上运行。 但是,Microsoft 确实会对多个第三方框架和工具(包括 Apache、Cassandra、Chocolatey、Datadog、Django、Flask、Git、Golang、JBoss、Jenkins、Rust、Nodejs、Pearl、Python、Ruby、Tomcat 等)进行内部可用性测试。

对于任何第三方框架或软件,请向提供它的供应商验证其在 Windows 容器上的可支持性。

最佳容器化候选项

现在我们已了解关于容器化应用的硬性限制,接下来可以更轻松地了解哪些类型的应用更适合于 Windows 容器。 下表显示了适合于 Windows 容器的最佳候选项,以及容器化它们的任何特殊注意事项。

应用程序类型 为什么这些是最佳候选项 特殊注意事项
控制台应用程序 不存在任何 GUI 限制,控制台应用非常适合用于容器。 根据应用程序的需求使用适当的基础容器映像。
Windows 服务 因为这些是不需要任何直接用户交互的后台进程 根据应用程序的需求使用适当的基础容器映像。 需要创建一个前台进程,以使任何容器化的后台进程保持运行。 请参阅下面关于“后台服务”的部分。
Windows Communication Foundation (WCF) 服务 因为它们是可同时在后台运行的面向服务的应用 根据应用程序的需求使用适当的基础容器映像。 可能需要创建一个前台进程,以使任何容器化的后台进程保持运行。 请参阅下面关于“后台服务”的部分。
Web 应用 Web 应用程序本质上是侦听特定端口的后台服务,因此非常适合进行容器化处理,因为它们可以利用容器提供的可伸缩性 根据应用程序的需求使用适当的基础容器映像。

注意:即使是这些最佳容器化候选项也可能依赖于 Windows 容器中需要以不同方式处理的核心 Windows 功能和组件。 下一节将更详细地介绍此类实际注意事项,以便更好地利用 Windows 容器的功能。

针对可容器化的应用程序的实际注意事项

应用更新项目通常会从应用的业务功能角度考虑是否可以对特定应用进行容器化处理。 但是业务功能并不是决定这在技术上是否可行的因素。 重要的是应用的体系结构,即它依赖的技术组件。 因此,很难回答“我是否可以容器化 HR 应用程序?”之类的问题,因为这不是关于应用程序正在执行的操作,而是如何(以及它使用哪些 Windows 组件/服务)产生影响。

这是一个重要的区别,因为如果应用程序不是一开始就使用微服务体系结构构建的,那么容器化可能会更加困难。 进行容器化时,某些功能可能需要特殊处理。 对一些功能进行特殊处理的原因可能是应用使用 Windows 容器不支持的核心 Windows 组件和框架。 对其他功能(如事件日志记录和监视)进行特殊处理可能是由于 Linux 和 Windows 之间存在固有差异,这些差异仅在容器化应用时才会显现出来。 还有其他功能(如计划任务和后台服务)必须从容器不是 VM 而是临时容器的角度进行理解,因此需要特殊处理。

下表简要概述了在考虑容器化时需要特别考虑的应用程序的组件/功能。 后面的子部分提供了更多详细信息,包括演示处理每个方案的技术的示例。 虽然下面的列表涵盖了 Windows 容器支持的方案,但这些方案仍然需要遵循上一章中的指南。 例如,虽然支持后台服务,但不支持在 .NET Framework 1.1 上运行后台服务。

需要特殊处理的 Windows 功能/组件 原因
Microsoft 消息队列 (MSMQ) MSMQ 很早以前源自容器,并非所有消息队列的部署模型都与容器体系结构兼容。
Microsoft 分布式事务协调器 (MSDTC) MSDTC 与容器之间的名称解析需要特别考虑。
IIS IIS 与在 VM 中相同,但在容器环境中运行 IIS 时,有一些重要注意事项,例如证书管理、数据库连接字符串等。
计划任务 Windows 容器可以运行计划任务,就像任何 Windows 实例一样。 但是,你可能需要运行前台任务来使容器实例保持运行。 根据应用程序,你可能需要考虑事件驱动方法。
后台服务 由于容器作为临时进程运行,因此你需要执行额外处理才能使容器保持运行
.NET Framework 和 .NET(以前称为 .Net Core) 请确保使用正确的映像以确保兼容性,如下面的子部分所述

其他支持的组件

需要特殊处理的组件 原因 替代方法
事件日志记录/监视 因为 Windows 写入事件和日志的方式在本质上不同于 Linux stdout 使用新的日志监视器工具规范化数据并从 Linux 和 Windows 中合并
Windows 容器安全性 虽然许多安全做法保持不变,但容器需要额外的安全措施 使用专用的注册表和映像扫描工具 - 稍后会进行详细介绍
Windows 容器备份 容器中不应包含数据或状态 备份容器使用的任何持久性存储以及容器映像

Windows 组件/功能

现在,让我们深入了解可以容器化但确实需要额外处理的应用程序和组件的详细信息。

MSMQ

如果应用程序依赖于 MSMQ,那么是否可以对它进行容器化取决于其 MSMQ 部署方案。 MSMQ 包含多个部署选项。 专用队列与公共队列、事务性或非事务性以及身份验证类型等因素构成了 MSMQ 最初旨在支持的方案矩阵。 并非所有这些内容都可以轻松移动到 Windows 容器。 下表列出了支持的方案:

范围 事务性? 队列位置 身份验证类型 发送和接收?
专用 同一容器(单个容器) 匿名
专用 永久性卷 匿名
专用 域控制器 匿名
专用 单个主机(两个容器) 匿名
公用 两个主机 匿名
公用 两个主机 匿名

经 Microsoft 的内部开发团队验证过的关于这些支持方案的一些注意事项:

  • 隔离模式:用于隔离的进程模式和 Hyper-V 模式都适用于上面列出的方案。
  • 最小 OS 和容器映像:建议用于 MSMQ 的最低 OS 版本是 Windows Server 2019。
  • 永久性卷:已通过在使用 Azure 文件进行持久性存储的 Azure Kubernetes 服务 (AKS) 上运行 MSMQ 验证了上述方案。

将这些注意事项与上表放在一起时,可以看到唯一不受支持的方案是需要使用 Active Directory 进行身份验证的队列。 目前不支持将 gMSA(组托管服务帐户)与 MSMQ 集成,因为 MSMQ 在 Active Directory 上拥有的依赖项尚不适用。

或者,使用 Azure 服务总线而不是 MSMQ。 Azure 服务总线是一个完全托管的企业消息代理,其中包含消息队列和发布订阅主题(在命名空间中)。 从 MSMQ 切换到 Azure 服务总线需要更改代码和重新构建应用程序体系结构,但这可使你灵活地迁移到现代平台。

MSDTC

在大型企业的 Windows 旧版应用程序中充分使用 Microsoft 分布式事务处理协调器 (MSDTC)。 MSDTC 可以安装在 Windows 容器上,但在某些情况下不起作用,也无法在 Windows 容器上重现。

  • 创建容器时,请确保将 --name 参数传递给 docker run 命令。 此名称参数允许容器通过 docker 网络进行通信。 如果使用 gMSA,该名称必须与主机名匹配,而主机名必须与 gMSA 帐户名匹配。
    • 下面是使用 gMSA 运行命令的示例:
docker run -d --security-opt "credentialspec=file://contoso_webapp01.json" --hostname webapp01 -- name webapp01 mcr.microsoft.com/windows/servercore:ltsc2022
  • 容器必须能够使用 NETBIOS 名称相互解析。 如果遇到任何困难,最好的解决方法是将容器的名称和 IP 添加到其他主机文件中。
  • 两个容器上 msdtc 的 uuid 必须是唯一的。 可通过在容器上的PowerShell中运行“”Get-Dtc 来找到 uuid。 如果它们不是唯一的,一种解决方法是将 MSDTC 卸载,并将其重新安装在其中一个容器上。 可使用以下 powershelll 命令:“uninstall-dtc”、“install-dtc”。
  • 目前,Azure Kubernetes 服务不支持 MSDTC。 如果有要在 AKS 上运行 MSDTC 的特定需要,请让 Windows 容器团队在 GitHub 上的 Windows 容器存储库中打开 am 问题。

IIS 在容器与 VM 中的工作原理

IIS 在 Windows 容器与 VM 中的工作方式相同。 但是,在容器环境中运行 IIS 实例时,有一些方面需要考虑:

  • 本地数据的持久性存储:对于可在 VM 中为 IIS 实例保留的内容,应用在其中写入/读取文件的文件夹是一个不错的示例。 使用容器时,你不希望将任何数据直接写入容器。 容器使用“暂存空间”进行本地存储,当同一应用程序中出现新容器时,它无法从之前的容器访问该区域。 因此,应对需要使 Web 应用程序可访问的数据使用持久性存储,以便任何容器实例都可以访问该存储。
  • 证书:尽管你可以在容器实例上拥有本地证书,但应该避免这样做,因为如果需要更新证书,则必须重新生成容器映像。 或者,可以使用具有入口控制的容器业务流程协调程序。 入口控制器可以应用网络策略,还可以处理托管在其后面的网站的证书管理。 好处是可以将证书生命周期管理与网站管理分隔开。
  • 数据库连接字符串:对于传统 IIS 部署,可以将 DB 连接字符串作为应用程序部署的一部分传递。 虽然 Windows 容器使你可以遵循该模型,但你可能需要考虑将 DB 连接字符串从容器分离到容器业务流程协调程序提供的集中式配置(应用程序可从中进行读取)。 这样,你就可以独立于应用程序管理和更新 DB 连接字符串。 如果 DB 发生更改(例如直接迁移到云的情况),你可以轻松更改连接字符串,而无需重新生成容器映像。 通过此方法,你还可以将机密(例如用于连接到 DB 的用户名和密码)保留在机密存储中。
  • 水平自动缩放:负载增加时,计算系统在尝试处理并发请求时往往会降低感知的性能。 通常有两种方法可以避免性能影响,即垂直或水平缩放。 垂直缩放会增加可用于现有计算实例的资源(更多 CPU、内存等)。 水平缩放会增加支持请求的实例数(更多的物理主机、VM 或容器)。 对于像 IIS 这样的 Web 层,水平缩放往往比垂直缩放更有效,但本地环境可能会遇到资源限制和负载均衡问题。 使用云环境时,水平缩放要容易得多,因为资源随时可用(需要额外的成本),并且云提供商通常在设计其负载均衡机制时会考虑水平缩放。 Windows 容器可以对 IIS 使用水平缩放,但容器的临时性质起着重要作用。 容器必须具有相同的配置,并且不存储任何状态或数据,以允许扩展或缩减支持 Web 应用程序的实例数。

计划任务

计划任务用于在 Windows 环境中随时调用程序、服务或脚本。 传统上,你始终有一个 Windows 实例处于启动并运行状态,并且在满足触发条件时会执行任务。 这可以通过 Windows 容器实现,除了需要通过 Azure PowerShell 配置和管理计划任务之外,它们的工作方式完全相同。

但是,使用微服务方法时,你有几个选项可用于避免让容器保持运行以等待触发器:

  • 使用事件驱动的 PaaS(平台即服务)(例如 Azure Function)来存储代码并为该应用定义触发器。 Azure Functions 甚至支持在满足触发条件时运行 Windows 容器映像。
  • 将 Windows 容器与容器业务流程协调程序结合使用。 仅当满足触发条件并从应用程序的其他部分调用触发器时,容器才能运行。 在这种情况下,容器业务流程协调程序将处理应用程序的计划和触发器。
  • 最后,使 Windows 容器保持运行,以运行计划任务。 你将需要一项前台服务(例如服务监视器)来使容器保持运行。

后台服务

尽管容器通常用于临时进程,但你仍可以容器化长时间运行的后台应用程序,前提是你创建了一个前台进程来启动它并使其保持运行。

一个很好的示例是 ServiceMonitor,这是一个 Windows 可执行文件,设计用于在容器中运行 IIS 时作为入口点进程。 尽管 ServiceMonitor 工具是为 IIS 构建的,但它提供了一个可用于监视其他服务的模型,并且存在一些限制。

有关 ServiceMonitor 的详细信息,请查看 Github 上的文档

.NET Framework 和 .NET

Windows 容器同时支持 .NET Framework 和 .NET(以前称为 .NET Core)。 .NET 团队在 Windows 基础容器映像的基础上为这两个框架创建了自己的官方映像。 选择适当的映像对于确保兼容性至关重要。 .NET 团队在服务器核心基础容器映像的基础上提供 .Net Framework 映像,并在服务器核心和 Nano Server 基础容器映像的基础上提供 .NET 映像。 服务器核心具有比 Nano Server 更大的 API 集,这提供了更高的兼容性,但也具有更大的映像大小。 Nano Server 的 API 表面极大减少,但映像大小要小得多。

在某些情况下,你可能需要基于 Windows 或服务器基础容器映像生成自己的 .NET Framework 或 .NET 映像。 如果应用程序不仅具有框架依赖项,而且具有 OS 依赖项,则可能需要这样做。 你将能够通过特定的基础容器映像来测试应用程序,以检测任何此类依赖项。

例如,服务器核心和 Nano Server 基础容器映像只有一种字体可用,以减小映像大小。 如果应用程序需要其他字体,那么你需要安装该字体或使用服务器或 Windows 映像,它们具有更大的 API 集并包含所有默认 Windows 字体。 从兼容性的角度来看,这允许对几乎任何应用(只要它们遵循容器的性质,例如无 GUI)进行容器化处理。 缺点是,它们的大小会大得多,这可能会影响性能。

验证要容器化的应用程序是否可在 Windows 容器上运行时,Microsoft 建议如下:

对于此框架 首先使用此容器映像进行测试 如果第一个容器映像不起作用,则回退到此容器映像 Base image
.NET Framework 版本 2.X 和 3.X .NET Framework 4.x .NET Framework 3.5 Windows Server 核心
.NET Framework 4.x 版本 .NET Framework 4.x 使用服务器或 Windows 映像生成 .NET Framework 容器映像 Windows Server 核心
.NET 6 或 7 分别对应 .NET 6 或 7 使用 Windows 或服务器基础映像生成 .NET 容器映像 Windows Nano Server 或服务器核心

其他支持的组件

下面的组件和主题提供关于随附项或更清楚地介绍 Windows 容器的项的其他指南。

事件日志记录

Windows 和 Linux 使用不同的方法来存储日志和事件并将其呈现给用户。 传统上,Windows 使用了 EVT 格式,可以在事件查看器中以结构化方式查看该格式。 相比之下,Linux 提供了一种简化的方法,其中包含其他工具(如 Docker)所依赖的标准输出 (stdout)。

Docker 始终有一种用于从 Linux 容器中提取日志的机制。 使用带有默认 stdout 配置的“docker logs”命令,Docker 可从容器中获取应用程序日志,而无需以交互方式打开容器。 但是,在启动日志监视器工具之前,同样的技术在 Windows 上不起作用。

日志监视器工具以 stdout 格式呈现 Windows 日志,因此其他工具(如 Docker)可以收集显示它所需的信息。 使用日志监视器的其他优势包括:

  • 能够筛选要在 stdout 上公开的事件/日志类型。 例如,仅当你对“信息”事件不感兴趣时,才能筛选应用程序日志中的“错误”和“警告”消息。
  • 从事件日志、自定义日志文件或 Windows 事件跟踪 (ETW) 中进行选择的功能。 如果应用程序在不同的日志源上写入,这特别有用。 一个很好的示例是位于“C:\inetpub”文件夹上的 IIS 日志。
  • 日志监视器使 Windows 容器的行为与 Linux 容器非常相似,因此查找 stdout 并与容器运行时交互的工具可按预期运行。 例如,如果从 Docker 切换到 ContainerD 作为容器运行时,则日志仍应通过(例如)“crictl logs”从容器主机可见。

有关日志监视器工具的详细信息,请参阅这篇博客文章

Windows 容器安全性

Windows 容器是在与物理计算机或虚拟机上运行的 Windows 实例相同的基础上构建的。 了解容器的实现方式(尤其是它们的共享内核性质)的具体信息有助于保护容器化的应用程序:

  • 共享组件。 Windows 容器出于安全目的共享部分主机组件。 这包括 Windows 防火墙、Windows Defender(防病毒)和其他资源访问限制。 无需直接在容器上配置这些组件,因为容器主机会根据容器工作负负载进行必要的调整。 例如,如果容器发出 Web 请求,容器主机将通过其防火墙转发必要的流量,以便容器可以访问 Web。
  • 隔离模式。 如前所述,Windows 容器可以在进程或 Hyper-V 隔离模式下部署,Hyper-V 可提供最安全的隔离。 在进程隔离中,容器与主机共享其内核、文件系统和注册表,从而支持提升的(管理)进程与容器进程和服务进行交互。 为应用程序选择正确的隔离模式对于确保适当的安全模型非常重要。
  • Windows 更新。 由于 Windows 容器上不存在服务堆栈,因此 Windows 容器不会像常规 Windows 实例那样接收更新。 你需要使用最新的可用基础容器映像重新生成 Windows 容器。 客户可以利用 DevOps 管道实现此目的。 Microsoft 每个月都会在星期二修补日之后更新其所有官方映像的基础容器映像。
  • 容器用户帐户。 默认情况下,Windows 容器中的应用程序在 ContainerAdmin 用户帐户下以提升的权限运行。 这有助于在容器映像中安装和配置必要的组件。 但是,在运行不需要提升的权限的应用程序时,你应考虑将用户帐户更改为 ContainerUser。 对于特定场景,你还可以创建具有适当权限的新帐户。
  • 映像和运行时扫描。 容器要求存储库和容器实例上的映像是安全的。 Microsoft 建议使用 Microsoft Defender for Containers 进行映像扫描和运行时扫描。 Defender for Containers 支持 Windows 容器,以便通过注册表扫描进行漏洞评估,并通过威胁检测保护运行时。

有关上述主题的详细信息,请参阅 Windows 容器文档页

Windows 容器备份

使用容器时,你需要以不同的方式看待备份。 如前所述,由于容器的临时性质,容器不应用于存储状态或数据。 如果将状态和数据与容器实例分开,那么备份问题就不在容器实例的运行时范围内,可以将该容器实例替换为一个新的容器实例(所有必要的持久性存储仍将对其可用)。

但是,仍有你要负责备份的组件;包括应用程序、容器映像和生成容器映像的 dockerfile。 其中大多数操作都由在其上运行生产和开发工作负载的平台进行处理。 采用 DevOps 方法时,请考虑最常见的情况:

  • 应用程序:应用程序可能驻留在 GitHub 或 Azure DevOps 等源存储库中。 这些存储库提供版本控制,使你能够还原到应用程序的特定版本。 如果你拥有源存储库,请确保遵循其备份和管理建议。
  • 容器映像:对于生产环境,容器映像应位于集中式映像存储库中,例如 Azure 容器注册表 (ACR)。 可以将容器映像推送到 ACR,以便其他主机可以拉取它。 ACR 处理容器映像的可用性并充当备份选项 - 但请记住,虽然 ACR 可处理映像的可用性时,但它不会阻止删除或覆盖映像。 对于任何其他本地映像存储库,请遵循供应商的建议备份现有注册表。
  • Dockerfile:Dockerfile 生成新的容器映像,通常与应用程序源一起存储。 由于 dockerfile 可能不是与应用程序一起创建的,尤其是当它是正在进行容器化的现有应用程序时,因此你要负责确保 dockerfile 存储在安全且已备份的位置。 你还应确保已备份应用程序在容器中运行所需的任何其他资产;例如:Kubernetes、Docker Swarm 和 Azure ARM 模板的 YAML 和 JSON 文件需遵循上述相同准则。

计划直接迁移过程

评估应用程序的容器化准备就绪情况后,请使用以下常规指南来计划该过程:

  1. 确定所需的 Windows 操作系统基础映像:Windows Server CoreNano ServerWindows服务器映像。
  2. 确定容器的隔离模式类型:在进程或 Hyper-V 隔离模式之间进行选择。 注意:目前,AKS 和 Azure Stack HCI 上的 AKS 仅支持进程隔离的容器。 在未来版本中,AKS 和 Azure Stack HCI 上的 AKS 还将支持 Hyper-V 隔离的容器。 有关详细信息,请参阅隔离模式
  3. 为应用程序选择合适的 Windows Server 版本以实现应用兼容性。 容器的最低 Windows Server 版本是 Windows Server 2016,但 Windows Server 2019 和 Windows Server 2022 是在 AKS 和 Azure Stack HCI 上的 AKS 上唯一受支持的容器主机操作系统。
  4. 确保公司的安全策略适用于容器环境。 这包括适应容器特定要求,例如注册表扫描和威胁检测。
  5. 考虑负载均衡需求。 容器本身不会移动;可以改为使用业务流程协调程序自动启动或停止群集节点上的容器,或者使用自动水平缩放来管理负载和可用性的更改。
  6. 考虑业务流程需求。 容器化后,应用程序可能需要通过 Kubernetes、AKS 或 Azure Stack HCI 上的 AKS 等工具进行自动化管理。 有关在工具之间进行选择的完整介绍和指南,请参阅 Windows 容器业务流程概述
  7. 将应用容器化。
  8. 将应用推送到映像存储库。 这将允许容器主机在任何环境中下载映像,包括开发、测试和生产环境。

Azure Migrate 可以提供一个用于发现、评估现有 Windows 应用程序并将其迁移到 Azure Kubernetes 服务的引导过程。 有关详细信息,请查看 Azure Migrate 文档页。