RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1606486
Accepted
Yulia
Yulia
Asked:2025-02-08 23:40:57 +0000 UTC2025-02-08 23:40:57 +0000 UTC 2025-02-08 23:40:57 +0000 UTC

Docker、虚拟化和使用操作系统内核?

  • 772

我被以下陈述误导了:“虚拟化(在您的情况下是 Docker)使用主机操作系统内核。”

出现了一个合理的问题:如何在基于Windows NT内核的主机操作系统上运行容器?那么运行容器是否依赖于 WSL(以及在这种情况下模拟的 Linux 内核)?例如,在Linux主机操作系统上运行时,是否会使用其内核?

就上下文而言,我试图定义容器化和模拟的“边界”。它们的区别(更多细节请参见上面的问题)。

linux
  • 1 1 个回答
  • 46 Views

1 个回答

  • Voted
  1. Best Answer
    Pak Uula
    2025-02-10T16:46:58Z2025-02-10T16:46:58Z

    短的

    那么如何在基于 Windows NT 内核的主机操作系统上运行容器呢?

    Windows 容器在 Windows 内核上运行。

    那么运行容器是否依赖于 WSL(以及在这种情况下模拟的 Linux 内核)?

    WSL 运行 Linux 容器。

    例如,如果我在 Linux 主机操作系统上运行它,它的内核会被使用吗?

    在Linux上运行Linux容器时,将使用主机内核。

    长的

    Docker既不是虚拟化技术,也不是容器化技术,更不是仿真技术。这是一个中介,它配置 Linux 或 Windows 内核来创建一个隔离的环境,并在此环境中运行容器描述中指定的进程。而且,他并不是班上唯一的一个。 Linux 中至少有用于容器的 podman。

    所有虚拟化,包括虚拟网络,都是由操作系统内核实现的。对于 Linux 来说,涉及以下子系统:

    • cgroups- 隔离硬件资源(CPU、内存等)
    • namespaces- 创建独立的标识符集(挂载点、进程标识符、用户标识符等)
    • union FS——几个文件系统的重叠联合:如果“上层”中缺少某个文件,则内核会在下一层中递归搜索。
    • iptables——在虚拟和真实网络接口之间创建传输。

    启动docker容器时

    • 创建一个操作系统容器(cgroups + namespace),
    • 将镜像中的层挂载到创建的容器中,
    • 在 OS 容器中创建网络设备并配置 iptables,
    • 在容器中启动进程。

    如您所见,Linux 内核完成所有工作,而 Docker 仅负责协调。

    现在谈论 Windows。

    曾经有一段时间(大约八年前),人们希望微软能在 Windows 内核中添加与 Linux 兼容的容器化接口集。但微软走自己的路,创造了

    • Windows 容器化接口:这些接口允许您运行Windows 容器
    • 一个虚拟机,在其中运行 Linux 内核。与此同时,他们对内核本身进行了重大的改造——大约十年前,微软的人是 Linux 内核最活跃的贡献者,为他们的虚拟机锯切和打磨内核。

    据我了解,Docker Desktop是目前唯一一款微软公开其容器接口细节的容器管理器。我不知道 Windows 内核究竟是如何创建隔离环境的。但可以肯定的是,要运行 Windows 映像,您需要适用于 Windows 的 Docker。当尝试在 Linux 上下载镜像时,Docker 将崩溃并出现错误

    $ docker pull mcr.microsoft.com/windows/nanoserver:ltsc2025
    ltsc2025: Pulling from windows/nanoserver
    no matching manifest for linux/amd64 in the manifest list entries
    

    Windows 上的 Docker 在虚拟机中运行 Linux 映像:

    PS> wsl --list
    Windows Subsystem for Linux Distributions:
    Ubuntu (Default)
    docker-desktop
    

    你看到虚拟机了吗docker-desktop?这是 Docker Engine 运行容器的地方。核心就在那里

    PS> docker run --rm alpine uname -a
    Linux caefb4cc2fda 5.15.167.4-microsoft-standard-WSL2 #1 SMP Tue Nov 5 00:21:55 UTC 2024 x86_64 Linux
    

    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] 需要注意的是,在虚拟机管理程序中,你可以禁用客户机中的机器指令集的执行,例如矢量运算,但对于你的问题来说,这并不重要

    • 2

相关问题

  • 如果 fuser -k number/tcp 没有帮助,如何在 Debian 中释放端口?

  • Ubuntu。startx 不起作用。黑屏

  • --syn 在 iptables 中有什么作用?

  • 为什么需要iso格式?

  • C程序中没有密码的sudo

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5