Docker 等容器化软件如何翻译 CPU 指令?
How does containerization software like Docker translate CPU instructions?
我最近 运行 遇到了一个错误,其中 python 库使用了特定的 CPU 指令,该指令存在于一个 x86 处理器上但不存在于另一个处理器上,导致意外崩溃一个系统上的程序(非法指令)在另一个系统上却没有。这让我想到了容器化为我的软件创建定义明确的 运行 时间环境的好处。但是当我意识到这是多么低级时,我的大脑就停止了,我无法通过推理或在互联网上阅读来弄清楚像docker这样的软件的隔离级别是什么。
问题
所以我的问题是:像Docker或LXC这样的容器化软件是否能够模拟物理硬件上不存在的指令?并且如果容器不能,完整的 VM 是否能够处理它?
轶事信息
以为我会填补空白,只是因为人们很好奇。
我遇到的具体情况是在尝试将 Reed-Solomon 擦除编码应用于数据对象时。我相信我正在使用 PyECLib library which implements Vandermonde Reed-Solomon via the liberasurecode
library (which in turn uses jerasure。
最小工作示例
这段代码 运行 在兼容处理器上没有错误,但在一些较旧的处理器上会产生 Illegal instruction
异常:
from pyeclib.ec_iface import ECDriver
ec_driver = ECDriver(k=1, m=5, ec_type='liberasurecode_rs_vand')
ec_driver.encode(b'foo')
环境
我在多个 Linux 平台上使用 Python 3.6。造成严重破坏的值得注意的情况是在下面指定的处理器上的 LXC 容器 运行ning Fedora 25 中,但我敢打赌 LXC 和 Fedora 与它关系不大。
我已经尝试了 pyeclib 1.4 和 1.1,并且发生了同样的事情。
这些处理器使我的程序崩溃:
- 英特尔至强 X5660
- 英特尔至强 X3363
- 英特尔至强 E5405
- 英特尔至强 X3430
- 英特尔至强 E3110
以下是一些运行良好的处理器:
- 英特尔至强 E31220
- 英特尔酷睿 i7-7500U
容器不翻译指令。容器中的程序 运行 与同一台机器上的任何其他程序 运行 完全相同,除了它具有某些事物的单独 ("namespaced") 实例,例如文件系统,网络堆栈和系统主机名。 CPU 未被模拟或虚拟化(无论如何都比平常多。)
虚拟机可以支持主机不支持的指令,但它们不一定这样做。如果他们这样做,通常会以性能为代价。
实际的答案是不,目前没有任何产品能够做到这一点。
好奇并不奇怪。事实上,就在不久前,ARM 处理器甚至在没有 VM 的情况下也支持这一功能。在 ARM 上,浮点数曾经是可选的,但在没有 FP 的处理器上,可以可靠地捕获 "invalid opertion" 异常。如果您链接了一个 FP 仿真库,那么它可以接管并从异常中恢复。
更现代的方法是使用备用代码路径。只需编译将从非通用指令中受益的每个函数的两个版本。在运行时,检查可用的 CPU,并以此来决定使用哪一组函数。一种变体是将这些函数打包在两个 DLL/.so 中,并根据 CPU.
加载两者之一
我最近 运行 遇到了一个错误,其中 python 库使用了特定的 CPU 指令,该指令存在于一个 x86 处理器上但不存在于另一个处理器上,导致意外崩溃一个系统上的程序(非法指令)在另一个系统上却没有。这让我想到了容器化为我的软件创建定义明确的 运行 时间环境的好处。但是当我意识到这是多么低级时,我的大脑就停止了,我无法通过推理或在互联网上阅读来弄清楚像docker这样的软件的隔离级别是什么。
问题
所以我的问题是:像Docker或LXC这样的容器化软件是否能够模拟物理硬件上不存在的指令?并且如果容器不能,完整的 VM 是否能够处理它?
轶事信息
以为我会填补空白,只是因为人们很好奇。
我遇到的具体情况是在尝试将 Reed-Solomon 擦除编码应用于数据对象时。我相信我正在使用 PyECLib library which implements Vandermonde Reed-Solomon via the liberasurecode
library (which in turn uses jerasure。
最小工作示例
这段代码 运行 在兼容处理器上没有错误,但在一些较旧的处理器上会产生 Illegal instruction
异常:
from pyeclib.ec_iface import ECDriver
ec_driver = ECDriver(k=1, m=5, ec_type='liberasurecode_rs_vand')
ec_driver.encode(b'foo')
环境
我在多个 Linux 平台上使用 Python 3.6。造成严重破坏的值得注意的情况是在下面指定的处理器上的 LXC 容器 运行ning Fedora 25 中,但我敢打赌 LXC 和 Fedora 与它关系不大。
我已经尝试了 pyeclib 1.4 和 1.1,并且发生了同样的事情。
这些处理器使我的程序崩溃:
- 英特尔至强 X5660
- 英特尔至强 X3363
- 英特尔至强 E5405
- 英特尔至强 X3430
- 英特尔至强 E3110
以下是一些运行良好的处理器:
- 英特尔至强 E31220
- 英特尔酷睿 i7-7500U
容器不翻译指令。容器中的程序 运行 与同一台机器上的任何其他程序 运行 完全相同,除了它具有某些事物的单独 ("namespaced") 实例,例如文件系统,网络堆栈和系统主机名。 CPU 未被模拟或虚拟化(无论如何都比平常多。)
虚拟机可以支持主机不支持的指令,但它们不一定这样做。如果他们这样做,通常会以性能为代价。
实际的答案是不,目前没有任何产品能够做到这一点。
好奇并不奇怪。事实上,就在不久前,ARM 处理器甚至在没有 VM 的情况下也支持这一功能。在 ARM 上,浮点数曾经是可选的,但在没有 FP 的处理器上,可以可靠地捕获 "invalid opertion" 异常。如果您链接了一个 FP 仿真库,那么它可以接管并从异常中恢复。
更现代的方法是使用备用代码路径。只需编译将从非通用指令中受益的每个函数的两个版本。在运行时,检查可用的 CPU,并以此来决定使用哪一组函数。一种变体是将这些函数打包在两个 DLL/.so 中,并根据 CPU.
加载两者之一