[k8s理论知识]3.docker基础(二)隔离技术

容器其实是一种沙盒技术,其核心是通过约束和修改进程的动态表现,为其创建一个边界。这个边界确保了应用与应用之间不会相互干扰,同时可以方便在不同的环境中迁移,这是PaaS最理想的状态。

程序是代码的可执行镜像,通常以二进制文件的形式存储在磁盘上。但是当程序被执行时,操作系统会将程序的数据加载到内存中,读取计算指令并指示CPU执行。CPU与内存协作进行计算,使用寄存器存放数值,内存堆栈保存执行的命令和变量,此外,程序还可能打开文件和调用IO设备。所有这些状态信息和数据信息的集合,构成了进程的动态表现。

进程可以理解为是 动态的程序,但更准确地说,进程是程序在计算机系统中的一个 执行实例。程序本身只是静态的代码文件(通常指由源代码编译得到的可执行文件),而进程则是该程序的一个活动状态,它包含了程序的执行上下文和资源。

那么,如果给进程之间确立边界,也就是给程序创建了边界。而容器技术的核心,就是通过约束和修改进程的动态表现,从而为其创造一个边界。

Nampespace技术

启动一个busybox容器,通过以下操作让我们更好的理解进程隔离。

[root@master ~]# docker run -it busybox:v1 /bin/sh
/ # pid
/bin/sh: pid: not found
/ # ps
PID   USER     TIME  COMMAND1 root      0:00 /bin/sh6 root      0:00 ps

可以看到,我们在 Docker 里最开始执行的 /bin/sh,就是这个容器内部的第 1 号进程(PID=1),而这个容器里一共只有两个进程在运行。这就意味着,前面执行的 /bin/sh,以及我们刚刚执行的 ps,已经被 Docker 隔离在了一个跟宿主机完全不同的世界当中。

当我们不要关闭这个命令行(否则容器会销毁),而打开另一个窗口,查看这个容器的pid,可以看到这个容器的PID实际为16043。

[root@master ~]# docker ps | grep busybox
e45240f24ffb   busybox:v1                                          "/bin/sh"                 12 seconds ago   Up 11 seconds             epic_moser
[root@master ~]# docker inspect --format '{{.State.Pid}}' e45240f24ffb 
16043

以上表述实际上是非常不严谨的,因为容器本身没有PID,容器只是为程序提供一个隔离的视图,而运行在容器里的程序(在我们的例子中是/bin/bash)才拥有PID。也就是说在查看容器的PID的时候,查看的实际上是它内部程序的PID。

所以我们可以理解,这个bin/bash本身的PID是16043,而容器实施了一个障眼法,让前面的所有PID都看不见了,这个程序的PID也就成了1。

事实上,以上只是将进程空间进行了Namespace隔离,容器还需要进行文件系统、IO设备等的隔离。这些在后面会一一演示。

在理解了 Namespace 的工作方式之后,你就会明白,跟真实存在的虚拟机不同,在使用 Docker 的时候,并没有一个真正的“Docker 容器”运行在宿主机里面。Docker 项目帮助用户启动的,还是原来的应用进程,只不过在创建这些进程时,Docker 为它们加上了各种各样的 Namespace 参数。

Cgroups

从上面例子可以看出,Namespace技术改变了进程看待计算机的视图,但是计算机并没有改变看待进程的视图,对于底层操作系统而言,容器里的进程和直接运行的进程没有区别。也就是说,虽然上面例子中的bin/bash进程表面上被隔离了起来,但是实际上它能得到的内存和cpu资源,却可以随意的被其他进程占用。而这个进程本身也可以吃掉别的进程的资源,这不符合一个沙盒的行为表现。而且,在linux内核中,有很多的资源是不能namespace化的,比如时间。

Linux Cgroups 的全称是 Linux Control Group。它最主要的作用,就是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。通过以下命令可以看到cgroup在系统中挂载的位置。

[root@master ~]# mount -t cgroup 
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_prio,net_cls)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)

可以看到,在 /sys/fs/cgroup 下面有很多诸如 cpuset、cpu、 memory 这样的子目录,也叫子系统。这些都是我这台机器当前可以被 Cgroups 进行限制的资源种类。我们进入CPU目录,可以看到有很多cpu的配置文件。在这些文件中,文件夹container是我们后来创建的。

当我们进入container文件夹,会看到里面已经创建了完整的cgoups文件系统。 这是因为当你在cgroups的某个子系统(比如cpu或者sys等),你实际上在创建一个新的控制组,控制组允许你为该组内的进程设置资源限制或监控资源使用情况。因此Linux内核会在这个子目录下生成一系列与该子系统相关的文件。

 但是这些文件实际上是虚拟的,并不是存储载物理磁盘上的文件,只是为用户提供的与内核交互的接口。

 随后打开另一个终端,执行以下命令。这条命令是一个死循环,会吃光所有cpu资源。

可以看到这个进程PID是47975。

接下来进入container目录, 看到 container 控制组里的 CPU quota 还没有任何限制(即:-1),CPU period 则是默认的 100  ms(100000  us)

[root@master container]# cat cpu.cfs_period_us 
100000
[root@master container]# cat cpu.cfs_quota_us 
-1

接下来我们进行控制组的限制操作,向container组里的cfs_quota和cfs_period文件写入参数进行限制。

以下的操作意思是100000us(100ms)里面有20000us(20ms)可以给这个控制组使用。

接下来要将这个PID(47975)放入这个控制组。

重新用top命令查看,发现 它虽然是一个死循环,但是只占用了20%的cpu资源。

控制组 

不是每一个Linux进程都有自己的控制组,但是每个进程都会属于某一个资源控制组。在没有配置自定义 cgroups 的情况下,所有进程都会被分配到系统的默认控制组,这些默认的 cgroups 通常是由 init 系统(如 systemd)或直接由内核管理的。多个进程也可以被放置在同一个控制组中。

比如说我们查看cgroup/cpu里的user.slice文件夹,可以看到里面有一个procs文件,打开可以看到这个资源控制组的所有进程。

假设有一个进程PID是12345,我们可以将它加入控制组中。

echo 12345 > /sys/fs/cgroup/cpu/user.slice/cgroup.procs

创建一个docker,并规定了他的cpu资源限制。可以看到docker ID是b47efc8e7d29,cgroup目录是system.slice下的以b47efc8e7d29开头的文件夹。

[root@master ~]# docker run  -it --cpu-period=100000 --cpu-quota=20000 ubuntu /bin/bash
root@b47efc8e7d29:/# cat /proc/self/cgroup
11:pids:/system.slice/docker-b47efc8e7d291be37292fdf8edb160947e2bfa413595f90d6d4960f7b22a3edf.scope
10:memory:/system.slice/docker-b47efc8e7d291be37292fdf8edb160947e2bfa413595f90d6d4960f7b22a3edf.scope
9:perf_event:/system.slice/docker-b47efc8e7d291be37292fdf8edb160947e2bfa413595f90d6d4960f7b22a3edf.scope
8:cpuset:/system.slice/docker-b47efc8e7d291be37292fdf8edb160947e2bfa413595f90d6d4960f7b22a3edf.scope
7:net_prio,net_cls:/system.slice/docker-b47efc8e7d291be37292fdf8edb160947e2bfa413595f90d6d4960f7b22a3edf.scope
6:devices:/system.slice/docker-b47efc8e7d291be37292fdf8edb160947e2bfa413595f90d6d4960f7b22a3edf.scope
5:blkio:/system.slice/docker-b47efc8e7d291be37292fdf8edb160947e2bfa413595f90d6d4960f7b22a3edf.scope
4:cpuacct,cpu:/system.slice/docker-b47efc8e7d291be37292fdf8edb160947e2bfa413595f90d6d4960f7b22a3edf.scope
3:hugetlb:/system.slice/docker-b47efc8e7d291be37292fdf8edb160947e2bfa413595f90d6d4960f7b22a3edf.scope
2:freezer:/system.slice/docker-b47efc8e7d291be37292fdf8edb160947e2bfa413595f90d6d4960f7b22a3edf.scope
1:name=systemd:/system.slice/docker-b47efc8e7d291be37292fdf8edb160947e2bfa413595f90d6d4960f7b22a3edf.scope

进入文件夹,可以看到他的cpu资源限制。 也就是说docker可以在创建容器的时候进行资源限制。

[root@master system.slice]# cd docker-b47efc8e7d291be37292fdf8edb160947e2bfa413595f90d6d4960f7b22a3edf.scope/
[root@master docker-b47efc8e7d291be37292fdf8edb160947e2bfa413595f90d6d4960f7b22a3edf.scope]# ls
cgroup.clone_children  cgroup.procs  cpuacct.usage         cpu.cfs_period_us  cpu.rt_period_us   cpu.shares  notify_on_release
cgroup.event_control   cpuacct.stat  cpuacct.usage_percpu  cpu.cfs_quota_us   cpu.rt_runtime_us  cpu.stat    tasks
[root@master docker-b47efc8e7d291be37292fdf8edb160947e2bfa413595f90d6d4960f7b22a3edf.scope]# cat cpu.rt_period_us 
1000000
[root@master docker-b47efc8e7d291be37292fdf8edb160947e2bfa413595f90d6d4960f7b22a3edf.scope]# cat cpu.cfs_quota_us 
20000
echo操作 

 /sys/fs/cgroup/cpu/container/cgroup.procs 和 /sys/fs/cgroup/cpu/container/cpu.cfs_quota_us 这两个文件的行为是不同的,所以当我们进行echo操作的时候,写入cpu.cfs_quota_us 文件的行为是覆盖式的。当你使用 echo 写入一个新的值时,它会替换掉之前的值。cgroup.procs 是一个特殊的文件,它的目的是让用户通过写入进程 ID 来动态管理进程所属的控制组。因此它的行为不是像普通文件那样追加或覆盖内容,而是执行一个动作(将进程加入到该控制组)。

文件系统

如果不进行单的文件系统挂载,容器内的进程的文件系统视图就是整个物理主机的视图。所以在容器创建之前,docker通过重新挂载根目录,从而让容器进程看到的是一个独立的隔离环境。为了能够让容器的这个根目录看起来更“真实”,Docker会在这个容器的根目录下挂载一个完整操作系统的文件系统,比如 Ubuntu16.04 的 ISO。这样,在容器启动之后,我们在容器里通过执行 "ls /" 查看根目录下的内容,就是 Ubuntu 16.04 的所有目录和文件。而挂载在容器根目录上,用来为进程提供隔离后环境的文件的操作系统,就是所谓的容器镜像。它还有一个更为专业的名字,叫作:rootfs(根文件系统)。

值得注意的是,rootfs只是一个操作系统所包含的文件、配置和目录,并不包含操作系统的内核。Linux操作系统分为两部分,内核和用户态。

内核:这是操作系统的核心,负责与硬件交互、调度进程、管理内存、网络、文件系统等。无论是ubuntu、centos还是其他linux发行版的内核,他们的核心功能是相同的。

用户态:这是操作系统中用户可以直接接触的部分,比如程序、库、配置文件等等。不同的linux发行版(linux/ubuntu/debian)在用户态可能有很大不同,包括包管理、配置文件等。

对于容器来讲,操作系统就是宿主机的操作系统内核。所以说,当你拉取一个 CentOS 容器镜像时,实际上你只是拉取了 CentOS 的用户态部分(包括系统工具、库、配置文件等),而不包含 CentOS 的内核。容器中的进程依然使用的是宿主机的内核来运行。因此,无论宿主机运行的是 Ubuntu 还是其他发行版的内核,只要它是 Linux 内核,容器中的 CentOS 文件系统都可以正常工作。

Docker和VM对比

但是事实上,宿主机不可能光有一个内核态,他也是有用户态的。当你在一个 Ubuntu 宿主机上运行一个 CentOS 容器时,容器中的进程会使用 CentOS 的用户态工具和库。比如,容器中的 yum(CentOS 的包管理器)可以正常运行,而不会使用 Ubuntu 的 apt(Ubuntu 的包管理器)。因此,容器就像是一个独立的系统,拥有自己的文件系统、程序、配置等,不依赖宿主机的用户态。你可以把它想象为容器本身有一个“虚拟的用户态”,但它并不运行在宿主机的用户态环境中。

当你在一个 Ubuntu 宿主机上运行了一个 CentOS 虚拟机,虚拟机内的 CentOS 系统会像在物理机上一样启动,它将加载自己的 CentOS 内核,并启动 CentOS 的用户态环境。CentOS 虚拟机使用自己的内核来处理系统调用、管理进程、分配内存等。这个内核与宿主机的内核完全独立,因此 CentOS 虚拟机可以运行与宿主机不同版本的内核。

对 Docker 项目来说,它最核心的原理实际上就是为待创建的用户进程:启用 Linux Namespace 配置;设置指定的 Cgroups 参数;切换进程的根目录(Change Root)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/57210.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

探索Spring Cloud Config:构建高可用的配置中心

目录 认识Spring Cloud ConfigConfig Server读取配置文件步骤1:(1)创建config-server项目(2)在config-server中开启Config Server功能(3)在config-server配置文件进行相关配置(4&…

Axure复选框全选反选取消高级交互

亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢! 课程主题:复选框全选反选取消制作 主要内容:点击复选框,实现列表数据项全选选中、反选和取消选中效果 应用场景:多项选定…

【MySQL 保姆级教学】表的增删改查(上)

表的增删改查 1. 创建一个表 CREATE2 插入数据 INSERT INTO2.1 语法2.2 插入单行数据全列插入2.3 插入多行数据指定列插入2.4 同步更新 ON DUPLICATE KEY UPDATE2.4.1 引入2.4.2 同步更新2.4.3 查看被影响的行 2.5. 替换 REPLACE INTO 3. Retrieve(查询SELECT&#…

有道在线翻译+4款新星,翻译从此无障碍,你get了吗?

现在全世界都连在一起了,说话不一样的问题再也不是啥大事。不管是搞研究、谈生意还是平时过日子,翻译软件都成了我们离不开的帮手。今儿,我们特激动地告诉大家,有道在线翻译和三个新伙伴一起,给Windows系统做了个超牛的…

9.校园二手网站系统( Springboot 和 thymeleaf(html)开源框架)

目录 1.系统的受众说明 2.系统需求分析 2.2.1用户功能模块 2.2.2二手交易功能需求 2.2.3需求发布功能需求 2.3.1操作流程 2.3.2添加信息流程 2.3.3删除信息流程 2.4 系统E-R图 3.系统概要设计 3.1系统的整体架构 3.2 数据库表 4.系统实现 4.1用户功能模块 4.2 二…

程序员们辛苦啦!1024程序员节,今天,我们不一样!

一、程序员节来历 程序员节(Programmers Day)是一年中专门为程序员和计算机科学工作者所设立的节日,通常是在每年的第256天庆祝。256这个数字在编程中具有特别的意义,因为它是2的8次方,代表着一个字节可以表示的所有可…

如何借助前端表格控件助力企业实现财务数字化转型

最新技术资源(建议收藏) https://www.grapecity.com.cn/resources/ 前言 在当今快速变化的经济环境中,记账软件对个人和企业的重要性愈发突出。对于个人而言,它可以帮助用户实时掌握财务状况,促进合理消费和有效储蓄&…

Java项目-基于Springboot的高校党务系统项目(源码+说明).zip

作者:计算机学长阿伟 开发技术:SpringBoot、SSM、Vue、MySQL、ElementUI等,“文末源码”。 开发运行环境 开发语言:Java数据库:MySQL技术:SpringBoot、Vue、Mybaits Plus、ELementUI工具:IDEA/…

【SoC_Design】USB基本知识

目录 USB物理接口 USB3.0物理层支持dp-alt的usb type-c接口 拓扑结构层次结构 USB物理接口 USB2.0 两线:D、D- USB3 六线:D、D-、SSTX、SSTX-、SSRX、SSRX- USB3 2lane 十线: D、D-、(SSTX、SSTX-、SSRX、SSRX-)x2USB2…

CSS文本基础知识

1、文本缩进 属性名:text-indent 属性值:数值px; 数字em(推荐:1em当前标签的字号大小) 例:代码: 结果: 2、文本对齐方式 作用:控制内容水平方式 属性名&#xff1a…

公众号变现及生财内参项目建议

一、核心内容 (一)公众号变现分享 从业者王薄荷介绍公众号常规盈利思路为推文广告和品牌广告,公众号能外链的地方有菜单栏和阅读原文,虽菜单栏点击率低但有商业价值。以小说为例,主要盈利方式是小黄文截止在高潮部分…

HTB:Knife[WriteUP]

目录 连接至HTB服务器并启动靶机 1.How many TCP ports are open on Knife? 2.What version of PHP is running on the webserver? 并没有我们需要的信息,接着使用浏览器访问靶机80端口 尝试使用ffuf对靶机Web进行一下目录FUZZ 使用curl访问该文件获取HTTP头…

聚焦IOC容器刷新环节postProcessBeanFactory(BeanFactory后置处理)专项

目录 一、IOC容器的刷新环节快速回顾 二、postProcessBeanFactory源码展示分析 (一)模版方法postProcessBeanFactory (二)AnnotationConfigServletWebServerApplicationContext 调用父类的 postProcessBeanFactory 包扫描 …

React综合指南(二)

https://activity.csdn.net/creatActivity?id10787 #1024程序员节|征文# 21、 React中的状态是什么?它是如何使用的?? 状态是 React 组件的核心,是数据的来源,必须尽可能简单。基本上状态是确定组件呈现…

rk3568 android11 单独烧写内核。

问题: 我现在 遇到一个问题,如果我单独 烧写boot.img 的话,就会进入 recovery 的模式。 如下图: 问题说明: 如果我烧写的 Update.img 是可以启动的。那么我再烧写一个 编译 update.img 顺带编译出来的 boot.img 是可以正常启动的。 问题出在 , 如果我 重新编译一遍 ,使…

在Oxygen编辑器中支持数学公式

在编写文档时,经常需要插入公式。虽然将公式作为图片插入到文档中是可以的,但这会使后续的修改变得非常不便。目前,MathML (Mathematical Markup Language) 和 LaTeX 是两种常用的数学公式描述语言,它们各自具有不同的特点和适用场…

第二十九篇:图解TCP三次握手,一次说透,TCP系列四

⼀开始,客户端和服务端都处于 CLOSED 状态。先是服务端主动监听某个端⼝,处于 LISTEN 状态。 接下来这部分内容的介绍将影响你能不能彻底理解了TCP的三次握手。 一、划重点:只有服务端启动了端口监听,客户端TCP握手才能建立连接&…

关于jmeter设置为中文问题之后无法保存设置的若干问题

1、jemeter如何设置中文模式 Options--->Choose Language--->Chinese(Simplifies), 如此设置后就可显示中文模式(缺点:下次打开还是英文);如下图所示: 操作完成之后: 但是下次重启之后依旧是英文; 2、在jmeter.…

TRIZ理论在医疗电子研发中的应用

TRIZ,全称“Theory of Inventive Problem Solving”(发明问题解决理论),是一种系统化、逻辑严谨的创新方法论。它通过对大量发明案例的深入分析和总结,提炼出一套行之有效的创新原理和解决方案,旨在帮助人们…

【Word原件测试资料合集】软件系统功能测试方案,软件测试方案(整体方案),软件测试文档-测试计划模版(功能与性能),软件测试流程

一、 前言 (一) 背景 (二) 目的 (三) 测试目标 (四) 适用范围与读者对象 (五) 术语与缩写 二、 软件测试实施流程 (一) 测试工作总体流…