在 Linux中,Namespace 和 Cgroups 是如何实现资源隔离?

系统 开发
Linux 内核提供了多种机制来实现系统资源的隔离和管理,这篇文章,我们来详细分析两种关键的技术:Namespace 和 Cgroups。

Linux 内核提供了多种机制来实现系统资源的隔离和管理,这篇文章,我们来详细分析两种关键的技术:Namespace 和 Cgroups。

一、Namespace 详解

Namespace(命名空间,也称名称空间)是 Linux 内核用于隔离系统资源,使得不同的进程组可以拥有各自独立的资源视图。Namespace 的核心思想是通过将系统资源划分为不同的命名空间,进而实现资源的隔离。

Namespace通常包含以下几种类型:

  • PID Namespace
  • Mount Namespace
  • UTS Namespace
  • IPC Namespace
  • Network Namespace
  • User Namespace

1. PID Namespace

PID Namespace 用于隔离进程 ID 空间。每个 PID Namespace 都有自己独立的进程 ID 号,父 Namespace 可以查看和管理子 Namespace 中的进程,但反之则不行。这种机制使得在容器中运行的进程可以拥有从 1 开始的 PID。

# 创建新的 PID Namespace 并运行一个 Bash 进程
unshare -p -f --mount-proc bash
  • 1.
  • 2.

2. Mount Namespace

Mount Namespace 用于隔离挂载点。不同的 Mount Namespace 可以拥有各自独立的文件系统视图。这样一来,在一个 Namespace 中对文件系统的修改不会影响到其他 Namespace。

# 创建新的 Mount Namespace 并运行一个 Bash 进程
unshare -m bash
  • 1.
  • 2.

3. UTS Namespace

UTS (UNIX Time-Sharing) Namespace 用于隔离主机名和域名。不同的 UTS Namespace 可以拥有不同的主机名和域名,这对于容器化应用非常有用。

# 创建新的 UTS Namespace 并运行一个 Bash 进程
unshare -u bash
hostname new_hostname
  • 1.
  • 2.
  • 3.

4. IPC Namespace

IPC (Inter-Process Communication) Namespace 用于隔离进程间通信资源,如消息队列、信号量和共享内存。不同的 IPC Namespace 之间的通信资源是隔离的。

# 创建新的 IPC Namespace 并运行一个 Bash 进程
unshare -i bash
  • 1.
  • 2.

5. Network Namespace

Network Namespace 用于隔离网络资源,如网络接口、路由表、防火墙规则等。每个 Network Namespace 可以拥有独立的网络设备和配置。

# 创建新的 Network Namespace 并运行一个 Bash 进程
ip netns add mynamespace
ip netns exec mynamespace bash
  • 1.
  • 2.
  • 3.

6. User Namespace

User Namespace 用于隔离用户和用户组 ID。它允许在不同的 Namespace 中使用相同的用户 ID,但这些 ID 在不同的 Namespace 中是独立的。这样一来,即使在容器中运行的进程以 root 身份运行,也不会拥有对宿主系统的 root 权限。

# 创建新的 User Namespace 并运行一个 Bash 进程
unshare -U bash
  • 1.
  • 2.

7. 无法被 Namespace

尽管 Linux的 Namespace机制提供了对多种系统资源的隔离,但并不是所有的系统资源都能被 Namespace隔离,以下是一些不能被 Namespace隔离的资源及其原因:

  • 内核模块: 内核模块(Kernel Modules)在整个系统中是全局共享的。加载或卸载一个内核模块会影响到所有Namespace中的进程。
  • 内核参数: 通过sysctl命令设置的内核参数(如/proc/sys下的参数)是全局的,无法在不同的Namespace中进行独立设置。
  • 硬件资源:硬件资源是物理存在的,无法通过软件机制进行隔离。
  • CPU:尽管Cgroups可以对CPU资源进行分配和限制,但CPU本身是一个物理资源,无法在不同的Namespace中进行隔离。
  • 内存:Cgroups可以对内存资源进行分配和限制,但物理内存本身无法在不同的Namespace中进行隔离。
  • 磁盘:磁盘设备是物理存在的,无法在不同的Namespace中进行隔离。尽管可以通过Cgroups对磁盘I/O进行限制,但磁盘设备本身是共享的。
  • 时间:系统时间(如系统时钟和硬件时钟)在整个系统中是共享的,无法在不同的Namespace中进行独立设置。
  • 安全机制:一些系统级的安全机制无法在不同的Namespace中进行隔离。
  • SELinux:SELinux(Security-Enhanced Linux)是一种安全模块,它的策略在整个系统中是全局的,无法在不同的Namespace中进行独立设置。
  • AppArmor:类似于SELinux,AppArmor也是一种安全机制,它的配置和策略在整个系统中是全局的。
  • 系统日志:系统日志(如/var/log下的日志文件)在整个系统中是共享的,无法在不同的Namespace中进行独立管理。
  • 特殊设备文件:一些特殊的设备文件(如/dev下的某些设备文件)在不同的Namespace中是共享的,无法进行隔离。例如,/dev/null、/dev/zero等设备文件在整个系统中是全局的。

二、Cgroups 详解

1. 什么是Cgroups?

Cgroups (Control Groups,控制组)是 Linux 内核的一个特性,用于限制、记录和隔离一组进程的资源使用(CPU、内存、磁盘 I/O、网络等)。

Cgroups 通过将进程分组,然后对这些组应用资源限制来工作,核心组件包括:

  • Subsystem: 资源控制的具体实现,如 CPU、内存等。
  • Hierarchy: Subsystem 的组织结构,类似于文件系统的层级结构。
  • Cgroup: Hierarchy 中的一个节点,代表一组进程。

2. Cgroups 的子系统

Cgroups 支持多种子系统,每种子系统负责不同的资源控制:

  • cpu: 控制 CPU 资源的分配。
  • cpuacct: 提供 CPU 资源使用的统计信息。
  • memory: 控制内存资源的分配和使用。
  • blkio: 控制块设备的 I/O 操作。
  • net_cls: 控制网络资源的分类。
  • devices: 控制设备的访问权限。
  • freezer: 暂停和恢复进程。

3. 创建和管理 Cgroups

通过命令行工具 cgcreate、cgset 和 cgexec 可以方便地创建和管理 Cgroups。

# 创建一个新的 Cgroup
cgcreate -g cpu,memory:/mygroup

# 设置 CPU 使用限制
cgset -r cpu.shares=512 mygroup

# 设置内存使用限制
cgset -r memory.limit_in_bytes=256M mygroup

# 将一个进程加入到 Cgroup
cgexec -g cpu,memory:mygroup /bin/bash
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

4. Cgroups v2

Cgroups v2 是 Cgroups 的第二个版本,提供了更为统一和简化的接口。Cgroups v2 的主要特点包括:

  • 统一的层级结构,所有子系统共享同一个层级。
  • 更为简化的配置接口,减少了配置的复杂性。
  • 提高了资源控制的精度和灵活性。
# 挂载 Cgroups v2
mount -t cgroup2 none /sys/fs/cgroup

# 创建一个新的 Cgroup
mkdir /sys/fs/cgroup/mygroup

# 设置 CPU 使用限制
echo 50000 > /sys/fs/cgroup/mygroup/cpu.max

# 设置内存使用限制
echo 256M > /sys/fs/cgroup/mygroup/memory.max

# 将一个进程加入到 Cgroup
echo $$ > /sys/fs/cgroup/mygroup/cgroup.procs
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

三、Namespace 和 Cgroups 的结合

Namespace 和 Cgroups 的结合使用是容器技术的基础,Namespace 提供了进程级别的隔离,而 Cgroups 则用于资源的分配和限制,通过这两种机制,可以创建高效且安全的容器化环境。

容器的创建

以下是一个简单的示例,展示如何使用 Namespace 和 Cgroups 创建一个容器:

# 创建新的 Namespace
unshare -p -f -m -u -i -n --mount-proc bash

# 设置主机名
hostname container

# 挂载新的文件系统
mount -t tmpfs none /tmp

# 创建新的 Cgroup
cgcreate -g cpu,memory:/container

# 设置 CPU 和内存限制
cgset -r cpu.shares=512 container
cgset -r memory.limit_in_bytes=256M container

# 将当前进程加入到 Cgroup
cgclassify -g cpu,memory:container $$
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

在上述示例中,我们首先创建了一个新的 Namespace,然后设置了主机名并挂载了新的文件系统。接着,我们创建了一个新的 Cgroup,并设置了 CPU 和内存限制。最后,我们将当前进程加入到 Cgroup。

四、总结

Namespace 和 Cgroups 是 Linux 内核提供的两种关键机制,用于实现系统资源的隔离和管理。Namespace 提供了进程级别的隔离,使得不同的进程组可以拥有各自独立的资源视图,而 Cgroups 则用于资源的分配和限制,通过将进程分组,然后对这些组应用资源限制来工作。结合使用这两种机制,可以创建高效且安全的容器化环境。

责任编辑:赵宁宁 来源: 猿java
相关推荐

2023-12-26 00:55:51

资源隔离CPU

2023-09-20 10:07:26

Linux虚拟化

2022-10-30 15:00:50

2015-06-05 10:08:27

CgroupsIaaSPaaS

2021-09-07 10:33:42

MySQL事务隔离性

2019-04-28 10:30:30

Linux操作系统Namespace

2018-06-01 10:37:26

Linux归档文件压缩文件

2021-09-16 10:21:58

topic容器容器信息

2014-01-07 14:29:14

HadoopYARN

2019-07-15 15:42:50

PythonPipx开源

2020-01-10 11:18:17

Hystrix架构系统

2019-05-22 10:43:16

Cgroups容器监控

2018-05-08 08:35:34

LinuxDocker 容器管理器

2024-04-07 00:00:00

Linux控制资源

2014-03-14 13:32:52

cgroupsLinux容器

2022-08-30 19:11:12

Docker虚拟化技术

2020-12-30 08:01:07

Java隔离加载

2019-09-24 20:07:30

Linux移动文件 命令

2022-06-27 10:25:55

Kubernetes调度CPU

2021-03-17 15:49:03

鸿蒙HarmonyOS应用
点赞
收藏

51CTO技术栈公众号