橘子学K8S01之容器中所谓的隔离

本文介绍了容器如何通过Namespace技术实现进程隔离,模拟独立的进程视图,以及Cgroups技术在资源限制中的作用。通过实例说明,容器实际上是通过限制进程的视角和资源使用来营造隔离环境的。

我们一直都在说容器就是一个沙盒,沙盒技术顾名思义就是像一个集装箱一样,把应用(服务,进程之类的)装起来的技术,这样每个进程在自己的沙盒中和其他的沙盒隔离开来,每个沙盒之间存在一个边界使得他们互不干扰,而被装入这个盒子中的应用也就很方便的可以跟着沙盒搬来搬去,这是一种很方便很理想的管理状态。
于是围绕这个状态的实现,需要一种可以真实落地的技术。也就是隔离和限制技术。

一、Namespace隔离技术

1、隔离的现象

我们说容器的核心功能就是通过约束和修改进程的动态表现,从而创造出一个边界,而Cgroups技术就是用来制造约束的能力,而我们这里要说的NameSpace则是用来修改进程的视图的技术,修改视图其实就是修改进程视角下自己能看到的内容。
我们先来操作一下,所以我们需要准备一个Linux环境和docker项目,至于你是哪个Linux的发行版本这不重要。我的环境如下:

CentOS Linux release 7.8.2003
Docker Engine - Community 20.10.14

首先我们先创建一个容器:执行docker run -it busybox /bin/sh命令来创建容器

#root  docker run -it busybox /bin/sh
这句命令的参数我们逐一来解释一下:
-it :在启动docker容器之后,给我们分配一个文本的输入输出环境,有了这个输入输出环境,我们就能在输入端和docker交互然后在输出端
获得交互的结果。

/bin/sh :就是我们在docker容器中运行的程序,bin/sh是一个常用的shell。

所以上面这句话的意思最终表达就是:请帮我启动一个容器,并且在容器里面执行/bin/sh这个shell,并且在启动之后就分配一个命令行的
终端来让我和这个容器交互。

在做完了以上操作之后,我的Linux机器就变成了宿主机,而这个运行着/bin/sh的容器 busybox 就运行在我的这台宿主机里。

在执行完以上这句命令之后,其实我们就进入了容器内部,并且可以通过终端交互。界面如下。
在这里插入图片描述
此时我们在交互终端指定ps,列出容器内的所有进程。
在这里插入图片描述
我们发现里面只有两个进程,我们在启动时运行的/bin/sh就是这个容器内部的一号进程(PID为1),第二个则就是我们执行的ps进程。此时这两个进程已经被隔离在我们这个容器中了。也就是所谓的沙盒世界。那么其中的原理又是为何呢?

2、隔离的原理

本来在我们没有容器的时候,我们直接在宿主机上运行一个/bin/sh程序,此时就会启动一个/bin/sh的进程,操作系统就会给他这个进程分配一个进程ID(PID),这个类似于编号一样的PID,是这个进程的唯一标识,就像一个公司中的员工的工号一眼。比如系统为他分配的是100,那么他就等同于工号为100的员工。公司的boss就是编号为1的员工。

但是此时我们有了容器了,当我们把程序运行在容器中的时候,docker就会给这个进程施展一个障眼法,让他感知不到前面的进程,看不到其他前面的99个员工,此时他就以为自己是1号员工,此时他就在一种忽悠的状态下,认为自己的ID就是1。

所以这种机制类比在linux中,就是在隔离的空间中运行的进程只能看到计算过后的编号,PID=1。实际上,你还是在操作系统上运行,在操作系统的视角看,你还是你100号员工,妄想成为1号,那是你自己认为。
这就是Linux中的Namespace机制,而对应在Linux中的实现中,namespace的实现方式,其实就是Linux创建进程的一个传入的可选参数,在linux中创建进程的系统函数为clone(),也就是如下:

int pid = clone(main_function,stack_size,SIGCHLD,NULL);
这行代码会创建一个进程,然后返回值是这个进程的PID,也就是那个编号。而玄机就在第三个参数中,第三个
形参可以有两种传入实参,CLONE_NEWPID和SIGCHLD,当我们传入的是SIGCHLD就创建真实的进程,不做任何
障眼法,而当我们把参数指定为CLONE_NEWPID,创建出来的进程,就会在自己的视角看到一个全新的空间,在
这个进程空间中,他的PID就是1,而这一切都是一个障眼法,在宿主机的真实的进程空间中,他的进程PID还是
真实的数字,比如100,而不是1.

如果你创建多个这样的进程,他们自己的视角中自己都是PID=1的进程,他们看不到宿主机的真实进程空间,同时也看不到其他的沙盒里面的状况,换言之,他们实现了隔离。
而且在PID的Namespace隔离之外,Linux还提供了诸如Mount,UTS,IPC,Network,User这些Namespace,用来对其他的网络设备和其他配置做隔离,这样每个进程都只能看到自己的空间里面的隔离内容了。

二、总结

所以我们可以看到,所谓的docker容器,实际就是在创建容器进程的时候,指定了一组关于这个进程需要启动的Namespace,隔离了进程的PID,文件,设备,配置等等。而对于宿主机以及其他和这个进程不相关的进程,他是完全看不到的。

所以,容器,其实就是一种特殊的进程。只是他做了隔离。
所以在这个概念之上,我们就知道,所谓容器,在使用的时候其实并没有一个真实的容器存在,docker启动的其实还是原来的应用,只是在创建这些进程的时候docker加上了很多Namespace参数来限制进程的视角。
当限制完成之后,这些进程就觉得自己是各自的PID Namespace里面的1号进程,只能看到自己各自的Mount Namespace挂载的目录和文件,只能访问各自Network Namespace里面的网络设备,只能看到自己被限制的那一组namespace空间中的内容,仿佛与世隔绝一样。所以一切都是障眼法。

而在完成了隔离之后,在自己那一亩三分地运行的进程对于资源也是需要做限制的,而这个限制就是所谓的Cgroups技术,也就是下面的主角。

[root@k8s01 filebeat]# systemctl status filebeat ● filebeat.service Loaded: loaded (/usr/lib/systemd/system/filebeat.service; disabled; preset: disabled) Active: active (running) since Mon 2025-08-11 15:29:22 CST; 5s ago Main PID: 2216031 (filebeat) Tasks: 9 (limit: 48665) Memory: 37.9M CPU: 215ms CGroup: /system.slice/filebeat.service └─2216031 /home/cbsuser/app/filebeat/filebeat -e -c /home/cbsuser/app/filebeat/filebeat.yml -path.home /home/cbsuser/app/filebeat -path.config /home/cbsuser/app/filebeat -path.data /home/cbsuser/> Aug 11 15:29:22 k8s01 filebeat[2216031]: 2025-08-11T15:29:22.796+0800 INFO memlog/store.go:119 Loading data file of '/home/cbsuser/app/filebeat/data/registry/filebeat' succeeded. Active t> Aug 11 15:29:22 k8s01 filebeat[2216031]: 2025-08-11T15:29:22.796+0800 INFO memlog/store.go:124 Finished loading transaction log file for '/home/cbsuser/app/filebeat/data/registry/filebeat> Aug 11 15:29:22 k8s01 filebeat[2216031]: 2025-08-11T15:29:22.797+0800 INFO [registrar] registrar/registrar.go:109 States Loaded from registrar: 0 Aug 11 15:29:22 k8s01 filebeat[2216031]: 2025-08-11T15:29:22.797+0800 INFO [crawler] beater/crawler.go:71 Loading Inputs: 1 Aug 11 15:29:22 k8s01 filebeat[2216031]: 2025-08-11T15:29:22.797+0800 INFO [crawler] beater/crawler.go:117 starting input, keys present on the config: [filebeat.inputs.0.paths.0 fi> Aug 11 15:29:22 k8s01 filebeat[2216031]: 2025-08-11T15:29:22.797+0800 ERROR [input] input-logfile/manager.go:177 filestream input ID without ID might lead to data duplication, plea> Aug 11 15:29:22 k8s01 filebeat[2216031]: 2025-08-11T15:29:22.797+0800 INFO [crawler] beater/crawler.go:148 Starting input (ID: 621065075911478034) Aug 11 15:29:22 k8s01 filebeat[2216031]: 2025-08-11T15:29:22.797+0800 INFO [crawler] beater/crawler.go:106 Loading and starting Inputs completed. Enabled inputs: 1 Aug 11 15:29:22 k8s01 filebeat[2216031]: 2025-08-11T15:29:22.798+0800 INFO [input.filestream] compat/compat.go:120 Input 'filestream' starting {"id": " 89E7765601ACB12"} Aug 11 15:29:22 k8s01 filebeat[2216031]: 2025-08-11T15:29:22.798+0800 ERROR [input.filestream] filestream/input.go:140 File could not be opened for reading: failed opening /var/log> [root@k8s01 filebeat]#
最新发布
08-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值