docker核心原理——unionfs、namespace、cgroup

docker

核心原理

docker的核心原理其实就是cgroup+namespace+unionfs 组合实现的隔离机制,资源控制等。

隔离机制

  • 在容器进程启动之前重新挂载它的整个根⽬录“/”,⽤来为容器提供隔离后的执⾏环境⽂件系统
  • 通过Linux Namespace 创建隔离,决定进程能够看到和使⽤哪些东⻄。
  • 通过control groups 技术来约束进程对资源的使⽤

unionfs

首先看rootfs,rootfs 是Docker 容器在启动时内部进程可⻅的⽂件系统,即Docker容器的根⽬录。rootfs通常包含⼀个操作系统运⾏所需的⽂件系统,例如可能包含经典的类Unix操作系统中的⽬录系统,如/dev、/proc、/bin、/etc、/lib、/usr、/tmp及运⾏Docker容器所需的配置⽂件、⼯具等。

在传统的linux操作系统内核启动时,⾸先挂载⼀个只读(read-only)的rootfs,当系统检测器完整性之后,再将其切换为读写(read-write)模式。⽽在Docker架构中,当Docker daemon 为Docker容器挂载rootfs时,沿⽤的Linux内核启动时的⽅法,即将rootfs设为只读模式。在挂载完毕之后,利⽤联合挂载(union mount)技术在已有的只读rootfs上再挂载⼀个读写层。这样,可读写层处于Docker容docker器⽂件系统的最顶层,其下可能联合挂载了多个只读层,只有在Docker容器运⾏过程中⽂件系统发⽣变化是,才会把变化的⽂件内容写到可读写层,并且隐藏只读层中的⽼版本⽂件。

如图所示,还可以在rootfs之上继续挂载读写层,也可以挂载只读层(可以用于共享)。上层的修改不会影响到下层的只读层。而只读层的修改会同步到上层可写层

在这里插入图片描述

有了容器镜像“打包操作系统”的能⼒,这个最基础的依赖环境也终于变成了应⽤沙盒的⼀部分。这就赋予了容器所谓的⼀致性:⽆论在本地、云端,还是在⼀台任何地⽅的机器上,⽤户只需要解压打包好的容器镜像,那么这个应⽤运⾏所需要的完整的执⾏环境就被重现出来了

namespace

概念

是一种资源隔离技术,可以和c++里的namespace类比

  • namespace 是 Linux 内核⽤来隔离内核资源的⽅式。通过 namespace 可以让⼀些进程只能看到与⾃⼰相关的⼀部分资源,⽽另外⼀些进程也只能看到与它们⾃⼰相关的资源,这两拨进程根本就感觉不到对⽅的存在。具体的实现⽅式是把⼀个或多个进程的相关资源指定在同⼀个 namespace 中。

  • Linux namespaces 是对全局系统资源的⼀种封装隔离,使得处于不同 namespace 的进程拥有独⽴的全局系统资源,改变⼀个 namespace 中的系统资源只会影响当前 namespace ⾥的进程,对其他namespace 中的进程没有影响。

namespace解决了什么问题呢?

Linux 内核实现 namespace 的⼀个主要⽬的就是实现轻量级虚拟化(容器)服务。在同⼀个namespace 下的进程可以感知彼此的变化,⽽对外界的进程⼀⽆所知。这样就可以让容器中的进程产⽣错觉,认为⾃⼰置身于⼀个独⽴的系统中,从⽽达到隔离的⽬的。也就是说 linux 内核提供的namespace 技术为 docker 等容器技术的出现和发展提供了基础条件。

有哪些namespace
  • Mount Namespace隔离了⼀组进程所看到的⽂件系统挂载点的集合,因此,在不同MountNamespace的进程看到的⽂件系统层次结构也不同
  • UTS Namespace隔离了uname()系统调⽤返回的两个系统标示符nodename和domainname,在容器的上下⽂中,UTS Namespace允许每个容器拥有⾃⼰的hostname和NIS domain name,这对于初始化和配置脚本是很有⽤的,这些脚本根据这些名称来定制它们的操作
  • IPC Namespace隔离了某些IPC资源(interprocess community,进程间通信)使划分到不同IPC Namespace的进程组通信上隔离,⽆法通过消息队列、共享内存、信号量⽅式通信
  • PID Namespace隔离了进程ID号空间,不同的PID Namespace中的进程可以拥有相同的PID。PID Namespace的好处之⼀是,容器可以在主机之间迁移,同时容器内的进程保持相同的进程ID。PID命名空间还允许每个容器拥有⾃⼰的init(PID 1),它是 “所有进程的祖先”,负责管理各种系统初始化任务,并在⼦进程终⽌时收割孤⼉进程
  • Network Namespace提供了⽹络相关系统资源的隔离,因此,每个Network Namespace都有⾃⼰的⽹络设备、IP地址、IP路由表、/proc/net⽬录、端⼝号等。
  • User Namespace隔离了⽤户和组ID号空间,⼀个进程的⽤户和组ID在⽤户命名空间内外可以是不同的,⼀个进程可以在⽤户命名空间外拥有⼀个正常的⽆权限⽤户ID,同时在命名空间内拥有⼀个(root权限)的⽤户ID

命名空间查看

ls /proc/{PID}/ns

cgroup

cgroup全称是control groups被整合在了linux内核当中,把进程(tasks)放到组⾥⾯,对组设置权限,对进程进⾏控制。可以理解为⽤户和组的概念,⽤户会继承它所在组的权限。cgroups是linux内核中的机制,这种机制可以根据特定的⾏为把⼀系列的任务,⼦任务整合或者分离,按照资源划分的等级的不同,从⽽实现资源统⼀控制的框架,cgroup可以控制、限制、隔离进程所需要的物理资源,包括cpu、内存、IO,为容器虚拟化提供了最基本的保证,是构建docker⼀系列虚拟化的管理⼯具

解决如下问题

  • 资源控制:cgroup通过进程组对资源总额进⾏限制。如:程序使⽤内存时,要为程序设定可以使⽤主机的多少内存,也叫作限额
  • 优先级分配:使⽤硬件的权重值。当两个程序都需要进程读取cpu,哪个先哪个后,通过优先级来进⾏控制
  • 资源统计:可以统计硬件资源的⽤量,如:cpu、内存…使⽤了多⻓时间
  • 进程控制:可以对进程组实现挂起/恢复的操作,

cgroup设计到许多子系统,每种子系统可以进行不同的资源调控

1. cpu⼦系统:该⼦系统为每个进程组设置⼀个使⽤CPU的权重值,以此来管理进程对cpu的访
问。
2. cpuset⼦系统:对于多核cpu,该⼦系统可以设置进程组只能在指定的核上运⾏,并且还可以
设置进程组在指定的内存节点上申请内存。
3. cpuacct⼦系统:该⼦系统只⽤于⽣成当前进程组内的进程对cpu的使⽤报告
4. memory⼦系统:该⼦系统提供了以⻚⾯为单位对内存的访问,⽐如对进程组设置内存使⽤上
限等,同时可以⽣成内存资源报告
5. blkio⼦系统:该⼦系统⽤于限制每个块设备的输⼊输出。⾸先,与CPU⼦系统类似,该系统
通过为每个进程组设置权重来控制块设备对其的I/O时间;其次,该⼦系统也可以限制进程组
的I/O带宽以及IOPS
6. devices⼦系统:通过该⼦系统可以限制进程组对设备的访问,即该允许或禁⽌进程组对某设
备的访问
7. freezer⼦系统:该⼦系统可以使得进程组中的所有进程挂起
8. net-cls⼦系统:该⼦系统提供对⽹络带宽的访问限制,⽐如对发送带宽和接收带宽进程限制

运⾏⼀个docker容器,查看容器的cgroup 和 linux namespace

docker pull nginx
docker run -p 80:80 -d nginx

cd /sys/fs/cgroup //查看cgroup ⼦系统变化 并找到其对应的PID
cd /proc/{PID}/ns //查看命名空间

ps -ef | grep nginx

例如ps -ef |grep nginx可以看到有哪些nginx进程

[root@localhost cpu]# ps -ef| grep nginx
root     14976 14953  0 13:59 ?        00:00:00 nginx: master process nginx -g daemon off;
101      15010 14976  0 13:59 ?        00:00:00 nginx: worker process
101      15011 14976  0 13:59 ?        00:00:00 nginx: worker process

可以看到worker由master fork出来,那么看master是父进程是哪个,其实就是docker containerd shim 进程。

docker containerd shim 进程在宿主机中进程树大概是下面这样。属于docker进程组

在这里插入图片描述

现在可以查看docker containerd shim 和 nginx master 和worker 的命名空间

#docker containerd shim 进程的ns
ll /proc/14953/ns
lrwxrwxrwx. 1 root root 0 Dec 12 14:10 cgroup -> cgroup:[4026531835]
lrwxrwxrwx. 1 root root 0 Dec 12 14:10 ipc -> ipc:[4026531839]
lrwxrwxrwx. 1 root root 0 Dec 12 14:10 mnt -> mnt:[4026531840]
lrwxrwxrwx. 1 root root 0 Dec 12 14:10 net -> net:[4026531992]
lrwxrwxrwx. 1 root root 0 Dec 12 14:10 pid -> pid:[4026531836]
lrwxrwxrwx. 1 root root 0 Dec 12 14:10 pid_for_children -> pid:[4026531836]
lrwxrwxrwx. 1 root root 0 Dec 12 14:10 time -> time:[4026531834]
lrwxrwxrwx. 1 root root 0 Dec 12 14:10 time_for_children -> time:[4026531834]
lrwxrwxrwx. 1 root root 0 Dec 12 14:10 user -> user:[4026531837]
lrwxrwxrwx. 1 root root 0 Dec 12 14:10 uts -> uts:[4026531838]

ll /proc/14976/ns
#nginx master进程
lrwxrwxrwx. 1 root root 0 Dec 12 14:12 cgroup -> cgroup:[4026531835]
lrwxrwxrwx. 1 root root 0 Dec 12 14:12 ipc -> ipc:[4026532397]
lrwxrwxrwx. 1 root root 0 Dec 12 13:59 mnt -> mnt:[4026532395]
lrwxrwxrwx. 1 root root 0 Dec 12 13:59 net -> net:[4026532400]
lrwxrwxrwx. 1 root root 0 Dec 12 14:12 pid -> pid:[4026532398]
lrwxrwxrwx. 1 root root 0 Dec 12 14:12 pid_for_children -> pid:[4026532398]
lrwxrwxrwx. 1 root root 0 Dec 12 14:12 time -> time:[4026531834]
lrwxrwxrwx. 1 root root 0 Dec 12 14:12 time_for_children -> time:[4026531834]
lrwxrwxrwx. 1 root root 0 Dec 12 14:12 user -> user:[4026531837]
lrwxrwxrwx. 1 root root 0 Dec 12 14:12 uts -> uts:[4026532396]

#nginx worker进程
ll /proc/15010/ns
lrwxrwxrwx. 1 101 101 0 Dec 12 14:12 cgroup -> cgroup:[4026531835]
lrwxrwxrwx. 1 101 101 0 Dec 12 14:12 ipc -> ipc:[4026532397]
lrwxrwxrwx. 1 101 101 0 Dec 12 14:12 mnt -> mnt:[4026532395]
lrwxrwxrwx. 1 101 101 0 Dec 12 14:12 net -> net:[4026532400]
lrwxrwxrwx. 1 101 101 0 Dec 12 14:12 pid -> pid:[4026532398]
lrwxrwxrwx. 1 101 101 0 Dec 12 14:12 pid_for_children -> pid:[4026532398]
lrwxrwxrwx. 1 101 101 0 Dec 12 14:12 time -> time:[4026531834]
lrwxrwxrwx. 1 101 101 0 Dec 12 14:12 time_for_children -> time:[4026531834]
lrwxrwxrwx. 1 101 101 0 Dec 12 14:12 user -> user:[4026531837]
lrwxrwxrwx. 1 101 101 0 Dec 12 14:12 uts -> uts:[4026532396]

不难发现,worker和master的ns是一样的,而与docker containerd shim 进程 ns是不一样的。虽然都在宿主机中运行,但是由于ns不同,他们两个是隔离的。

同时可以在子系统下,根据对应pid查看其资源分配情况。不过docker需要手动限制,或者docker run启动的时候限制

docker run --memory 64m  -p 80:80 -d  nginx
# 查看对应资源分配
sudo cat /sys/fs/cgroup/memory/docker/<container_id or container_name>/memory.limit_in_bytes

不过笔者的cgroup下却没有docker目录,这个暂时还不知道为啥。查了一下可能是Docker 配置使用了不同的 cgroup 驱动程序。所以路径也有所不同。

查看容器详细信息,在里面也没发现cgroup路径,无奈只能进容器里看了。

docker inspect  b5ce5ac1e4ae
#
docker exec -it b5ce5ac1e4ae bash
cat /proc/self/cgroup
13:hugetlb:/system.slice/docker-b5ce5ac1e4ae9b644fc8950eb8293077878a47b198c3a468738062d425fee312.scope
12:cpuset:/system.slice/docker-b5ce5ac1e4ae9b644fc8950eb8293077878a47b198c3a468738062d425fee312.scope
11:memory:/system.slice/docker-b5ce5ac1e4ae9b644fc8950eb8293077878a47b198c3a468738062d425fee312.scope
10:freezer:/system.slice/docker-b5ce5ac1e4ae9b644fc8950eb8293077878a47b198c3a468738062d425fee312.scope
9:blkio:/system.slice/docker-b5ce5ac1e4ae9b644fc8950eb8293077878a47b198c3a468738062d425fee312.scope
8:devices:/system.slice/docker-b5ce5ac1e4ae9b644fc8950eb8293077878a47b198c3a468738062d425fee312.scope
7:rdma:/
6:cpu,cpuacct:/system.slice/docker-b5ce5ac1e4ae9b644fc8950eb8293077878a47b198c3a468738062d425fee312.scope
5:pids:/system.slice/docker-b5ce5ac1e4ae9b644fc8950eb8293077878a47b198c3a468738062d425fee312.scope
4:misc:/
3:net_cls,net_prio:/system.slice/docker-b5ce5ac1e4ae9b644fc8950eb8293077878a47b198c3a468738062d425fee312.scope
2:perf_event:/system.slice/docker-b5ce5ac1e4ae9b644fc8950eb8293077878a47b198c3a468738062d425fee312.scope

# 这里就可以看到挂载了哪些进来。 这些地方是读写层,那么可以在对应宿主机(只读层)去查看即可,或者直接在docker里查看
# 退出来
cd /sys/fs/cgroup/memory/system.slice/docker-b5ce5ac1e4ae9b644fc8950eb8293077878a47b198c3a468738062d425fee312.scope

[root@localhost docker-b5ce5ac1e4ae9b644fc8950eb8293077878a47b198c3a468738062d425fee312.scope]# ls
cgroup.clone_children  memory.kmem.failcnt             memory.kmem.tcp.limit_in_bytes      memory.max_usage_in_bytes        memory.move_charge_at_immigrate  memory.stat            tasks
cgroup.event_control   memory.kmem.limit_in_bytes      memory.kmem.tcp.max_usage_in_bytes  memory.memsw.failcnt             memory.numa_stat                 memory.swappiness
cgroup.procs           memory.kmem.max_usage_in_bytes  memory.kmem.tcp.usage_in_bytes      memory.memsw.limit_in_bytes      memory.oom_control               memory.usage_in_bytes
memory.failcnt         memory.kmem.slabinfo            memory.kmem.usage_in_bytes          memory.memsw.max_usage_in_bytes  memory.pressure_level            memory.use_hierarchy
memory.force_empty     memory.kmem.tcp.failcnt         memory.limit_in_bytes               memory.memsw.usage_in_bytes      memory.soft_limit_in_bytes       notify_on_release
[root@localhost docker-b5ce5ac1e4ae9b644fc8950eb8293077878a47b198c3a468738062d425fee312.scope]# cat memory.max_usage_in_bytes
14090240
[root@localhost docker-b5ce5ac1e4ae9b644fc8950eb8293077878a47b198c3a468738062d425fee312.scope]# cat memory.limit_in_bytes
67108864



正好是64m

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

论文阅读:MonetDB/X100: Hyper-Pipelining Query Execution

目录 Abstract 1 Introduction 1.1 Outline 2 How CPU Work Abstract 在决策支持、OLAP和多媒体检索等计算密集型应用领域&#xff0c;数据库系统往往只能在现代cpu上实现较低的IPC(每周期指令)效率。本文首先以TPC-H基准为重点&#xff0c;深入研究了这种情况发生的原因。…

Debian 系统镜像下载

最近在看一些网络相关的文章需要用到 debian 11.x 的系统网上找了好多都发下载&#xff0c;在官网看一下 有个 11.8 的版本我无法下载&#xff0c;提示被最新的 debian-12.4.0 所代替&#xff0c;于是找到了这个链接 Index of /cdimage/unofficial/non-free/cd-including-fi…

计算机毕业设计 基于Web的城市旅游网站的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

【已解决】ModuleNotFoundError: No module named ‘tensorflow‘

问题描述 Traceback (most recent call last): File "dataset_tool.py", line 16, in <module> import tensorflow as tf ModuleNotFoundError: No module named tensorflow 如果直接pip install tensorflow&#xff0c;还会报错 解决办法 方法一 pip i…

MSF学习

之前的渗透测试中 其实很少用到 cs msf 但是在实际内网的时候 可以发现 msf cs 都是很好用的 所以现在我来学习一下 msf的使用方法 kali自带msf https://www.cnblogs.com/bmjoker/p/10051014.html 使用 msfconsole 启动即可 首先就是最正常的木马生成 所以这里其实只需…

hive聚合函数之JOIN原理及案例

1.数据准备 原始数据 创建dept.txt文件&#xff0c;并赋值如下内容&#xff0c;上传HDFS。 部门编号 部门名称 部门位置id 10 行政部 1700 20 财务部 1800 30 教学部 1900 40 销售部 1700创建emp.txt文件&#xff0c;并赋值如下内容&#xff0c;上传HDFS。 员工编号 姓名 岗…

es6学习(一):变量声明的方式对比:var,let,const

前言 在let和const出现之前,js可以使用var为变量命令,如果是函数也可以用function命名,甚至你可以直接不用任何关键字命名 var a 1function fn() { }b 2console.log(a)console.log(fn)console.log(b) 结果如下 var的特性 1.window环境下,var在最外层定义的变量会直接赋值给…

jmeter配置使用(mac)

前言 这篇文件就是一个笔记&#xff0c;非mac用户不用看了&#xff0c;我这是换了mac&#xff0c;要用jmeter的倒腾。 一、下载 二、使用步骤 1.解压 tgz格式的直接用tar命令就行 tar -zxvf 包名2.启动 一种是进入解压包的bin目录启动 这种方式启动的就是命令框不能关闭&am…

解决GateWay报错:Exceeded limit on max bytes to buffer : 262144

场景&#xff1a; 前端传来了一个大的字符串 发现请求不通 一番调试发现SpringGateway 默认内存缓冲区262144字节 网上查了很多种常见的解决方案无效之后 直接重写底层 网友的解决方案 方案1&#xff08;无效&#xff09; 直接修改缓冲区大小 spring:codec:max-in-memory-s…

GeoTrust OV证书

当谈到网站安全性和可信度时&#xff0c;GeoTrust OV证书是一个备受推崇的选择。作为一家备受尊敬的数字证书颁发机构&#xff0c;GeoTrust以其卓越的品牌声誉和高质量的产品而闻名于世。GeoTrust OV证书提供了一系列的安全功能&#xff0c;同时还具有出色的性价比&#xff0c;…

Axure元件库的使用

1.基本元件库 1.1Axure的画布范围 Axure是一个绘制项目原型图的软件&#xff0c;它里面的基本原件有&#xff1a; 1.1元件的呈现范围 首先我们要了解基本元件的作用范围在哪里&#xff1f; 浏览效果&#xff1a; 可以看出当我们的基本元件放在画布区域内是可以完全呈现出来…

mac安装pnpm与使用

1、什么是pnpm&#xff1f; pnpm 全称 performant npm&#xff0c;意思是高性能的 npm。pnpm 由 npm/yarn 衍生而来&#xff0c;解决了 npm/yarn 内部潜在的 bug&#xff0c;极大的优化了性能&#xff0c;扩展了使用场景。被誉为 “最先进的包管理工具”。 2、pnpm特点 速度…

2024上海智慧城市展会(世亚智博会)促进长三角地区智慧城市发展

上海市政府近期印发的《上海市进一步推进新型基础设施建设行动方案(2023-2026年)》标志着新一轮新基建的全面启动。市政府副秘书长、市发展改革委主任顾军指出&#xff0c;这一行动方案紧抓智能算力、大模型、数据要素、区块链、机器人等技术发展趋势和绿色低碳节能要求&#x…

textarea 网页文本框在光标处添加内容

在前端研发中我们经常需要使用脚本在文本框中插入内容。如果产品要求不能直接插入开始或者尾部&#xff0c;而是要插入到光标位置&#xff0c;此时我们就需要获取光标/光标选中的位置。 很多时候&#xff0c;我在格式化文本处需要选择选项&#xff0c;将选择的信息输入到光标位…

共建开源新里程:北京航空航天大学OpenHarmony技术俱乐部正式揭牌成立

12月11日,由OpenAtom OpenHarmony(以下简称“OpenHarmony”)项目群技术指导委员会(以下简称“TSC”)和北京航空航天大学共同举办的“OpenHarmony软件工程研讨会暨北京航空航天大学OpenHarmony技术俱乐部成立仪式”在京圆满落幕。 现场大合影 活动当天,多位重量级嘉宾出席了此次…

I2C总线通信(温湿度实验)

1.使能GPIOF时钟 2.将PF14设置为输出&#xff0c;PF15也可以先设置为输出 3.设置输出速度最高档位速度 4.SI7006的初始化 5.读取温度、湿度 6.将读取到的温度湿度数据通过计算公式进行转换 7.将结果输出 main.c #include "si7006.h"extern void printf(cons…

【python笔记】requests模块基础总结

前言 菜某笔记总结&#xff0c;如有错误请指正。&#xff08;抱歉可能我用渗透的靶场做的功能演示&#xff0c;让单纯想看爬虫整理的朋友不好理解&#xff0c;主要看一下requests库的写法吧&#xff0c;关于sql靶场&#xff0c;文件上传靶场什么的都当做网站的名字吧&#xff…

YashanDB携手深智城集团联合发布智慧城市解决方案

近日&#xff0c;在YashanDB 2023年度发布会上&#xff0c;深圳计算科学研究院携手深圳市智慧城市科技发展集团有限公司&#xff08;简称“深智城集团”&#xff09;重磅推出基于崖山数据库YashanDB的智慧城市解决方案&#xff0c;该联合解决方案高效支撑了深圳市CIM平台的建设…

020 OpenCV 轮廓、外接圆、外接矩形

一、环境 本文使用环境为&#xff1a; Windows10Python 3.9.17opencv-python 4.8.0.74 二、原理 2.1 函数接口 OpenCV中的findContours函数用于检测图像中的轮廓。轮廓是图像中连续的点集&#xff0c;它们通常表示物体的边缘或形状。在计算机视觉和图像处理中&#xff0c;…

PyCharm控制台堆栈乱码问题解决

目录 1、问题描述2、问题原因3、问题解决 1、问题描述 PyCharm环境都已经配置成了UTF-8编码&#xff0c;控制台打印中文也不会出现乱码&#xff0c;但报错堆栈信息中如果有中文会出现中文乱码&#xff1a; 这种该怎么解决呢&#xff1f; 2、问题原因 未将PyCharm编码环境与项目…