docker 底层实现原理
容器的概念
容器本质就是一种沙盒技术,docker虚拟化
的核心是需要解决两个问题,就是 隔离和限制。
-
虚拟机是通过硬件虚拟化技术,通过一个
hypervisor
层实现对资源的彻底隔离 -
容器则是通过操作系统级别的虚拟化技术,利用
操作系统内核
的Cgroup
和Namespace
特性,此方法是完全通过软件的方式来实现的
相关概念
程序:存储在某种介质上的二进制代码
进程: 具有独立功能的程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位
容器:容器的本质,就是一个加了限定参数的进程,是一组与系统其余部分隔离的一个或多个进程
容器的实现,主要归根于三大技术:命名空间(NameSpce)、控制组(Control Groups)、文件联合系统(Union File System)
nameSpace 资源隔离
命名空间是全局资源的一种抽象,将不同的资源放在不同的命名空间里,各个命名空间之间是相互隔离的(感觉和编程语言中的命名空间,概念差不太多)。
不通内核,命名空间不同, 4.6
加入了 cgroup namespace
, 5.6
加入了time namespace
。学习 docker
和 k8s
建议使用较新的 linux 版本
查看内核的命令如下:
uname -a
使用 lsns
命令,查看当前机器上的命名空间
PID Namespace:
隔离进程 ID,每个 Namespace 内部的进程都有一个独立的 PID 空间,即使在不同的 Namespace 中,进程 ID 可能是相同的,但它们是完全不同的进程。
Mount Namespace:
隔离文件系统挂载点,每个 Namespace 都有自己独立的文件系统视图,一个 Namespace 中的挂载或卸载操作不会影响其他 Namespace。
CGroup 资源限制
通过 namespace
可以保证容器之间的隔离,但是无法控制每个容器占有多少资源。如果某个容器正在执行 CPU 密集型任务
,那么就会影响其他的容器中任务的性能与执行效率,导致多个容器相互影响并抢占资源。如何对多个容器资源的使用进行限制,就成了解决进程虚拟资源
Control Groups 简称(CGroups)就是能够隔离宿主机上的物理资源,如 CPU、内存、磁盘 IO 等,每个CGroup都是一组被相同的b标准和参数限制的进程。而我们需要做的就是把这个容器加入到指定的 CGroup中。
UnionFS 联合文件系统
docker
借助于 Linux
的 nameSpace 和 cGroup 分别解决了资源隔离和资源限制的问题,那么这个容器就是很轻量级的,
镜像的结构正如上图所示,是一层层的堆叠起来的,镜像中的这些层都是 只读层,当我们运行程序的时候,就是只要添加新的可写层即可(容器层)。对于运行中的容器所做的所有更改(比如写入新文件,修改现有文件,删除文件)都将写入这个容器层。
对于容器的操作,主要是使用了写时复制 (CoW) 技术。只有需要写时才去复制,Cow技术可以让所有的容器共享 image 文件系统。所有数据都从 image
中读取。只有对当前文件进行写操作时,才从 images 中把要写的文件复制到自己的文件系统进行更改。无论多少个容器都共享一个 images。
参考文献
https://study.163.com/course/courseLearn.htm?courseId=1212937804#/learn/video?
https://blog.csdn.net/wangguchao/article/details/109002488
https://blog.csdn.net/crazyjinks/article/details/133799471