千家信息网

Docker技术三大要点:cgroup, namespace和unionFS的理解

发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,www.docker.com 的网页有这样一张有意思的动画:从这张gif图片,我们不难看出Docker网站想传达这样一条信息, 使用Docker加速了build,ship和run的过程。Docker最
千家信息网最后更新 2025年02月01日Docker技术三大要点:cgroup, namespace和unionFS的理解

www.docker.com 的网页有这样一张有意思的动画:

从这张gif图片,我们不难看出Docker网站想传达这样一条信息, 使用Docker加速了build,ship和run的过程。

Docker最早问世是2013年,以一个开源项目的方式被大家熟知。

Docker的奠基者是dotcloud,一家开发PaaS平台的技术公司。

不过可惜的是,这家公司把Docker开源之后,于2016年倒闭了,因为其主业务PaaS无法和微软,亚马逊等PaaS业界巨头竞争,不禁让人唏嘘。

Docker其实是容器化技术的具体技术实现之一,采用go语言开发。很多朋友刚接触Docker时,认为它就是一种更轻量级的虚拟机,这种认识其实是错误的,Docker和虚拟机有本质的区别。容器本质上讲就是运行在操作系统上的一个进程,只不过加入了对资源的隔离和限制。而Docker是基于容器的这个设计思想,基于Linux Container技术实现的核心管理引擎。

为什么资源的隔离和限制在云时代更加重要?在默认情况下,一个操作系统里所有运行的进程共享CPU和内存资源,如果程序设计不当,最极端的情况,某进程出现死循环可能会耗尽CPU资源,或者由于内存泄漏消耗掉大部分系统资源,这在企业级产品场景下是不可接受的,所以进程的资源隔离技术是非常必要的。

我当初刚接触Docker时,以为这是一项新的技术发明,后来才知道,Linux操作系统本身从操作系统层面就支持虚拟化技术,叫做Linux container,也就是大家到处能看到的LXC的全称。

LXC的三大特色:cgroup,namespace和unionFS。

cgroup:

CGroups 全称control group,用来限定一个进程的资源使用,由Linux 内核支持,可以限制和隔离Linux进程组 (process groups) 所使用的物理资源 ,比如cpu,内存,磁盘和网络IO,是Linux container技术的物理基础。

namespace:

另一个维度的资源隔离技术,大家可以把这个概念和我们熟悉的C++和Java里的namespace相对照。

如果CGroup设计出来的目的是为了隔离上面描述的物理资源,那么namespace则用来隔离PID(进程ID),IPC,Network等系统资源。

我们现在可以将它们分配给特定的Namespace,每个Namespace里面的资源对其他Namespace都是透明的。

不同container内的进程属于不同的Namespace,彼此透明,互不干扰。

我们用一个例子来理解namespace的必要。

假设多个用户购买了一台Linux服务器的Nginx服务,每个用户在该服务器上被分配了一个Linux系统的账号。我们希望每个用户只能访问分配给其的文件夹,这当然可以通过Linux文件系统本身的权限控制来实现,即一个用户只能访问属于他本身的那些文件夹。

但是有些操作仍然需要系统级别的权限,比如root,但我们肯定不可能给每个用户都分配root权限。因此我们就可以使用namespace技术:

我们能够为UID = n的用户,虚拟化一个namespace出来,在这个namespace里面,该用户具备root权限,但是在宿主机上,该UID =n的用户还是一个普通用户,也感知不到自己其实不是一个真的root用户这件事。

同样的方式可以通过namespace虚拟化进程树。

在每一个namespace内部,每一个用户都拥有一个属于自己的init进程,pid = 1,对于该用户来说,仿佛他独占一台物理的Linux服务器。

对于每一个命名空间,从用户看起来,应该像一台单独的Linux计算机一样,有自己的init进程(PID为1),其他进程的PID依次递增,A和B空间都有PID为1的init进程,子容器的进程映射到父容器的进程上,父容器可以知道每一个子容器的运行状态,而子容器与子容器之间是隔离的。从图中我们可以看到,进程3在父命名空间里面PID 为3,但是在子命名空间内,他就是1.也就是说用户从子命名空间 A 内看进程3就像 init 进程一样,以为这个进程是自己的初始化进程,但是从整个 host 来看,他其实只是3号进程虚拟化出来的一个空间而已。

看下面的图加深理解。

父容器有两个子容器,父容器的命名空间里有两个进程,id分别为3和4, 映射到两个子命名空间后,分别成为其init进程,这样命名空间A和B的用户都认为自己独占整台服务器。

Linux操作系统到目前为止支持的六种namespace:

unionFS:

顾名思义,unionFS可以把文件系统上多个目录(也叫分支)内容联合挂载到同一个目录下,而目录的物理位置是分开的。

要理解unionFS,我们首先要认识bootfs和rootfs。

1. boot file system (bootfs):包含操作系统boot loader 和 kernel。用户不会修改这个文件系统。

一旦启动完成后,整个Linux内核加载进内存,之后bootfs会被卸载掉,从而释放出内存。

同样内核版本的不同的 Linux 发行版,其bootfs都是一致的。

2. root file system (rootfs):包含典型的目录结构,包括 /dev, /proc, /bin, /etc, /lib, /usr, and /tmp

就是我下面这张图里的这些文件夹:

等再加上要运行用户应用所需要的所有配置文件,二进制文件和库文件。这个文件系统在不同的Linux 发行版中是不同的。而且用户可以对这个文件进行修改。

Linux 系统在启动时,roofs 首先会被挂载为只读模式,然后在启动完成后被修改为读写模式,随后它们就可以被修改了。

不同的Linux版本,实现unionFS的技术可能不一样,使用命令docker info查看,比如我的机器上实现技术是overlay2:

看个实际的例子。

新建两个文件夹abap和java,在里面用touch命名分别创建两个空文件:

新建一个mnt文件夹,用mount命令把abap和java文件夹merge到mnt文件夹下,-t执行文件系统类型为aufs:

sudo mount -t aufs -o dirs=./abap:./java none ./mnt

mount完成后,到mnt文件夹下查看,发现了来自abap和java文件夹里总共4个文件:

现在我到java文件夹里修改spring,比如加上一行spring is awesome, 然后到mnt文件夹下查看,发现mnt下面的文件内容也自动被更新了。

那么反过来会如何呢?比如我修改mnt文件夹下的aop文件:

而java文件夹下的原始文件没有受到影响:

实际上这就是Docker容器镜像分层实现的技术基础。如果我们浏览Docker hub,能发现大多数镜像都不是从头开始制作,而是从一些base镜像基础上创建,比如debian基础镜像。

而新镜像就是从基础镜像上一层层叠加新的逻辑构成的。这种分层设计,一个优点就是资源共享。

想象这样一个场景,一台宿主机上运行了100个基于debian base镜像的容器,难道每个容器里都有一份重复的debian拷贝呢?这显然不合理;借助Linux的unionFS,宿主机只需要在磁盘上保存一份base镜像,内存中也只需要加载一份,就能被所有基于这个镜像的容器共享。

当某个容器修改了基础镜像的内容,比如 /bin文件夹下的文件,这时其他容器的/bin文件夹是否会发生变化呢?

根据容器镜像的写时拷贝技术,某个容器对基础镜像的修改会被限制在单个容器内。

这就是我们接下来要学习的容器 Copy-on-Write 特性。

容器镜像由多个镜像层组成,所有镜像层会联合在一起组成一个统一的文件系统。如果不同层中有一个相同路径的文件,比如 /text,上层的 /text 会覆盖下层的 /text,也就是说用户只能访问到上层中的文件 /text。

假设我有如下这个dockerfile:

FROM debian

RUN apt-get install emacs

RUN apt-get install apache2

CMD ["/bin/bash"]

执行docker build .看看发生了什么。

生成的容器镜像如下:

当用docker run启动这个容器时,实际上在镜像的顶部添加了一个新的可写层。这个可写层也叫容器层。

容器启动后,其内的应用所有对容器的改动,文件的增删改操作都只会发生在容器层中,对容器层下面的所有只读镜像层没有影响。

要获取更多Jerry的原创文章,请关注公众号"汪子熙":


文件 容器 进程 用户 镜像 系统 文件夹 技术 资源 空间 隔离 不同 基础 就是 操作系统 内存 两个 物理 服务 运行 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 包河区企业网络技术咨询优点 mysql 数据库 时区 网络安全事件预案幼儿园 综合评价计算机网络技术 软件开发需要具备什么学历 数据库管理员是工程技术人员吗 服务器加入一块硬盘怎么查看信息 云数据库的概念及其应用 网络安全协议课程心得 大学生网络安全竞赛题及答案 服务器执行接受的文件 网络安全的手抄报幼儿版 上海仓库进出库管理软件开发商 服务器搭建与配置摘要 数据库中怎样查找一个表 大数据网络安全与信息化 5g时代的网络安全论文 计算机网络技术个人经历 有软件开发公司 网络技术是干啥的 苹果电脑服务器 工业园区高品质服务器代理厂家 智能家居和服务器联系 贵州知名软件开发 像素工厂无法进入服务器 网络安全博弈不仅是 衡水酒吧移动点餐软件开发 程序员数据库原理及使用方法 数据库技术非空 服务器系统安装合并所有硬盘
0