Docker | 容器资源管控

Docker | 容器资源管控

_

一、Namespace和Cgroup

1. Namespace命名空间

Linux内核实现Namespace的主要目的之一是实现轻量级虚拟化(容器)服务。再此之前,Linux中很多资源是全局管理。

命名空间建立系统的不同视图,对于每一个命名空间,从用户看起来,应该像一台单独的Linux计算机一样,有自己的init进程(PID为O),其他进程的PID依次递增,A和B空间都有PID为0的init进程。

子容器的进程映射到父容器的进程上,父容器可以知道每一个子容器的运行状态,而子容器与子容器之间是隔离的。通俗一点说,NameSpace让容器认为自己是独立系统。

想要实现一个资源隔离的容器,需要6项隔离,Linux内核提供了这6种Namespace隔离的系统调用,在同一个Namespace下的进程可以感知彼此的变化,但不了解外界的变化,因此,可以让容器中的进程以为自己在一个独立的系统环境中,达到独立和隔离的目的。Linux提供了多个API用来操作 Namespace,它们是 clone(),setns() 和 unshare()函数:

  • clone():创建新进程,flags参数可以用来创建新的namespace

  • setns():让进程加入存在的 namespace

  • unshare():将调用进程移动到新的 namespace中

Docker容器在实现上通过namespace技术实现进程隔离,通过cgroup技术实现容器进程可用资源的限制。Docker启动一个容器时,实际上是创建了带多个 namespace 参数的进程。

  • 作用:资源隔离

  • 原理:namespace 将内核的全局资源进行封装,使得每个 namespace 都有一份独立的资源。因此不同进程在各自 namespace 内对同一种资源的使用不会互相干扰。

Namespace类型

系统调用参数

隔离内容

引入的内核版本

PID

CLONE_NEWPID

进程空间(进程ID)

Linux 2.6.24

Mount

CLONE_NEWNS

文件系统挂载点

Linux 2.6.19

Network

CLONE_NEWNET

网络资源:网络设备、端口等

Linux 2.6.24开始 ~ Linux2.6.29完成

User

CLONE_NEWUSER

用户ID和用户组ID

Linux 2.6.23开始 ~ Linux3.8完成

UTS

CLONE_NEWUTS

主机名和域名

Linux 2.6.19

IPC

CLONE_NEWIPC

信号量、消息队列和共享内存

Linux 2.6.19

[Step1] 查看进程所属的Namespace。从版本号为3.8的内核开始,“/proc/[pid]/ns”目录下会包含进程所属的 namesapce 信息,使用下面的命令可以查看当前进程所属的namespace信息。

// 1046为当前系统docker的进程ID
[root@redhat ~]# ls -l /proc/1046/ns        

2. Namespace隔离实例

[Step1] 基于kylinsp3镜像创建一个容器ky01,运行/bin/bash。通过ps命令可以看到“/bin/bash”是PID=1的进程,说明Docker将隔离于宿主机中的其他进程。

[root@redhat ~]# docker run -it --name ky01 kylinsp3:latest /bin/bash
[root@e75b6402786f /]# ps axf

[Step2] 查看容器进程在宿主机上的真实PID,实际上容器上运行的/bin/bash在宿主机上是7216进程。

[root@redhat ~]# docker inspect ky01 | grep Pid

[Step3]: 分别在宿主机和容器中查看该容器进程相关的namespace信息,可以发现二者都一致。

[root@redhat ~]# ll /proc/7216/ns/
[root@redhat ~]# docker exec ky01 ls -l /proc/1/ns

3. Cgroup

Cgroup:Linux Control Group。限制一个进程组对系统资源的使用上限,包括CPU、内存、Block I/O等。Cgroups还能设置进程优先级,对进程进行挂起和恢复等操作。通俗一点说,CGroup能够让容器只使用指定资源。

  • 原理:将一组进程放进一个Cgroup中,通过给这个Cgroup分配指定的可用资源,达到控制这个一组进程可用资源的目录

  • 实现:在Linux中,Cgroups以文件和目录的方式组织在操作系统的 /sys/fs/cgroup 路径下。该路径下的所有资源种类均可被 cgroup 限制

二、CPU资源限制

1. 性能压测容器stress

[Step1] 下载容器镜像。

[root@redhat ~]# docker pull polinux/stress-ng
[root@redhat ~]# docker pull polinux/stress

2. CPU资源限制

[Step1] 能够通过相关参数对容器的可用CPU资源进行限制。

  • -c、--cpu-shares:权重值,表示该进程能使用的CPU资源权重

  • --cpus:限制使用的CPU数量

[Step2] 调整虚拟机的处理器和内核数量。

[Step3]: 创建两个终端,第一个终端用于创建stress01容器并在前台运行。第二个终端运行top命令,实时监控系统状态。

[root@redhat ~]# docker run --name stress01 -it -c 1024 polinux/stress-ng --cpu 1

[Step2]: 再新建一个终端,创建一个容器,CPU权重依然设置为1024。

[root@redhat ~]# docker run --name stress02 -it -c 1024 polinux/stress-ng --cpu 1

[Step3] 运行top命令,实时监控系统状态,可以看到两个stress-ng-cpu进程个占用约50%。

3. 内存资源限制

默认情况先,宿主机不限制容器对内存资源的使用。可以通过相关参数可以容器的可用CPU资源进行限制

  • --memory:设置内存资源的使用限额

  • --memory-swap:设置内存和SWAP资源的使用限额

[Step1]: 启动一个容器,限制其只能使用400M内存和100M交换分区

[root@redhat ~]# docker run -it -m 400M --memory-swap=500M polinux/stress-ng --vm 1 --vm-bytes 450M

4. Block IO限制

Block IO指的是磁盘的读写,可以通过三种方式限制容器读写磁盘的带宽

  • 设置相对权重

    • --blkio-weight

  • 设置bps:每秒读写的数据量

    • --device-read-bps

    • --device-write-bps

  • 设置iops:每秒IO次数

    • --device-read-iops

    • --device-write-iops


Docker | 数据持久化与跨容器共享 2026-03-21
RedHat9 | 东方通TongLink8部署与管理 2026-03-23

评论区