docker-资源限制:如何通过 Cgroups 机制实现资源限制?

简介: 我们知道使用不同的 Namespace,可以实现容器中的进程看不到别的容器的资源,但是有一个问题你是否注意到?

我们知道使用不同的 Namespace,可以实现容器中的进程看不到别的容器的资源,但是有一个问题你是否注意到?


容器内的进程仍然可以任意地使用主机的 CPU 、内存等资源,如果某一个容器使用的主机资源过多,可能导致主机的资源竞争,进而影响业务。那如果我们想限制一个容器资源的使用(如 CPU、内存等)应该如何做呢?

一、cgroups 由来


cgroups(全称:control groups)是 Linux 内核的一个功能,它可以实现限制进程或者进程组的资源(如 CPU、内存、磁盘 IO 等)。


在 2006 年,Google 的工程师( Rohit Seth 和 Paul Menage 为主要发起人) 发起了这个项目,起初项目名称并不是cgroups,而被称为进程容器(process containers)。在 2007 年cgroups代码计划合入Linux 内核,但是当时在 Linux 内核中,容器(container)这个词被广泛使用,并且拥有不同的含义。为了避免命名混乱和歧义,进程容器被重名为cgroups,并在 2008 年成功合入 Linux 2.6.24 版本中。cgroups目前已经成为 systemd、Docker、Linux Containers(LXC) 等技术的基础。

二、cgroups 功能及核心概念


2.1 功能


20210521171715623.png

2.2 核心概念


20210521171741834.png

  1. 子系统(subsystem):是一个内核的组件,一个子系统代表一类资源调度控制器。例如内存子系统可以限制内存的使用量,CPU 子系统可以限制 CPU 的使用时间。
  2. 控制组(cgroup):表示一组进程和一组带有参数的子系统的关联关系。例如,一个进程使用了 CPU 子系统来限制 CPU 的使用时间,则这个进程和 CPU 子系统的关联关系称为控制组。
  3. 层级树(hierarchy):是由一系列的控制组按照树状结构排列组成的。这种排列方式可以使得控制组拥有父子关系,子控制组默认拥有父控制组的属性,也就是子控制组会继承于父控制组。比如,系统中定义了一个控制组 c1,限制了 CPU 可以使用 1 核,然后另外一个控制组 c2 想实现既限制 CPU 使用 1 核,同时限制内存使用 2G,那么 c2 就可以直接继承 c1,无须重复定义 CPU 限制。

cgroups 的三个核心概念中,子系统是最核心的概念,因为子系统是真正实现某类资源的限制的基础。

三、cgroups 子系统实例


mount 命令查看一下当前系统已经挂载的cgroups信息:

]# mount -t cgroup

操作系统版本和内核版本如下

不同内核版本cgroups子系统和使用方式可能略有差异

20210521172213810.png

20210521172039269.png

以cpu子系统为例子

第一步:在 cpu 子系统下创建 cgroup


在相应的子系统下创建目录

# mkdir /sys/fs/cgroup/cpu/mydocker

20210521172606733.png

新建的目录下被自动创建了很多文件,其中 cpu.cfs_quota_us 文件代表在某一个阶段限制的 CPU 时间总量,单位为微秒


例如,我们想限制某个进程最多使用 1 核 CPU,就在这个文件里写入 100000(100000 代表限制 1 个核) ,tasks 文件中写入进程的 ID 即可(如果要限制多个进程 ID,在 tasks 文件中用换行符分隔即可)。


此时,我们所需要的 cgroup 就创建好了


第二步:创建进程,加入 cgroup

把当前运行的 shell 进程加入 cgroup,然后在当前 shell 运行 cpu 耗时任务(这里利用到了继承,子进程会继承父进程的 cgroup)。

第二步:创建进程,加入 cgroup


cd /sys/fs/cgroup/cpu/mydocker
 echo $$ > tasks  

20210521173030359.png

查看一下 tasks 文件内容:


其中第一个进程 ID 为当前 shell 的主进程,也就是说,当前 shell 主进程为 348

20210521173140184.png

第三步:执行 CPU 耗时任务,验证 cgroup 是否可以限制 cpu 使用时间


使用以下命令制造一个死循环,来提升 cpu 使用率:

目录
相关文章
|
1月前
|
存储 Linux 数据中心
docker的底层原理四: 资源隔离
本文详细解释了Docker利用Linux内核的Namespace和Cgroups技术实现资源隔离,包括CPU、内存、网络、存储、文件系统、进程间通信、用户和用户组以及进程ID和主机名的隔离,确保容器的独立性和系统的安全性。
44 0
|
2月前
|
存储 数据中心 Docker
Docker如何实现资源隔离?
Docker如何实现资源隔离?
47 1
|
3月前
|
缓存 Kubernetes 数据中心
在Docker中,如何控制容器占用系统资源(CPU,内存)的份额?
在Docker中,如何控制容器占用系统资源(CPU,内存)的份额?
|
6月前
|
存储 安全 数据中心
【Docker 专栏】Docker 容器与宿主机的资源隔离机制
【5月更文挑战第8天】Docker容器利用Namespace和Cgroups实现资源隔离,保证CPU、内存、网络和存储的独立,提升资源利用率和系统安全性。资源隔离有助于简化应用部署与管理,但也带来资源竞争、监控管理及安全挑战。理解并善用资源隔离机制能实现更高效、安全的容器运行。随着技术进步,Docker容器资源隔离将持续优化。
534 2
【Docker 专栏】Docker 容器与宿主机的资源隔离机制
|
6月前
|
运维 Linux Docker
Docker详解(十一)——Docker容器CPU资源限额实战Docker详解
Docker详解(十一)——Docker容器CPU资源限额实战
141 5
|
6月前
|
存储 运维 Linux
Docker详解(十)——Docker容器CPU资源限额配置
Docker详解(十)——Docker容器CPU资源限额配置
271 3
|
6月前
|
存储 网络协议 Linux
深入剖析docker核心技术(namespace、cgroups、union fs、网络)(二)
深入剖析docker核心技术(namespace、cgroups、union fs、网络)(二)
104 0
|
6月前
|
Linux 调度 虚拟化
深入剖析docker核心技术(namespace、cgroups、union fs、网络)(一)
深入剖析docker核心技术(namespace、cgroups、union fs、网络)(一)
249 0
|
3天前
|
Kubernetes Cloud Native Docker
云原生时代的容器化实践:Docker和Kubernetes入门
【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术成为企业提升敏捷性和效率的关键。本篇文章将引导读者了解如何利用Docker进行容器化打包及部署,以及Kubernetes集群管理的基础操作,帮助初学者快速入门云原生的世界。通过实际案例分析,我们将深入探讨这些技术在现代IT架构中的应用与影响。
12 2
|
5天前
|
运维 持续交付 Docker
深入理解Docker容器化技术
深入理解Docker容器化技术