Docker如何运行不同内核的发行版?

pla*_*irt 45 linux-kernel linux-distro docker

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

Von*_*onC 39

如何在Debian主机上运行docker可能是容器中的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版本不匹配? ":

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

  • 我认为以上内容并未完全回答问题。虽然我完全同意引用的链接可以很好地解释为什么容器不生成自己的内核,但我们实际上可能希望生成可能依赖于特定内核版本的容器。我认为docker即使在Linux主机上运行时也可以采用一种模式,可以选择内核版本。 (2认同)
  • 该图是不正确且具有误导性的:“容器”部分根本不在用户空间中。容器配置改变了_内核_响应系统调用的方式,例如,如果您`open("/etc/passwd", O_RDONLY)`,实际上打开了内核已知的许多文件中的哪一个?从用户空间的角度来看,该进程与“非容器化”进程没有什么不同。 (2认同)

Cur*_*son 16

Docker从不使用其他内核:内核始终是您的宿主内核。

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

“容器”只是过程配置

要了解的关键是,Docker容器不是虚拟机:它不会创建新的虚拟机来运行该软件。取而代之的是,Docker只是在您现有的OS中运行进程,就像您从命令行启动进程一样。

容器化过程与普通过程之间的区别在于对容器化过程的限制以及对容器化过程的看法的变化。(这些将传递给由容器化进程启动的任何子进程。)典型的限制和更改包括:

  • 而不是使用主机的根文件系统,而是在其上挂载不同的文件系统/(通常是随容器映像提供的文件系统)。主机文件系统的某些部分可以安装在新进程的根文件系统下,例如通过使用,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或更早版本),则会发现它可以正常工作。(至少就我测试而言。)

  • 很好的解释。为我澄清了有关Docker工作原理的许多事情。 (4认同)
  • 这是一个很好的答案!回答了我很多关于 docker 的问题。 (2认同)
  • 我最近听到一个说法很好地总结了这一点:“Docker 只是一堆 Linux 内核。” 参考命名空间、cgroup ... (2认同)