容器核心技术之Namespace与Cgroup

news2024/11/25 16:39:03

        容器是一种流行的虚拟化技术,它允许我们在同一台计算机上与其他进程在独立环境中运行进程。那么容器是如何做到这一点的呢?为此,容器是从 Linux 内核的一些新功能构建的,其中两个主要功能是“namespace”和“cgroup”。

1.Namespace

1.1Namespace简介

        Namespace(命名空间)技术是一种内核级别的特性,它允许将全局系统资源隔离成独立的视图,使得在不同 Namespace 中运行的进程看到的资源是不同的。这为容器化技术提供了基础,使得多个进程或容器可以在同一台主机上独立运行而不会相互干扰。

        容器中的命名空间(Namespace)是一种用于隔离和分割不同容器之间和容器与主机操作系统之间资源的技术。命名空间是Linux内核提供的一种特性,容器技术(如Docker和Kubernetes)利用这些命名空间来实现容器的隔离和资源管理。每个命名空间都提供了一种不同类型的隔离,允许容器内的进程和资源在一个虚拟化的环境中运行,以便它们似乎独立于主机和其他容器。

对应到容器技术,为了隔离不同类型的资源,Linux 内核里面实现了以下几种不同类型的 namespace。

  • PID Namespace(进程命名空间): 这个命名空间隔离了进程ID(PID),使得容器内的进程拥有自己独立的PID空间。这意味着容器内的进程可以以1作为其PID,而不会与主机或其他容器的进程冲突。
  • Network Namespace(网络命名空间): 这个命名空间隔离了网络资源,包括网络接口、IP地址、路由表等。每个容器通常都有自己的网络命名空间,使其能够运行自己的网络栈,与其他容器隔离。
  • Mount Namespace(挂载命名空间): 每个容器都有自己的挂载命名空间,使其能够拥有独立的文件系统挂载点。这允许容器在其内部拥有自己的文件系统视图,而不会影响到主机或其他容器的文件系统。
  • UTS Namespace(UTS命名空间): UTS命名空间用于隔离主机名和域名。每个容器都可以具有自己独立的主机名,这有助于在容器中创建隔离的网络标识。
  • User Namespace(用户命名空间): 这个命名空间允许容器内的进程拥有不同于主机的用户和用户组标识。这增强了安全性,因为容器中的进程无法直接影响主机上的用户。

        通过这些命名空间,容器技术可以提供隔离、安全性和资源管理,使多个容器可以在同一主机上运行而不会相互干扰。容器编排系统(如Kubernetes)可以有效地管理多个容器,并使用这些命名空间来确保它们之间的隔离和资源控制。这有助于实现更高效和可伸缩的应用程序部署和管理。

1.2用户空间与内核空间

为了开始我们的探索,重要的是要注意,在 Linux 中,内核是程序和它们需要访问的资源之间的唯一抽象层。

每个进程进行系统调用:

由于容器是进程,它们也会进行系统调用:

内核为安全性、硬件和内部数据结构提供了抽象。例如,open系统调用通常用于获取文件处理程序并抽象文件操作。

        

如果我们用 ps 查看机器上的 nginx 进程,可以看到 master 和 worker,worker 的父进程是 master。

# ps -ef |grep nginx

root 58212 58195 0 01:43 ? 00:00:00 /bin/sh -c nginx -g "daemon off;"

root 58244 58212 0 01:43 ? 00:00:00 nginx: master process nginx -g daemon off;

33 58250 58244 0 01:43 ? 00:00:00 nginx: worker process

33 58251 58244 0 01:43 ? 00:00:05 nginx: worker process

33 58252 58244 0 01:43 ? 00:00:05 nginx: worker process

33 58253 58244 0 01:43 ? 00:00:05 nginx: worker process

在 /proc/pid/ns 里面,我们能够看到这个进程所属于的 6 种 namespace。我们拿出两个进程来,应该可以看出来,它们属于同一个 namespace。

# ls -l /proc/58212/ns 
lrwxrwxrwx 1 root root 0 Jul 16 19:19 ipc -> ipc:[4026532278]
lrwxrwxrwx 1 root root 0 Jul 16 19:19 mnt -> mnt:[4026532276]
lrwxrwxrwx 1 root root 0 Jul 16 01:43 net -> net:[4026532281]
lrwxrwxrwx 1 root root 0 Jul 16 19:19 pid -> pid:[4026532279]
lrwxrwxrwx 1 root root 0 Jul 16 19:19 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 Jul 16 19:19 uts -> uts:[4026532277]

# ls -l /proc/58253/ns 
lrwxrwxrwx 1 33 tape 0 Jul 16 19:20 ipc -> ipc:[4026532278]
lrwxrwxrwx 1 33 tape 0 Jul 16 19:20 mnt -> mnt:[4026532276]
lrwxrwxrwx 1 33 tape 0 Jul 16 19:20 net -> net:[4026532281]
lrwxrwxrwx 1 33 tape 0 Jul 16 19:20 pid -> pid:[4026532279]
lrwxrwxrwx 1 33 tape 0 Jul 16 19:20 user -> user:[4026531837]
lrwxrwxrwx 1 33 tape 0 Jul 16 19:20 uts -> uts:[4026532277]

2.Cgroup

2.1Cgroup简介

在容器技术中,控制组(Control Group,通常简称为cgroup)是一种用于资源限制、管理和隔离的 Linux 内核功能。Cgroup 允许你对容器内的资源进行精细的控制,确保容器在主机上共享的资源(如CPU、内存、磁盘I/O、网络带宽等)得到合理的分配和隔离。

首先,cgroup 定义了下面的一系列子系统,每个子系统用于控制某一类资源。

  • cpu: 这个子系统用于控制和限制 CPU 资源的分配。它可以设置容器或进程组在一段时间内可以使用的 CPU 时间比例,以及最大 CPU 时间。这使得你可以为容器分配特定的 CPU 资源,确保它们不会占用过多的处理器资源。
  • memory: memory 子系统用于控制和限制内存的使用。你可以设置容器或进程组可以使用的最大内存量,以及当内存达到限制时如何处理(如进行内存交换或终止进程)。
  • blkio: 这个子系统用于控制块设备的 I/O(包括磁盘读写)访问。你可以设置容器或进程组的磁盘 I/O 限制,以确保它们不会占用过多的磁盘带宽。
  • cpuset: cpuset 子系统用于将进程或容器绑定到特定的 CPU 和内存节点。这使得你可以将特定的任务限制在特定的 CPU 核心上运行,或者将它们限制在特定的内存区域中。
  • pids: pids 子系统用于限制进程组内的进程数量。你可以设置容器或进程组可以创建的最大进程数量。
  • net_cls 和 net_prio: 这两个子系统用于网络流量控制。net_cls 允许你标记特定的网络数据包,而 net_prio 则用于设置不同网络流量的优先级。
  • hugetlb: 这个子系统用于管理大页内存的分配和使用。
  • rdma: rdma 子系统用于控制远程直接内存访问(RDMA)资源的分配。
  • freezer: freezer 子系统用于暂停和恢复容器内的进程。

这些子系统允许你在容器内或进程组内对特定类型的资源进行精细的控制和限制。在容器编排系统(如Kubernetes)或容器管理工具(如Docker)中,这些子系统通常会被自动配置和管理,以确保容器能够在共享主机上安全、高效地运行。

2.2Cgroup的工作机制

第一步,系统初始化的时候,初始化 cgroup 的各个子系统的操作函数,分配各个子系统的数据结构。

第二步,mount cgroup 文件系统,创建文件系统的树形结构,以及操作函数。

第三步,写入 cgroup 文件,设置 cpu 或者 memory 的相关参数,这个时候文件系统的操作函数会调用到 cgroup 子系统的操作函数,从而将参数设置到 cgroup 子系统的数据结构中。

第四步,写入 tasks 文件,将进程交给某个 cgroup 进行管理,因为 tasks 文件也是一个 cgroup 文件,统一会调用文件系统的操作函数进而调用 cgroup 子系统的操作函数,将 cgroup 子系统的数据结构和进程关联起来。

第五步,对于 CPU 来讲,会修改 scheduled entity,放入相应的队列里面去,从而下次调度的时候就起作用了。对于内存的 cgroup 设定,只有在申请内存的时候才起作用。

创建cgroup

以下命令创建一个名为 v1 cgroup(您可以通过路径名格式判断)foo并将其内存限制设置为 50,000,000字节 (50 MB)。

root # mkdir -p /sys/fs/cgroup/memory/foo

root # echo 50000000 > /sys/fs/cgroup/memory/foo/memory.limit_in_bytes

现在我可以将一个进程分配给 cgroup,从而对其施加 cgroup 的内存限制。我编写了一个名为 的 shell 脚本test.sh,它打印cgroup testing tool到屏幕上,然后等待什么都不做。就我而言,这是一个持续运行的过程,直到我停止它为止。

我test.sh在后台启动,其 PID 报告为 2428。脚本生成其输出,然后通过将其 PID 通过管道传输到 cgroup 文件/sys/fs/cgroup/memory/foo/cgroup.procs ,将进程分配给 cgroup 。

root # ./test.sh &
[1] 2428
root # cgroup testing tool
root # echo 2428 > /sys/fs/cgroup/memory/foo/cgroup.procs

为了验证我的进程实际上受到我为 cgroup 定义的内存限制foo,我运行以下ps命令。该-o cgroup标志显示指定进程 (2428) 所属的 cgroup。输出确认其内存 cgroup 是foo。

为了验证我的进程实际上受到我为 cgroup 定义的内存限制foo,我运行以下ps命令。该-o cgroup标志显示指定进程 (2428) 所属的 cgroup。输出确认其内存 cgroup 是foo。我们在 /sys/fs/cgroup/ 下面能看到下面的目录结构。

drwxr-xr-x 5 root root  0 May 30 17:00 blkio
lrwxrwxrwx 1 root root 11 May 30 17:00 cpu -> cpu,cpuacct
lrwxrwxrwx 1 root root 11 May 30 17:00 cpuacct -> cpu,cpuacct
drwxr-xr-x 5 root root  0 May 30 17:00 cpu,cpuacct
drwxr-xr-x 3 root root  0 May 30 17:00 cpuset
drwxr-xr-x 5 root root  0 May 30 17:00 devices
drwxr-xr-x 3 root root  0 May 30 17:00 freezer
drwxr-xr-x 3 root root  0 May 30 17:00 hugetlb
drwxr-xr-x 5 root root  0 May 30 17:00 memory
lrwxrwxrwx 1 root root 16 May 30 17:00 net_cls -> net_cls,net_prio
drwxr-xr-x 3 root root  0 May 30 17:00 net_cls,net_prio
lrwxrwxrwx 1 root root 16 May 30 17:00 net_prio -> net_cls,net_prio
drwxr-xr-x 3 root root  0 May 30 17:00 perf_event
drwxr-xr-x 5 root root  0 May 30 17:00 pids
drwxr-xr-x 5 root root  0 May 30 17:00 systemd

3.参考资料

Deep into Container — Linux Namespaces and Cgroups: What are containers made from? | by Quân Huỳnh | FAUN — Developer Community 🐾

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

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

相关文章

IDE VS2012正则替换 并将捕获的内容放入替换的字符串中$1

场景: 我想把ESLOG_INF(("deviceName %s", deviceName));只要一对括号,即ESLOG_INF(“deviceName %s”, deviceName); 获取不想替换的内容 先用正则 ESLOG_INF\(\((.*)\)\);捕获 不想替换的内容 "deviceName %s", deviceName放…

Qt --- Day01

效果图&#xff1a; 头像的圆形未实现 单击登陆&#xff0c;触发信号与槽 enter_widget.h #ifndef ENTER_H #define ENTER_H#include <QDialog> #include<QLabel> #include<QTimer> class enter_widget : public QDialog {Q_OBJECT public:explicit enter_…

【面试题】前端应该了解的个JavaScript技巧有什么?

前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 【国庆头像】- 国庆爱国 程序员头像&#xff01;总有一款适合你&#xff01; 简介 如果你用这些技巧优化你的js码&#xff0c;它可以帮助你编写更干净、…

AUTOSAR通信篇 - CAN网络通信(五:ComM)

文章目录 模块交互EcuM交互BswM交互NvM交互CanSM交互NM交互 ComM功能Paritial Network Cluster 管理Partial Network Cluster 管理功能ComM PNC状态机在主状态COMM_PNC_NO_COMMUNICATION中PNC的行为PNC网关相关的要求 从断电进入PNC主状态COMM_PNC_NO_COMMUNICATION时在主状态C…

微软发现影响 Linux 和 macOS系统的 ncurses 库漏洞

微软在 ncurses&#xff08;new curses 的缩写&#xff09;编程库中发现了一组内存损坏漏洞&#xff0c;威胁者可利用这些漏洞在易受攻击的 Linux 和 macOS 系统上运行恶意代码。 微软威胁情报研究人员 Jonathan Bar Or、Emanuele Cozzi 和 Michael Pearse 在今天发布的一份技…

GcExcel:Java 应用创建、修改和保存 Excel 电子表格 -Crack

在 Java 应用程序中创建、修改和保存 Excel 电子表格&#xff1a; GrapeCity Documents for Excel&#xff0c;Java 版 (GcExcel) 是一个高速 Java Excel 电子表格 API 库&#xff0c;不需要依赖于 Microsoft Excel。用户可以通过 Java 应用程序以编程方式创建、编辑、导入和导…

PP-Tracking之C++部署

文章目录 概要环境fastdeploy源码编译PP-Tracking源码编译使用参考概要 PP-Tracking是基于飞桨深度学习框架的业界首个开源实时跟踪系统。针对实际业务的难点痛点,PP-Tracking内置行人车辆跟踪、跨镜头跟踪、多类别跟踪、小目标跟踪及流量计数等能力与产业应用,同时提供可视…

大数据学习1.5-单机Hadoop

1.修改主机信息 vi /etc/hosts 2.修改信息如下(这里第三位一定是自己的IP 每个人都不一样) 192.168.216.140 hadoop01 192.168.216.141 hadoop02 192.168.216.142 hadoop033.修改Hadoop配置信息-1进入配置信息文件 cd /usr/local/hadoop/hadoop-2.7.1/etc/hadoop/ 4.修改Had…

wx-open-subscribe自定义样式和按钮无效【已解决】

有一个需求&#xff0c;是在微信公众号中加下类似于小程序的的那个订阅消息弹框&#xff0c;需要用户点击允许才可以给用户推送消息。如下图 微信官方文档&#xff1a;wx-open-subscribe 官方示例如下&#xff1a; 这个代码一看也能看明白&#xff0c;<wx-open-subscribe包…

【计算机网络】——数据链路层(应用:介质访问控制)

//仅做个人复习和技术交流&#xff0c;图片取自王道考研&#xff0c;侵删 一、大纲 1、介质访问控制 信道划分介质访问控制 随机访问介质访问控制 2、局域网 3、广域网 4、数据链路层设备 二、介质访问控制 省流&#xff1a;把广播信道通过介质访问控制机制 逻辑上转换为 …

Window 10安装MySQL 5.7

1、访问如下链接进行下载&#xff1a;Mysql官方下载地址 官方地址下载的东西没有那么多病毒~。这东西见仁见智吧哈哈~。有些人不怕这个。 注意安装上面这个下面的是test 2、填写mysql的环境变量 具体操作步骤如下&#xff1a; 在桌面按下快捷键“WinR”输入“control sysdm…

JVM内存模型(JMM)

目录 一、运行时数据区域划分 ​编辑 二、线程私有的 1、程序计数器 2、虚拟机栈&#xff08;VM Stack&#xff09; 3、本地方法栈 三、线程公有的 1、堆 2、元空间 Java程序把内存控制权利交给JVM虚拟机&#xff0c;一旦出现内存泄漏和溢出方法的问题&#xff0…

Webpack使用output配置打包代码信息和自动清理打包目录

一、修改代码打包后的文件名 二、自动清理打包目录 如果我们将打包文件名修改再进行打包&#xff0c;会发现之前不同名的打包文件会进行保留 在output对象中配置clean属性可自动清理打包目录 三、指定打包文件的目录 四、指定多个打包文件文件名

爬虫 — 多线程

目录 一、多任务概念二、实现多任务方式1、多进程 &#xff08;Multiprocessing&#xff09;2、多线程&#xff08;Multithreading&#xff09;3、协程&#xff08;Coroutine&#xff09; 三、多线程执行顺序四、多线程的方法1、join()2、setDaemon()3、threading.enumerate() …

npm发布vue3自定义组件库--方法一

npm发布vue3自定义组件库 创建项目 vue create test-ui自定义组件 创建自定义组件&#xff0c;组件名称根据你的需求来&#xff0c;最好一个组件一个文件夹&#xff0c;下图是我的示例。 src/components 组件和你写页面一样&#xff0c;所谓组件就是方便实用&#xff0c;不…

Unity Bolt 实现UI拖拽功能

最近在学习使用Bolt插件实现五代码对UGUI Image元素实现拖拽。先看效果 录制_2023_09_15_17_50_45_29 下面是实现方式介绍&#xff1a; 1&#xff1a;注册RectTransformUtility 在使用Bolt插件实现UI拖拽的功能&#xff0c;需要使用 RectTransformUtility.ScreenPointToLoca…

网络安全深入学习第五课——热门框架漏洞(RCE— Apache Shiro 1.2.4反序列化漏洞)

文章目录 一、序列化和反序列化二、反序列化漏洞原理三、Apache Shiro 1.2.4反序列化漏洞1、漏洞描述&#xff1a;2、漏洞影响的版本3、Shiro反序列化漏洞原理4、工作原理&#xff1a;5、shiro反序列化的特征&#xff1a; 四、Apache Shiro 1.2.4反序列化漏洞手工复现1、使用DN…

做好制造项目管理的5个技巧

制造过程通常由不同的要素组成&#xff0c;如采购材料、与供应商合作、优化生产线效率等。制造商还需要处理库存、物流和分销。 为了确保制造项目在预算范围内按时完成&#xff0c;并且不遗漏任何环节&#xff0c;企业必须建立项目管理流程&#xff0c;以帮助改善组织流程和效…

社区版MyApps低代码平台,免费即刻拥有!

编者按&#xff1a;本文主要介绍了MyApps推出的免费社区版的优势&#xff0c;为企业数字化转型提供了解决方案。立即登录MyApps低代码平台&#xff0c;就能获取永久免费的低代码平台。 1.MyApps社区版的优势 1.1不受限制&#xff0c;畅享自由 无用户限制、无安装限制、全面应用…

使用 Charles 去修改响应信息(真实工作使用场景1)

目录 背景 理论 Breakpoint功能 Map功能 实践 原理 背景 测试过程中&#xff0c;遇到接口透传数据&#xff0c;修改请求中的值可以使用Postman来进行&#xff0c;当业务场景遇到修改响应里的值的时候&#xff0c;就需要借助Charles来进行。 以下将会阐述具体的步…