docker - 像 Docker 这样的容器化软件是如何翻译 CPU 指令的?
问题描述
我最近遇到了一个错误,其中 python 库使用了某个 CPU 指令,该指令存在于一个 x86 处理器上但不存在于另一个上,导致程序在一个系统上意外崩溃(非法指令),但在另一个系统上却没有。这让我想到了容器化为我的软件创建定义良好的运行时环境的好处。但是当我意识到这是多么低级时,我的大脑就停了下来,我无法通过推理和互联网阅读来弄清楚像docker这样的软件隔离到什么级别。
问题
所以我的问题是:像 Docker 或 LXC 这样的容器化软件是否能够模拟物理硬件上不存在的指令?如果容器不能,完整的 VM 是否能够处理它?
轶事信息
以为我会填补空白,只是因为人们很好奇。
我遇到的具体情况是在尝试将 Reed-Solomon 擦除编码应用于数据对象时。我正在使用PyECLib库,它通过库实现 Vandermonde Reed-Solomon liberasurecode
(我相信它又使用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。在下面指定的处理器上运行 Fedora 25 的 LXC 容器中发生严重破坏的值得注意的情况,但我敢打赌 LXC 和 Fedora 与它几乎没有关系。
我已经尝试过 pyeclib 1.4 和 1.1,并且发生了同样的事情。
这些处理器使我的程序崩溃:
- 英特尔至强 X5660
- 英特尔至强 X3363
- 英特尔至强 E5405
- 英特尔至强 X3430
- 英特尔至强 E3110
以下是一些运行良好的处理器:
- 英特尔至强 E31220
- 英特尔酷睿 i7-7500U
解决方案
容器不翻译指令。在容器中运行的程序与在同一台机器上运行的任何其他程序完全相同,只是它具有某些事物的单独(“命名空间”)实例,例如文件系统、网络堆栈和系统主机名。CPU 没有被模拟或虚拟化(无论如何,比平常更多。)
虚拟机可以支持主机上不支持的指令,但它们不一定这样做。如果他们这样做,通常会在性能上付出巨大的代价。
推荐阅读
- javascript - nextjs 使用静态类名添加动态类名
- c# - 字典
尽管找到了预期值,但 ShouldContainKeyAndValue 未能通过单元测试 - enaml - 有没有办法将 qtawesome 与 enaml 一起使用?
- r - 如何使用 terra 包在 freq 函数的输出中添加图层名称?
- django - 在 django 中等待 HTTP 请求时轮询的更好选择?
- android - Android Studio 无法运行 Flutter 项目
- azure - 将自定义参数传递到 Azure 数据工厂中的存储过程
- javascript - 我可以在特定媒体查询中将 HTML DOM 转换为图像吗?
- python - 获取 Pandas Dataframe 中每列的最后一个值
- angular - ngx-editor 显示占位符,尽管它有一个值