77

docker 如何在 Debian 主机上运行,​​或者在容器中运行 OpenSUSE?它使用不同的内核,具有独立的模块。旧的 Debian 版本也使用了旧的内核,那么如何在内核版本 3.10+ 上运行它?较旧的内核只有较旧的内置功能,旧发行版如何管理新功能?其中的“诀窍”是什么?

4

2 回答 2

90

Docker 从不使用不同的内核:内核始终是您的主机内核。

如果您的主机内核与您要运行的容器中的软件“足够兼容”,它将可以工作;否则不会。

“容器”只是流程配置

要理解的关键是 Docker 容器不是虚拟机:它不会创建运行软件的新虚拟计算机。相反,Docker 只是在你现有的操作系​​统中运行进程,就像你从命令行启动一个进程一样。

容器化进程与普通进程的区别在于对容器化进程的限制以及它如何看待周围环境的变化。(这些将传递给由容器化进程启动的任何子进程。)典型的限制和更改包括:

  • 不要使用主机的根文件系统,而是挂载一个不同的文件系统/(通常是容器镜像提供的一个)。主机文件系统的一部分可以挂载在新进程的根文件系统下,例如通过使用docker run -v /u/myprogram-data:/var/data/myprogram这样当容器化进程读取或写入主机文件系统中的/var/data/myprogram/file读取/写入时。/u/myprogram-data/file
  • 为容器化进程创建一个单独的进程空间,使其只能看到自己及其子进程(使用ps或类似命令),而看不到主机上运行的其他进程。
  • 创建一个单独的用户命名空间,使容器中的用户与主机中的用户不同:例如,容器化进程中的 UID 1234 与非容器化进程中的 UID 1234 不同
  • 使用自己的 IP 地址创建一组单独的网络接口,通常使用“虚拟路由器”并在这些网络接口和主机网络接口之间进行地址转换。(例如,当主机在端口 8080 上接收到数据包时,将其转发到容器进程的虚拟网络接口上的端口 80。)

所有这些都是由内核内置的设施完成的。如果您编写程序来进行适当的设置并在启动新进程时设置适当的参数,那么您可以在没有 Docker 的情况下自己完成任何事情。

兼容性

那么“足够兼容”是什么意思呢?这取决于程序对内核提出的请求(系统调用)以及它期望内核支持的功能。有些程序会发出会破坏事情的请求;其他人没有。例如,在 Ubuntu 18.04(内核 4.19)或类似主机上:

  • docker run centos:7 bash工作正常。
  • docker run centos:6 bash以退出代码 139 失败,这意味着它以分段违规信号终止;这是因为 4.19 内核不支持构建bash试图做的事情。
  • docker run centos:6 ls工作正常,因为它没有发出内核无法处理的请求bash

如果您尝试docker run centos:6 bash使用较旧的内核,例如 4.9 或更早版本,您会发现它可以正常工作。(至少就我测试而言。)

于 2019-06-14T23:49:06.003 回答
52

docker 如何在 Debian 主机上运行,​​也许是容器中的 OpenSUSE

因为内核是相同的,并且将支持 Docker 引擎运行所有这些容器镜像:主机内核应该是 3.10 或更高版本,但它的系统调用列表相当稳定。

请参阅“架构容器:为什么了解用户空间与内核空间很重要”:

  1. 应用程序包含业务逻辑,但依赖于系统调用。
  2. 一旦应用程序被编译,应用程序使用(即依赖)的一组系统调用被嵌入到二进制文件中(在高级语言中,这是解释器或 JVM)。
  3. 容器不会抽象出对用户空间和内核空间共享一组公共系统调用的需求。
  4. 在容器化的世界中,这个用户空间被捆绑并运送到不同的主机,从笔记本电脑到生产服务器。
  5. 未来几年,这将带来挑战。

https://rhelblog.files.wordpress.com/2015/07/user-space-vs-kernel-space-simple-container.png?w=584&h=231

不时添加新的系统调用,不推荐使用旧的系统调用;在考虑容器基础架构的生命周期以及将在其中运行的应用程序时,应该考虑这一点。

另请参阅“为什么内核版本与 Docker 容器中的 Ubuntu 版本不匹配? ”:

容器内没有内核。即使您安装了内核,容器启动时也不会加载它。容器的真正目的是在不需要运行新内核的情况下隔离进程。

于 2015-09-29T11:16:00.720 回答