隔离模式

适用于:Windows Server 2025、Windows Server 2022、Windows Server 2019、Windows Server 2016

Windows 容器提供两种不同的运行时隔离模式:processHyper-V 隔离。 在两种隔离模式下运行的容器创建、管理和运行方式相同。 它们还会生成和使用相同的容器映像。 隔离模式之间的区别在于容器、主机操作系统和在该主机上运行的其他所有容器之间的隔离程度。

进程隔离

这是容器的“传统”隔离模式,Windows 容器概述中所述。 进程隔离技术允许多个容器实例在给定的主机上并发运行,隔离通过命名空间、资源控制和其他进程隔离技术来实现。 在此模式下运行时,容器与主机及彼此共享同一个内核。 这与 Linux 容器的运行方式大致相同。

显示一个容器,其中包含与 OS 和硬件隔离的应用程序。

隔离内容

Windows 容器虚拟化对各种操作系统命名空间的访问。 命名空间通过名称提供对信息、对象或资源的访问权限。 例如,文件系统可能是最知名的命名空间。 在 Windows 上,有许多命名空间是根据每个容器单独隔离的。

  • 文件系统
  • 注册表
  • 网络端口
  • 进程和线程 ID 空间
  • 对象管理器命名空间

刺穿隔离边界

在某些情况下,可以刺穿隔离边界。 这些操作必须由用户故意请求,应仔细考虑,因为它可能会损害容器的安全状况。 Windows 容器支持以下各项:

Windows 容器当前不支持:

  • 共享内存
  • 共享同步对象(信号灯、互斥等)
  • 共享进程命名空间

Hyper-V 隔离

此隔离模式提供了主机和容器版本之间的增强安全性和更广泛的兼容性。 通过 Hyper-V 隔离,多个容器实例在主机上并发运行;但是,每个容器在高度优化的虚拟机内部运行,并有效地获取其自己的内核。 虚拟机的存在提供每个容器和容器主机之间的硬件级隔离。

描述容器如何在虚拟机(而这个虚拟机又运行在物理计算机的操作系统上)中的操作系统内被隔离的示意图。

隔离示例

创建容器

使用 Docker 管理 Hyper-V 隔离的容器与管理进程隔离的容器几乎完全相同。 若要使用 Docker 创建具有 Hyper-V 隔离的容器,请使用 --isolation 参数设置 --isolation=hyperv

docker run -it --isolation=hyperv mcr.microsoft.com/windows/servercore:ltsc2019 cmd

若要通过 Docker 创建进程隔离的容器,请使用 --isolation 参数设置 --isolation=process

docker run -it --isolation=process mcr.microsoft.com/windows/servercore:ltsc2019 cmd

在 Windows Server 上运行的 Windows 容器默认为进程隔离运行。 在 Windows 10 专业版和企业版上运行的 Windows 容器默认为 Hyper-V 隔离运行。 从 Windows 10 2018 年 10 月更新开始,运行 Windows 10 专业版或企业版主机的用户可以运行进程隔离的 Windows 容器。 用户必须使用 --isolation=process 标志直接请求进程隔离。

警告

在 Windows 10 专业版和企业版上运行进程隔离是为了进行开发/测试。 主机必须运行 Windows 10 内部版本 17763+,并且必须安装 Docker 引擎版本 18.09 或更高。

应继续使用 Windows Server 作为生产部署的主机。 通过在 Windows 10 专业版和企业版上使用此功能,还必须确保主机和容器版本标记匹配,否则容器可能无法启动或表现出未定义的行为。

隔离说明

此示例演示了进程与 Hyper-V 隔离之间的隔离功能差异。

在这里,正在部署进程隔离的容器,并将托管长时间运行的 ping 进程。

docker run -d mcr.microsoft.com/windows/servercore:ltsc2019 ping localhost -t

使用 docker top 命令时,将返回如容器内所示的 ping 进程。 此示例中的过程 ID 为 3964。

docker top 1f8bf89026c8f66921a55e773bac1c60174bb6bab52ef427c6c8dbc8698f9d7a

3964 ping

在容器主机上,可以使用 get-process 命令从主机返回任何正在运行的 ping 进程。 在此示例中,有一个进程 ID 与容器的进程 ID 相匹配。 从容器和主机看去,过程是相同的。

get-process -Name ping

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id  SI ProcessName
-------  ------    -----      ----- -----   ------     --  -- -----------
     67       5      820       3836 ...71     0.03   3964   3 PING

与此相反,此示例还使用 ping 进程启动 Hyper-V 隔离容器。

docker run -d --isolation=hyperv mcr.microsoft.com/windows/servercore:ltsc2019 ping localhost -t

同样,可以使用 docker top 从容器返回正在运行的进程。

docker top 5d5611e38b31a41879d37a94468a1e11dc1086dcd009e2640d36023aa1663e62

1732 ping

但是,在容器主机上搜索进程时,找不到 ping 进程,并引发错误。

get-process -Name ping

get-process : Cannot find a process with the name "ping". Verify the process name and call the cmdlet again.
At line:1 char:1
+ get-process -Name ping
+ ~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (ping:String) [Get-Process], ProcessCommandException
    + FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShell.Commands.GetProcessCommand

最后,在主机上,vmwp 进程可见,这是正在运行的虚拟机,它封装正在运行的容器,并保护正在运行的进程免受主机操作系统的影响。

get-process -Name vmwp

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id  SI ProcessName
-------  ------    -----      ----- -----   ------     --  -- -----------
   1737      15    39452      19620 ...61     5.55   2376   0 vmwp