我被以下陈述误导了:“虚拟化(在您的情况下是 Docker)使用主机操作系统内核。”
出现了一个合理的问题:如何在基于Windows NT内核的主机操作系统上运行容器?那么运行容器是否依赖于 WSL(以及在这种情况下模拟的 Linux 内核)?例如,在Linux主机操作系统上运行时,是否会使用其内核?
就上下文而言,我试图定义容器化和模拟的“边界”。它们的区别(更多细节请参见上面的问题)。
我被以下陈述误导了:“虚拟化(在您的情况下是 Docker)使用主机操作系统内核。”
出现了一个合理的问题:如何在基于Windows NT内核的主机操作系统上运行容器?那么运行容器是否依赖于 WSL(以及在这种情况下模拟的 Linux 内核)?例如,在Linux主机操作系统上运行时,是否会使用其内核?
就上下文而言,我试图定义容器化和模拟的“边界”。它们的区别(更多细节请参见上面的问题)。
短的
Windows 容器在 Windows 内核上运行。
WSL 运行 Linux 容器。
在Linux上运行Linux容器时,将使用主机内核。
长的
Docker既不是虚拟化技术,也不是容器化技术,更不是仿真技术。这是一个中介,它配置 Linux 或 Windows 内核来创建一个隔离的环境,并在此环境中运行容器描述中指定的进程。而且,他并不是班上唯一的一个。 Linux 中至少有用于容器的 podman。
所有虚拟化,包括虚拟网络,都是由操作系统内核实现的。对于 Linux 来说,涉及以下子系统:
cgroups
- 隔离硬件资源(CPU、内存等)namespaces
- 创建独立的标识符集(挂载点、进程标识符、用户标识符等)启动docker容器时
如您所见,Linux 内核完成所有工作,而 Docker 仅负责协调。
现在谈论 Windows。
曾经有一段时间(大约八年前),人们希望微软能在 Windows 内核中添加与 Linux 兼容的容器化接口集。但微软走自己的路,创造了
据我了解,Docker Desktop是目前唯一一款微软公开其容器接口细节的容器管理器。我不知道 Windows 内核究竟是如何创建隔离环境的。但可以肯定的是,要运行 Windows 映像,您需要适用于 Windows 的 Docker。当尝试在 Linux 上下载镜像时,Docker 将崩溃并出现错误
Windows 上的 Docker 在虚拟机中运行 Linux 映像:
你看到虚拟机了吗
docker-desktop
?这是 Docker Engine 运行容器的地方。核心就在那里Windows 中的 Linux 内核未被模拟:https://github.com/microsoft/WSL2-Linux-Kernel它与常规 Linux 内核的主要区别在于,除了 x86-64 之外的所有硬件架构以及除了 MS 虚拟机设备所需的驱动程序之外的所有驱动程序都已被抛弃。
为了让生活变得更加困难,让我提醒你,有适用于 OSX 的 Docker。它还在 LinuxKit 虚拟机中使用 Linux 内核。
关于模拟
据我了解,“模拟内核”是指与 Linux 不兼容的操作系统内核公开一组 Linux 系统调用。比如应用程序调用一个函数
write
,库glibc
进行系统调用syscall_write
,内核拦截并按照Linux ABI解析其参数,按照自己的方式处理,然后按照Linux ABI再次返回结果。这就是 WSL 第一版的实现方式。没有 Linux 内核,但是 Windows 内核中有一层处理 Windows 内核中的 Linux 系统调用。但最终,微软放弃了对疯狂的 Linux 系统调用的支持,转而创建了一个单独的虚拟机,其中运行着功能齐全的 Linux 内核及其所有附加功能。
现在讨论虚拟机和仿真。虚拟机的定义是创建一个对于引导加载程序、内核和驱动程序等低级代码来说像“真实硬件”的环境。
在这种情况下,模拟器通常是在非特权模式下运行并解释二进制代码的程序。也许最著名的例子是 qemu。该程序查看二进制代码并使用主机平台的工具对其进行解释。有适用于 ARM、PowerPC、MIPS 和其他 amd64 平台代码的 qemu 版本。甚至还有专为运行 amd64 而设计的 amd64 上的 qemu - 这个模拟器可以预览二进制代码,如果发现系统调用或中断,则用服务例程调用替换它们。用于各类嵌入式系统的开发和调试。
但对于像Linux这样的大型操作系统,需要使用硬件进行虚拟化。这样的虚拟化系统被称为虚拟机管理程序。例如:KVM、Hyper-V。
虚拟机管理程序运行在比操作系统内核更深的特权级别上。具体来说,它们拦截中断和系统调用并决定将它们传递给哪个域进行处理。 WSL2 是基于 Hyper-V 虚拟机管理程序构建的。与模拟器不同,WSL2 不会修改可执行代码。当应用程序中发生系统调用时,它实际上发生在处理器上。只有处理程序不是在操作系统内核中调用,而是在虚拟机管理程序中调用。它根据一些内部考虑,猜测系统调用是在 Linux 应用程序中,并将该系统调用传递给 Linux 内核。或者它明白该调用是在 Windows 应用程序中进行的,并将其传递给 Windows 进行处理。
WSL2 知道 Hyper-V 管理程序的存在,在启动时,它会联系管理程序来配置虚拟机并设置中断和系统调用处理。
当然,虚拟机管理程序虚拟机中也有一定的模拟空间。但它们并不模拟中央处理器,而是模拟外围设备。例如,PCI 总线、网络设备和存储控制器/驱动器。主机使用的 CPU[1]
[1] 需要注意的是,在虚拟机管理程序中,你可以禁用客户机中的机器指令集的执行,例如矢量运算,但对于你的问题来说,这并不重要