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

时间:2015-09-29 10:49:21

标签: linux-kernel docker linux-distro

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

2 个答案:

答案 0 :(得分:31)

  

如何在Debian主机上运行docker可能是容器中的OpenSUSE

因为内核是相同的并且将支持Docker引擎运行所有这些容器映像:主机内核应该是3.10或更多,但它的list of system calls相当稳定。

请参阅" Architecting Containers: Why Understanding User Space vs. Kernel Space Matters":

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

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

  

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

另见" Why kernel version doesn't match Ubuntu version in a Docker container?":

  

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

答案 1 :(得分:6)

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那样发出内核无法处理的请求。

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