容器核心技术之Namespace与Cgroup

2023-09-18 20:47:47

        容器是一种流行的虚拟化技术,它允许我们在同一台计算机上与其他进程在独立环境中运行进程。那么容器是如何做到这一点的呢?为此,容器是从 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 🐾

更多推荐

职业了解|03师范生的编制教师之路

“初闻不解曲中意,再闻已是曲中人”。每个行业有一个共性在于,外面的人想进去,里面的人想出来。时代变化,不同的行业的细则也在变化。十五年前,有谁会预计计算机会这么火爆呢?估计大概率只会被认为计算机属于不务正业。而现在,宇宙的尽头是编制。但编制是否真的十全十美呢?本文讲述一个小学在编教师的心声。1、为什么想到读师范生我高考

基于CNN-LSTM的时序预测MATLAB实战

一、算法原理1.1CNN原理卷积神经网络具有局部连接、权值共享和空间相关等特性。卷积神经网络结构包含卷积层、激活层和池化层。(a)二维卷积层将滑动卷积滤波器应用于输入。该层通过沿输入垂直和水平方向移动滤波器对输入进行卷积,并计算权重与输入的点积,然后加入一个偏置项。具体表达式为:卷积层的功能是对输入数据进行特征提取。其

基于R语言APSIM模型进阶应用与参数优化、批量模拟实践技术

APSIM(AgriculturalProductionSystemssIMulator)模型是世界知名的作物生长模拟模型之一。APSIM模型有Classic和NextGeneration两个系列模型,能模拟几十种农作物、牧草和树木的土壤-植物-大气过程,被广泛应用于精细农业、水肥管理、气候变化、粮食安全、土壤碳周转、

Nvme Spec 第一章节学习

@NvmeExpressBaseSpecification第一章简介1.1概述NVMExpressTM(NVMeTM)接口允许主机软件与非易失性存储器子系统通信。此接口针对企业和客户端固态驱动器进行了优化,通常作为寄存器级接口连接到PCIExpress接口。注:在开发过程中,本规范被称为企业NVMHCI。然而,在完成之

YOLOv8『小目标』检测指南

前言目前博主课题组在进行物体部件的异常检测项目,项目中需要先使用YOLOv8进行目标检测,然后进行图像切割,最后采用WinCLIP模型进行部件异常检测但是在实际操作过程中出现问题,YOLOv8模型目标检测在大目标精确度不错,但是在小目标检测中效果极差我们之前的解决方案是扩大异常部件的目标检测范围,易于检测。但是缺点是会

stable diffusion在建筑行业应用

AI建筑研究室-帆哥投稿视频-AI建筑研究室-帆哥视频分享-哔哩哔哩视频点击观看AI建筑研究室-帆哥的全部投稿视频,在这里可以查看AI建筑研究室-帆哥最新发布、最多播放和最多收藏的视频。https://space.bilibili.com/2161614/videoHD▎ChatGPT接入自研AI工具集,为设计生产赋能

wkeOnDownload2与mbOnDownloadInBlinkThread

背景:最近开始实习(打工)生涯。需求:使用miniblink,显示网页,点击下载链接,可以实现下载。寻求大佬帮助,得到了wke.h版本的下载相关的代码。这里进行一些简单的分析:实际语句:wkeOnDownload2(webView,onDownloadCallback,nullptr);通过调用该函数实现:点击链接,实

SpringMVC之自定义注解

目录前言一、自定义注解1.Java注解简介2.注解的用处3.为什么要用注解4.自定义注解的应用场景5.注解的分类6.如何定义并使用自定义注解7.自定义注解三种使用案例案例一:案例二:案例三:二、Aop自定义注解的应用1.自定义注解类2.切面类3.Controller层前言随着Web开发的发展,越来越多的企业开始使用Sp

基于springboot+vue的便利店信息管理系统

博主主页:猫头鹰源码博主简介:Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万+、专注Java技术领域和毕业设计项目实战主要内容:毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询文末联系获取项目介绍:本系统适合选题:便利店、便利店管理、商店管理等。系统采用springb

C++之operator()和构造函数区别与总结(二百三十)

简介:CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀人生格言:人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.更多原创,欢迎关注:Android系统攻城狮1.前言本篇目的:理解C+

MYSQL--事务

目录一、事物的概念:二、事务的ACID特点:1.原子性:2.一致性:3.隔离性:4.持久性:三、隔离性:1.事务之间的相互影响:(1)脏读:(2)不可重复读:(3)幻读:(4)丢失更新:2.Mysql的隔离级别:3.隔离级别作用范围:四、事务控制语句:1.commit提交事务:2.ROLLBACK回滚:3.使用回滚点:

热文推荐