5

尝试理解Linux容器进程与宿主机共享内核的具体含义 - 及时

 2 years ago
source link: https://www.cnblogs.com/AcAc-t/p/linux_container_share_kernel_meaning.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

尝试理解Linux容器进程与宿主机共享内核的具体含义

近期接触容器技术时,经常看到各类比较容器与虚拟机区别的文章中会提到:容器是共享宿主机的内核,而虚拟机则是拥有自己独立的内核,所以不可能在Linux上用容器运行windows,但是用虚拟机则可以。
乍看下去,觉得Linux上无法运行windows是很自然的结论,然后突然升起一个疑问:Linux上无法运行windows容器,那Debian上可以运行Ubuntu容器吗?Ubuntu上又能运行CentOS容器吗?
从自己实际使用上看,Debian上确实有运行CentOS的docker容器,CentOS上确实也有运行Ubuntu的docker容器,那无法运行windows容器却能运行不同发行版Linux的根本原因是什么呢?
进一步探究:具体发行版Debian 10.0 Linux上能运行低版本如Debian 9.0的容器吗?能运行Debian11.0的容器吗?为什么?
这些的问题的底层其实都指向共享内核的确切含义,这里记录一下思考过程,以下观点均为个人分析推断,不一定准确,有疑义的小伙伴欢迎指正、探讨。

容器与虚拟机的对比

已经有很多文章对容器、虚拟机的区别进行了详细的对比,这里不再赘述,很多文章对比时都会引用类似如下图片:

image

左图中是在Host OS上运行Hypervisor(虚拟机监控器,virtual machine monitor),在Hypervisor提供的硬件模拟基础上运行有有多个Guest OS,每个Guest OS均有自己的独立内核,相当于为GuestOS提供了一个完全模拟的虚拟裸机,GuestOS其实无感知自身是运行在物理机上还是虚拟硬件上。
而右图中container是作为一个普通进程运行于Host OS上,所有进程共享Host OS的内核,而container的运行、编排则由中间的docker engine实现。

内核究竟是什么

Linux内核

Linux® 内核是 Linux 操作系统(OS)的主要组件,也是计算机硬件与其进程之间的核心接口。它负责两者之间的通信,还要尽可能高效地管理资源。
之所以称为内核,是因为它在操作系统中就像果实硬壳中的种子一样,并且控制着硬件(无论是电话、笔记本电脑、服务器,还是任何其他类型的计算机)的所有主要功能,主要包括内存管理、进程管理、设备驱动程序、系统调用和安全防护,单纯的linux内核并不算我们传统意义上说的一个完整操作系统。

系统调用 && glibc

那么内核在整个系统中的具体作用到底是什么呢?
内核对上层屏蔽了底层硬件操作的细节,对其提供了统一的系统调用对硬件进行统一的操作。
但是系统调用接口一般比较原始,涉及和操作系统相关的细节,不同操作系统之间的系统调用基本完全不同,哪怕同系列的Linux与UNIX都不相同。
基于以上原因,一般应用程序是通过标准的运行库来使用系统调用,运行库的优点是本身是语言级别的,设计比较友好,标准、形式统一,不会随着操作系统或编译器的变化而变化。
Linux上的运行库即是glibc,其位于用户程序与系统调用之间,如下图:

image

Linux发行版与内核的关系

Linux发行版就是一些组织和厂商将Linux内核、各类软件、库及文档组合起来,提供了完整各类常用工具、库(如gcc、dpkg、yum、glibc等),打包在一起作为一个完整的发行版操作系统提供给用户,其关系如下图:

image

由于不同发行版使用的都是同一个Linux内核,所以在内核的层面并不存在兼容性问题--具体来说对于运行在宿主机上的容器进程分三种情况:

  1. 相同内核版本的情况下,不存在兼容性问题。
  2. 宿主机内核版本高于容器发行版内核版本时,由于高版本内核保证向后兼容性(backward compatibility),一般也可以正常运行。
  3. 宿主机内核版本低于容器发行版内核,若容器中使用了低版本内核中不存在的系统调用,则无法正常运行。

回到文章一开始提出的几个问题:
Linux上为什么无法运行windows容器?
因为Linux内核与windows内核完全不是一个东西,windows程序不可能使用Linux内核的系统调用与硬件交互。
Debian上可以运行Ubuntu容器吗?Ubuntu容器又能运行CentOS容器吗?
根据发行版使用的具体内核版本,其可以基于其宿主机内核运行成功则可以,由于linux内核提供向后兼容(backward compatible),一般来说容器发行版内核<=宿主机内核版本的情况都是可以成功的,而>宿主机内核的情况下可能可以成功。
具体发行版Debian 10.0 Linux上能运行低版本如Debian 9.0的容器吗?能运行Debian11.0的容器吗?为什么?
和上面其实是一个分析思路。

转载请注明出处,原文地址:https://www.cnblogs.com/AcAc-t/p/linux_container_share_kernel_meaning.html

https://zh.wikipedia.org/zh-cn/Hypervisor
https://cloudacademy.com/blog/docker-vs-virtual-machines-differences-you-should-know/
https://www.redhat.com/zh/topics/linux/what-is-the-linux-kernel
https://book.douban.com/subject/3652388/
https://www.cnblogs.com/blog-yejy/p/9373850.html
https://stackoverflow.com/questions/32756988/what-is-meant-by-shared-kernel-in-docker
https://stackoverflow.com/questions/32841982/how-can-docker-run-distros-with-different-kernels
https://en.wikipedia.org/wiki/Linux_distribution


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK