适用于:Windows Server 2025、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不专门认证或支持在 Windows 容器上使用非Microsoft框架 | 请咨询特定框架或应用的供应商,了解 Windows 容器的支持策略。 有关详细信息,请参阅下文 |
让我们反过来考虑其中每个限制。
需要桌面的应用程序
容器非常适合从其他应用程序调用的临时函数,包括具有用户交互的函数。 但是,不能将其用于具有 GUI 本身的应用程序。 即使应用程序本身没有 GUI,但具有依赖于 GUI 的安装程序,也是如此。 通常,可以使用 PowerShell 调用 Windows Installer,但如果应用程序需要通过 GUI 进行安装,该要求将消除它作为容器化候选项。
这不是实现 Windows 容器的方式的问题,而是容器工作原理的基本概念。
如果应用需要 GUI API,则这一点不同。 即使这些 API 提供的 GUI 不是,也支持这些 API。 这在主题 Nano Server x Server Core x Server x Server - 哪个基础映像适合你中更充分地说明这一点?
使用 RDP 的应用程序
由于远程桌面协议(RDP)的整个用途是建立交互式可视会话,因此刚才所述的 GUI 限制也适用。 不能 as-is容器化使用 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 容器。 因此,不能在 Windows 容器上运行 Active Directory 域服务作为基础结构角色。 可以运行 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 实例一样。 但是,可能需要运行前台任务才能使容器实例保持运行。 根据应用程序,可能需要考虑事件驱动方法。 |
后台服务 | 由于容器作为临时进程运行,因此需要额外的处理来保持容器 runnin.g |
.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)上使用 Azure 文件对持久存储运行 MSMQ 进行了验证。
将这些注意事项与上表结合使用时,可以看到不支持的唯一方案是使用 Active Directory 进行身份验证的队列。 目前不支持将 gMSA(组托管服务帐户)与 MSMQ 集成,因为 MSMQ 依赖于尚未到位的 Active Directory。
或者,使用 Azure 服务总线而不是 MSMQ。 Azure 服务总线是一个完全托管的企业消息代理,其中包含消息队列和发布订阅主题(在命名空间中)。 从 MSMQ 切换到 Azure 服务总线需要代码更改和应用程序重新体系结构,但你可以灵活地迁移到新式平台。
MSDTC
Microsoft分布式事务处理协调器(MSDTC)在大型企业的 Windows 旧版应用程序中广泛使用。 MSDTC 可以安装在 Windows 容器上,但在某些情况下不起作用,并且无法在 Windows 容器上重现。
- 创建容器时,请务必将 --name 参数传入 docker run 命令。 此名称参数允许容器通过 docker 网络进行通信。 如果使用 gMSA,则名称必须与 gMSA 帐户名称匹配的主机名匹配。
- 下面是使用 gMSA 的 run 命令的示例:
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 的特定需求,请在 GitHub 上的 Windows 容器存储库 上打开 am 问题,让 Windows 容器团队知道。
IIS 在容器与 VM 中的工作原理
IIS 在 Windows 容器上的工作方式与 VM 中的相同。 但是,在容器环境中运行时,应考虑运行 IIS 实例的某些方面:
- 本地数据的持久存储:应用向其写入/读取文件的文件夹是 IIS 实例的 VM 中保留的一个很好的示例。 使用容器时,不希望将任何数据直接写入容器。 容器对本地存储使用“暂存空间”,当新容器用于同一应用程序时,它无法从以前的容器访问该区域。 因此,对 Web 应用程序需要访问的数据使用永久性存储,以便任何容器实例都可以访问该存储。
- 证书:尽管可以在容器实例上拥有本地证书,但可以避免这样做,因为如果需要更新证书,则必须重新生成容器映像。 或者,可以将容器业务流程协调程序与入口控件配合使用。 入口控制器可以应用网络策略,并处理托管在网络后面的网站的证书管理。 缺点是将证书生命周期管理与网站管理分离。
- 数据库连接字符串:对于传统的 IIS 部署,可以在应用程序部署过程中传递 DB 连接字符串。 虽然 Windows 容器允许你遵循该模型,但可能需要考虑将 DB 连接字符串从容器分离到容器业务流程协调程序提供的集中配置,应用程序可以从中读取该配置。 这样,就可以独立于应用程序管理和更新 DB 连接字符串。 如果 DB 发生更改(例如直接迁移到云的情况),则可以轻松地更改连接字符串,而无需重新生成容器映像。 此方法还允许在机密存储中保留机密(例如用于连接到 DB 的用户名和密码)。
- 水平自动缩放:负载增加时,计算系统在尝试处理同时请求时往往降低感知到的性能。 通常有两种方法可以避免性能影响,即垂直或水平缩放。 垂直缩放会增加现有计算实例可用的资源(更多 CPU、内存等)。 水平缩放会增加支持请求的实例数(更多的物理主机、VM 或容器)。 对于 IIS 等 Web 层,水平缩放往往比垂直更高效,但本地环境可能会遇到资源限制和负载均衡问题。 使用云环境时,水平缩放要容易得多,因为资源随时可用(需要额外的成本),云提供商通常会设计其负载均衡机制,同时考虑到水平缩放。 Windows 容器可以利用 IIS 的水平缩放,但容器的临时方面起着重要作用。 容器必须具有相同的配置,并且没有存储任何状态或数据,以允许纵向扩展或减少支持 Web 应用程序的实例数。
计划任务
计划的任务用于在 Windows 环境中随时调用程序、服务或脚本。 传统上,你随时都有一个 Windows 实例启动并运行,并且满足触发器时,将执行该任务。 这可以通过 Windows 容器实现,除了需要通过 Azure PowerShell 配置和管理计划任务之外,它们的工作方式完全相同。
但是,使用微服务方法,可以使用一些选项来避免让容器保持运行以等待触发器:
- 使用事件驱动的 PaaS(平台即服务)(例如 Azure 函数)来存储代码,并为该应用定义触发器。 Azure Functions 甚至支持满足触发器时要运行的 Windows 容器映像。
- 将 Windows 容器与容器业务流程协调程序结合使用。 仅当满足触发器并从应用程序的其他部分调用时,容器才能运行。 在这种情况下,容器业务流程协调程序将处理应用程序的计划和触发器。
- 最后,使 Windows 容器保持运行,以运行计划任务。 需要一个前台服务(如服务监视器),使容器保持运行。
后台服务
尽管容器通常适用于临时进程,但你可以容器化后台长时间运行的应用程序,前提是你创建了一个前台进程来启动它并使其保持运行。
一个很好的示例是 ServiceMonitor,它是一个 Windows 可执行文件,旨在用作在容器中运行 IIS 时的入口点进程。 尽管它是针对 IIS 构建的,但 ServiceMonitor 工具提供了一个模型,可用于监视其他服务,但存在一些限制。
有关 ServiceMonitor 的详细信息,请查看 Github 上的文档。
.NET Framework 和 .NET
Windows 容器同时支持 .NET Framework 和 .NET(以前为 .NET Core)。 .NET 团队为 Windows 基础容器映像之上的两个框架创建自己的官方映像。 选择适当的映像对于确保兼容性至关重要。 .NET 团队在服务器核心基础容器映像和 .NET 映像的基础上提供 .Net Framework 映像,以及服务器核心和 Nano Server 基础容器映像之上的 .NET 映像。 服务器核心的 API 集比 Nano Server 大,因此可实现更高的兼容性,但也允许更大的图像大小。 Nano Server 的 API 表面严重减少,但图像大小要小得多。
在某些情况下,可能需要在 Windows 或服务器基础容器映像的基础上生成自己的 .NET Framework 或 .NET 映像。 如果应用程序不仅具有框架依赖项,而且具有 OS 依赖项,则可能是必需的。 可以通过使用特定的基础容器映像测试应用程序来检测任何此类依赖项。
例如,服务器核心和 Nano Server 基本容器映像只有一个字体可用,以减少图像大小。 如果应用程序需要其他字体,则必须 安装该字体 或使用服务器或 Windows 映像,该映像集更大,并包含所有默认 Windows 字体。 从兼容性的角度来看,这几乎允许任何应用(只要它们尊重容器的性质(如 no-GUI)进行容器化。 缺点是,它们的大小会大得多,这可能会影响性能。
验证要容器化的应用程序是否适用于 Windows 容器时,Microsoft建议执行以下作:
对于此框架 | 首先使用此容器映像进行测试 | 如果第一个容器映像不起作用,请回退到此容器映像 | 基础映像 |
---|---|---|---|
.NET Framework 版本 2.X 和 3.X | .NET Framework 4.x | .NET Framework 3.5 | Windows Server Core |
.NET Framework 4.x 版本 | .NET Framework 4.x | 使用服务器或 Windows 映像生成 .NET Framework 容器映像 | Windows Server Core |
.NET 6 或 7 | .NET 6 或 7 分别 | 使用 Windows 或 Server 基础映像生成 .NET 容器映像 | Windows Nano Server 或 Server Core |
其他支持组件
下面的组件和主题为与 Windows 容器一起提供的其他指导,或者为 Windows 容器提供更清晰的项目。
事件日志记录
Windows 和 Linux 使用不同的方法来存储日志和事件并将其呈现给用户。 传统上,Windows 使用 EVT 格式,可以在事件查看器中以结构化方式查看。 相比之下,Linux 通过标准输出(stdout)提供了一种简化的方法,其他工具(如 Docker)所依赖。
Docker 始终有一种从 Linux 容器中提取日志的机制。 将“docker logs”命令与默认 stdout 配置结合使用,Docker 会将应用程序日志从容器中带出,而无需以交互方式打开容器。 但是,在启动日志监视器工具之前,相同的技术在 Windows 上不起作用。
日志监视器工具以 stdout 格式显示 Windows 日志,以便其他工具(如 Docker)可以收集显示它所需的信息。 使用日志监视器的其他好处包括:
- 能够筛选要在 stdout 上公开的事件/日志类型。 例如,仅当对“信息”事件不感兴趣时,才能筛选应用程序日志中的“错误”和“警告”消息。
- 从事件日志、自定义日志文件或 Windows 事件跟踪(ETW)中进行选择的功能。 如果应用程序在不同的日志源上写入,这尤其有用。 例如,IIS 日志位于“C:\inetpub”文件夹中。
- Log Monitor 使 Windows 容器的行为非常类似于 Linux 容器,因此查找 stdout 并按预期与容器运行时函数交互的工具。 例如,如果将 Docker 移动到 ContainerD 作为容器运行时,则日志仍应通过“crictl logs”从容器主机可见。
可以 在此博客文章中详细了解日志监视器工具。
Windows 容器安全性
Windows 容器是在与物理计算机或虚拟机上运行的 Windows 实例相同的基础上构建的。 了解容器实现方式(尤其是其共享内核性质)的具体信息有助于保护容器化应用程序:
- 共享组件。 Windows 容器出于安全目的共享部分主机组件。 这包括 Windows 防火墙、Windows Defender(防病毒)和其他资源访问限制。 无需直接在容器上配置这些组件,因为容器主机会根据容器工作负荷进行必要的调整。 例如,如果容器发出 Web 请求,容器主机将通过其防火墙转发必要的流量,以便容器可以访问 Web。
- 隔离模式。 如前所述,可以在进程或 Hyper-V 隔离模式下部署 Windows 容器,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:Dockerfiles 生成新的容器映像,通常与应用程序源一起存储。 由于 dockerfile 可能尚未使用应用程序创建,尤其是如果它是正在容器化的现有应用程序,因此你负责确保 dockerfile 存储在安全且已备份的位置。 还应确保备份应用程序在容器中工作所需的任何其他资产;例如:Kubernetes、Docker Swarm 和 Azure ARM 模板的 YAML 和 JSON 文件遵循与上述相同的准则。
规划直接迁移过程
评估应用程序的容器化准备情况后,请使用以下常规指南来规划该过程:
- 确定所需的 Windows作系统基础映像: Windows Server Core、 Nano Server、 Windows 或 Server 映像。
- 确定容器的隔离模式类型:在进程或 Hyper-V 隔离模式之间进行选择。 注意:目前,Azure Stack HCI 上的 AKS 和 AKS 仅支持进程隔离的容器。 在将来的版本中,Azure Stack HCI 上的 AKS 和 AKS 也将支持 Hyper-V 隔离的容器。 有关详细信息,请参阅 隔离模式。
- 为应用程序选择正确的 Windows Server 版本,以便实现应用兼容性。 容器的最低 Windows Server 版本是 Windows Server 2016,但 Windows Server 2019 和 Windows Server 2022 是唯一在 AKS 和 Azure Stack HCI 上的 AKS 上支持的容器主机作系统。
- 确保公司的安全策略适用于容器环境。 这包括适应容器特定的要求,例如注册表扫描和威胁检测。
- 考虑负载均衡需求。 容器本身不会移动;可以改用业务流程协调程序来自动启动或停止群集节点上的容器,或者使用自动水平缩放管理负载和可用性的更改。
- 考虑业务流程需求。 容器化后,应用程序可能需要通过 Azure Stack HCI 上的 Kubernetes、AKS 或 AKS 等工具实现自动化管理。 有关在工具之间进行选择的完整讨论和指南,请参阅 Windows 容器业务流程概述 。
- 容器化应用。
- 将应用推送到映像存储库。 这将允许容器主机在任何环境中下载映像,包括开发、测试和生产。
Azure Migrate 可以提供发现、评估和将现有 Windows 应用程序迁移到 Azure Kubernetes 服务的引导式过程。 有关详细信息,请查看 Azure Migrate 文档页。