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

news/2024/7/4 7:48:21 标签: kubernetes, 容器, 云原生

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

一、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技术,也就是下面的主角。


http://www.niftyadmin.cn/n/5253119.html

相关文章

Java网络编程——安全网络通信

在网络上,信息在由源主机到目标主机的传输过程中会经过其他计算机。在一般情况下,中间的计算机不会监听路过的信息。但在使用网上银行或者进行信用卡交易时,网络上的信息有可能被非法分子监听,从而导致个人隐私的泄露。由于Intern…

安全AI系统开发指南

执行摘要 本文件建议为使用人工智能(AI)的任何系统的提供商提供指导方针,无论这些系统是从头开始创建的,还是建立在他人提供的工具和服务之上的。实施这些指导方针将有助于提供商构建按预期运行、在需要时可用的人工智能系统&…

AI 中台

https://github.com/tencentmusic/cube-studio/blob/master/README_CN.md GitHub - lining0806/dingdang-robot: 叮当是一款可以工作在 Raspberry Pi 上的中文语音对话机器人/智能音箱项目。 https://github.com/WeBankFinTech/Exchangis/blob/master/README-ZH.md https://g…

【线性代数与矩阵论】Jordan型矩阵

Jordan型矩阵 2023年11月3日 #algebra 文章目录 Jordan型矩阵1. 代数重数与几何重数2. Jordan块与Jordan标准型2.1 最小多项式与Jordan标准型2.2 两类重要矩阵 3. 矩阵的Jordan分解3.1 Jordan分解的应用 下链 1. 代数重数与几何重数 在对向量做线性变换时,向量空间…

Promise与async/await的简单介绍

在 JavaScript 中,处理异步操作一直是开发者们面临的挑战之一。传统的回调函数方式往往导致代码难以维护、可读性差、易产生回调地狱等问题。为了解决这些问题,出现了 Promise 和 Async/Await 这两种处理异步操作的方式。 一、异步产生问题示例 当我们…

STM32用flash保存参数实现平衡擦写的一种方法

#FLASH平衡擦写# 一、概述 简易示意图如下: 写参数前要擦除对应的扇区 全为0XFFFFFFFF操作的最小单位为32位 uint32_t; 当一块扇区写完时,将所有有用参数复制到第二块扇区,开始写新的参数,如果所有参数写完,又重第…

vue3.2版本setup语法糖

setup语法糖&#xff1a; 一、Vue3.0 <script>里定义的变量、属性和方法必须 return 出来&#xff0c;<template>中才能使用&#xff1b;这样会导致在页面上变量会出现很多次。vue3.2只需在script标签中添加setup&#xff0c;就可以帮助我们解决这个问题,无需再写…

咨询室游戏

咨询室游戏 今天上午学了专注地学习了一上午&#xff0c;觉得自己真棒。中午吃完饭后之后就像休息一下&#xff0c;想一想自己两年前的中午的休息方式就是看书。索性就看看书吧。 今天的主题是咨询室游戏&#xff0c;摘自《人间游戏》一书。 那些在治疗场合因紧张发生的游戏对…