01 前言
在之前,写过了一篇《漫谈容器化技术》,主要就是讲解了容器化技术的由来、发展以及技术,有兴趣的童鞋可以参阅下:https://yanglinwei.blog.csdn.net/article/details/121761856
大家都知道docker
是容器化技术的一个工具,而且是很多容器化技术的基础,其地位在十分重要,本文来详细讲解docker
的原理。
02 docker简介
在docker的官网,可以看到是这样描述docker
的:
Developers Love Docker. Businesses Trust It. Build safer, share wider, run faster:
翻译为:
Docker最受开发人员的喜爱。 企业信任它。 Docker构建更安全,共享更广泛,运行更快
docker
是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux
或Windows
操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。
特点:开源、虚拟化、沙箱隔离机制。
03 docker原理
在《漫谈容器化技术》已经描述了虚拟化与容器化的区别,整体如下:
特性 | 虚拟机 | 容器 |
隔离级别 | 操作系统级 | 进程级别 |
隔离策略 | Hypervisor | CGroups |
系统资源 | 5%~15% | 0%~5% |
启动时间 | 分钟级 | 秒级 |
镜像存储 | GB-TB | KB-MB |
集群规模 | 上百 | 上万 |
高可用策略 | 备份、容灾、迁移 | 弹性、负载、动态 |
3.1 虚拟机隔离技术
从图,可以看到虚拟机(VM
)本质是一个软件,其具有完整硬件系统功能的、VM间隔离,类似于完整计算机系统。我们都知道操作系统的本质是一个软件,VM这样做就是在真实的操作系统下在新建一个或多个子操作系统(区别这些操作系统资源可控)。
虚拟机(VM
)是通过 Hypervisor
技术进行 虚拟机运行环境与计算机体系的建立 ,并通过该技术进行资源控制。由于篇幅有限,这里没有深入去讲解 Hypervisor
的概念,不是本文的重点,有表层认知就可以了。
3.2 容器化隔离技术
docker
充当着软件的角色运行在我们的操作系统,其实它是一个进程,利用操作系统提供的各种功能实现了进程间网络、空间、权限等隔离,让多个 docker
容器进程相互不知道彼此的存在。
虚拟机技术与容器技术的最大区别在于:多个虚拟机使用多个操作系统内核,而多个容器共享宿主机操作系统内核。
说到docker
的隔离技术,就很有必要了解Linux
的资源隔离技术(Namespace
)、资源限制技术(Cgroups
)、分层技术(Union File System
)。
3.2.1 Namespace-资源隔离技术
Linux Namespace(Linux
命名空间)是Linux
内核(Kernel)
提供的功能,它可以隔离一系列的系统资源,如PID
、User ID
、Network
、File System
等。
Linux
主要提供 6 种不同类型的Namespace
:
Namespace类型 | 描述 |
Mount | 隔离文件系统挂载点 |
UTS | 隔离HostName与DomianName |
IPC | 隔离进程间通信 |
PID | 隔离进程ID |
Network | 隔离网络 |
User | 隔离用户和用户组 |
下面举例两个场景来熟悉Namespace
:
情景一: 比如我们分配计算机的资源给一些用户,我们可以使用User Namespace
对不同的用户进行隔离,而用户在自己的命名空间内具有root
权限,但在真实物理机中,用户只操作了自己的空间的内容,这就解决了用户间隔离的问题。
情景二: 而用户在自己的User Namespace
里,也进行了PID NameSpace
隔离,对于这些用户来说,分配的命名空间就像一台新的Linux
,有自己的 init
进程(初始进程,PID
为 1),其他进程的 PID
在 init
进程 PID
上递增。
Linux关于Namespace有3个API:
①
clone()
: 创建新进程,根据系统调用flags
来决定哪种类型Namespace
将会被创建,而该进程的子进程也会包含这些Namespace
。②
setns ()
: 将进程加入到已存在的Namespace
中。③
unshare ()
: 将进程移出某个Namespace
这里可以看到:docker
就是利用 Linux Namespace
开放的API
来实现多个 docker
容器相互隔离,使其具有独立环境的功能。
3.2.2 Cgroups-资源限制技术
从上面可以看到docker
是使用了Linux Namespace
技术来实现了用户空间及进程的隔离,使用户觉得自己是在使用一个新的Linux
系统,那么docker
是如何限制用户在自己空间内的资源使用的呢?这里就使用到了Linux Cgroups
资源限制技术了。
Linux Cgroups(Linux Contorl Groups
,简称 Cgroups
):可以对一组进程及这些进程的子进程进行资源限制、控制和统计的能力,其中包括 CPU、内存、存储、网络、设备访问权限等,通过 Cgroups 可以很轻松的限制某个进程的资源占用并且统计该进程的实时使用情况。
说白了,可以把Cgroups
看作是Linux
一个资源限制功能,提供API
给docker
使用,docker
只要调用其API
就可以对当前用户NameSpace
命名空间内的资源进行限制以及查看。
Cgroups 由 3 个组件构成:分别是 cgroup
(控制组)、subsystem
(子系统)以及 hierarchy
(层级树)。
①
cgroup
: 是对进程分组管理的一种机制,一个cgroup
通常包含一组(多个)进程,Cgroups
中的资源控制都以cgroup
为单位实现。②
subsystem
:是一组(多个)资源控制的模块,每个subsystem
会管理到某个cgroup
上,对该cgroup
中的进程做出相应的限制和控制。③
hierarchy
:会将一组(多个)cgroup
构建成一个树状结构,Cgropus
可以利用该结构实现继承等功能
3.2.3 Union File System-分层技术
docker
镜像是一种分层结构,每一层构建在其它层之上,从而实现增量增加内容的功能,这是如何实现的?这里用到了Linux
的Union File System
分层技术。
Union File System(简称,UnionFS):是为 Linux
系统设计的将其他文件系统联合到一个联合挂载点的文件系统服务。UnionFS
使用 branch
(分支)将不同文件系统的文件和目录透明地叠加覆盖,形成一个单一一致的文件系统,此外 UnionFS
使用写时复制(Copy on Write
,简称,CoW)
技术来提高合并后文件系统的资源利用。
其实docker
镜像分层、增量增加就是利用UnionFS
功能,在基础的文件系统上增量的增加新的文件系统,通过叠加覆盖的形式最终形成一个文件系统,同时这也导致了运行 docker
容器如果没有指定 volume
(数据卷)或 bind mount
,则 docker
容器结束后,运行时产生的数据便丢失了(一般会指定宿主主机的目录)。
04 小结
本文主要讲解了docker的概念以及原理,整理下:
docker
是一个开源的应用容器引擎,它有开源、虚拟化、沙箱隔离机制的特点;docker
使用Namespace
来实现多个容器相互隔离,使其具有独立环境的功能;docker
使用Cgroups
对用户NameSpace
命名空间内的资源使用进行限制与监控;docker
使用UnionFS
实现分层结构与增量更新等功能。
这里需要说的是,docker不止使用了Namespace
、Cgroups
、UnionFS
这三种核心技术,还使用了很多其其它技术,本文就没有详述了。
本文或许存在纰漏之处,欢迎大家留言指出并关注。本文完!