【Docker】Docker的资源限制

系统版本:RHEL9.3

一、Docker资源限制简介

Linux Cgroups 的全称是 Linux Control Group。

  • 是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。

  • 对进程进行优先级设置、审计,以及将进程挂起和恢复等操作。

Linux Cgroups 给用户暴露出来的操作接口是文件系统

  • 它以文件和目录的方式组织在操作系统的 /sys/fs/cgroup 路径下。

  • 执行此命令查看:mount -t cgroup

cpp 复制代码
[root@docker ~]# mount -t cgroup					#在rhel9中默认使用cgroup2
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)
cgroup on /sys/fs/cgroup/misc type cgroup (rw,nosuid,nodev,noexec,relatime,misc)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/rdma type cgroup (rw,nosuid,nodev,noexec,relatime,rdma)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
  • 在 /sys/fs/cgroup 下面有很多诸如 cpuset、cpu、 memory 这样的子目录,也叫子系统。

  • 在每个子系统下面,为每个容器创建一个控制组(即创建一个新目录)。

  • 控制组下面的资源文件里填上什么值,就靠用户执行 docker run 时的参数指定。

二、限制CPU的使用

2.1 限制CPU的使用量

不限制容器cpu的使用量的情况下

cpp 复制代码
# 运行一个容器
[root@docker-node1 ~]# docker run -it --rm ubuntu:latest 
root@44a15d349dfa:/# dd if=/dev/zero of=/dev/null &		# 使用dd命令占用资源
root@44a15d349dfa:/# top		# 容器内查看cpu使用量
PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                9 root      20   0    2736   1096   1008 R 100.0   0.0   0:21.14 dd   

[root@docker-node1 ~]# top		# 系统中查看cpu使用量
 PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                2609 root      20   0    2736   1096   1008 R  99.7   0.0   1:05.57 dd                                           
# 可以发现在没有限制的情况下容器将cpu的资源全部消耗了

限制cpu使用量

cpp 复制代码
[root@docker ~]# docker run  -it --rm --name test \
--cpu-period 100000 \					#设置 CPU 周期的长度,单位为微秒(通常为 100000,即 100 毫秒)
--cpu-quota 20000 ubuntu				#设置容器在一个周期内可以使用的 CPU 时间,单位也是微秒。
root@5797d76b20f5:/# dd if=/dev/zero of=/dev/null &
[1] 8
root@5797d76b20f5:/# top
top - 11:53:22 up 1 day,  1:58,  0 user,  load average: 0.00, 0.00, 0.00
Tasks:   3 total,   2 running,   1 sleeping,   0 stopped,   0 zombie
%Cpu(s):  4.4 us,  6.0 sy,  0.0 ni, 89.5 id,  0.0 wa,  0.2 hi,  0.0 si,  0.0 st
MiB Mem :   3627.1 total,    558.1 free,    899.4 used,   2471.0 buff/cache
MiB Swap:   2063.0 total,   2062.0 free,      1.0 used.   2727.7 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
      8 root      20   0    2736   1536   1536 R  20.0   0.0   0:00.92 dd			#使用cpu的百分比
      1 root      20   0    4588   3968   3456 S   0.0   0.1   0:00.03 bash
      9 root      20   0    8856   5248   3200 R   0.0   0.1   0:00.00 top
 
#在cgroup中查看docker的资源限制
[root@docker ~]# cat /sys/fs/cgroup/cpu/docker/"docker id(所要查看容器的id)"/cpu.cfs_period_us       #cpu总量划分

[root@docker ~]# cat /sys/fs/cgroup/cpu/docker/"docker id(所要查看容器的id)"/cpu.cfs_quota_us       #cpu限制

实例

cpp 复制代码
# 开启容器并限制只能使用20%的cpu算力
[root@docker-node1 ~]# docker run -it --name test --cpu-period 100000 --cpu-quota 20000 ubuntu:latest 
root@b12ac1791814:/# dd if=/dev/zero of=/dev/null &

# 主机中查看cpu使用情况
[root@docker-node1 ~]# top
 PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                               2802 root      20   0    2736   1100   1012 R  19.6   0.0   0:03.86 dd       
 
# 可以看见现在容器最多使用到20%的cpu算力了

# 查看cpu总量划分
# 注意容器一定需要是运行状态才可以在/docker目录下看到容器id
[root@docker-node1 ~]# cat /sys/fs/cgroup/cpu/docker/43646513c3eab33e4a8ca054aa42b8525259140ec46dacbf6d1ed6366dfa8378//cpu.cfs_period_us 
100000
[root@docker-node1 ~]# cat /sys/fs/cgroup/cpu/docker/43646513c3eab33e4a8ca054aa42b8525259140ec46dacbf6d1ed6366dfa8378//cpu.cfs_quota_us 
20000

2.2 限制CPU的优先级

cpp 复制代码
#关闭cpu的核心,当cpu都不空闲下才会出现争抢的情况,为了实验效果我们可以关闭cpu核心到只剩1个
root@docker ~]# echo 0 > /sys/devices/system/cpu/cpu1/online
[root@docker ~]# cat /proc/cpuinfo
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 58
model name      : Intel(R) Core(TM) i7-3770K CPU @ 3.50GHz
stepping        : 9
microcode       : 0x21
cpu MHz         : 3901.000
cache size      : 8192 KB
physical id     : 0
siblings        : 1
core id         : 0
cpu cores       : 1		##cpu核心数为1
apicid          : 0
initial apicid  : 0
fpu             : yes
fpu_exception   : yes
cpuid level     : 13
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx rdtscp lm constant_tsc arch_perfmon nopl xtopology tsc_reliable nonstop_tsc cpuid tsc_known_freq pni pclmulqdq ssse3 cx16 pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm pti ssbd ibrs ibpb stibp fsgsbase tsc_adjust smep arat md_clear flush_l1d arch_capabilities
bugs            : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs itlb_multihit srbds mmio_unknown
bogomips        : 7802.00
clflush size    : 64
cache_alignment : 64
address sizes   : 45 bits physical, 48 bits virtual
power management:

#开启容器时如果指定了cpu使用优先级,那么设定文件为
[root@docker ~]# cat /sys/fs/cgroup/cpu/docker/"docker id(所要查看容器的id)"/cpu.shares


#开启容器并限制资源
[root@docker ~]# docker run -it  --rm --cpu-shares 100 ubuntu		#设定cpu优先级,最大为1024,值越大优先级越高
root@dc066aa1a1f0:/# dd if=/dev/zero of=/dev/null &
[1] 8
root@dc066aa1a1f0:/# top
top - 12:16:56 up 1 day,  2:22,  0 user,  load average: 1.20, 0.37, 0.20
Tasks:   3 total,   2 running,   1 sleeping,   0 stopped,   0 zombie
%Cpu(s): 37.3 us, 61.4 sy,  0.0 ni,  0.0 id,  0.0 wa,  1.0 hi,  0.3 si,  0.0 st
MiB Mem :   3627.1 total,    502.5 free,    954.5 used,   2471.7 buff/cache
MiB Swap:   2063.0 total,   2062.3 free,      0.7 used.   2672.6 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
      8 root      20   0    2736   1536   1536 R   3.6   0.0   0:16.74 dd			#cpu有限制被限制
      1 root      20   0    4588   3968   3456 S   0.0   0.1   0:00.03 bash
      9 root      20   0    8856   5248   3200 R   0.0   0.1   0:00.00 top


#开启另外一个容器不限制cpu的优先级
root@17f8c9d66fde:/# dd if=/dev/zero of=/dev/null &
[1] 8
root@17f8c9d66fde:/# top
top - 12:17:55 up 1 day,  2:23,  0 user,  load average: 1.84, 0.70, 0.32
Tasks:   3 total,   2 running,   1 sleeping,   0 stopped,   0 zombie
%Cpu(s): 36.2 us, 62.1 sy,  0.0 ni,  0.0 id,  0.0 wa,  1.3 hi,  0.3 si,  0.0 st
MiB Mem :   3627.1 total,    502.3 free,    954.6 used,   2471.7 buff/cache
MiB Swap:   2063.0 total,   2062.3 free,      0.7 used.   2672.5 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
      8 root      20   0    2736   1408   1408 R  94.0   0.0   1:09.34 dd			#cpu未被限制
      1 root      20   0    4588   3968   3456 S   0.0   0.1   0:00.02 bash
      9 root      20   0    8848   5248   3200 R   0.0   0.1   0:00.01 top

实例

cpp 复制代码
# 下线多的cpu
[root@docker-node1 ~]# echo 0 > /sys/devices/system/cpu/cpu1/online 
[root@docker-node1 ~]# echo 0 > /sys/devices/system/cpu/cpu2/online 
[root@docker-node1 ~]# echo 0 > /sys/devices/system/cpu/cpu3/online 
[root@docker-node1 ~]# cat /proc/cpuinfo | grep cores
cpu cores	: 1

# 开启容器并限制cpu的优先级
[root@docker-node1 ~]# docker run -it --name test --cpu-shares 100 ubuntu:latest 
root@1cae7d65d23d:/# 
root@1cae7d65d23d:/# dd if=/dev/zero of=/dev/null &		# 开始占用cpu算力

# 查看cpu使用情况
root@1cae7d65d23d:/# top
    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
      8 root      20   0    2736   1080    992 R  99.0   0.0   0:38.71 dd		# 可见cpu被占完

# 开启另外一个不限制cpu优先级的容器
[root@docker-node1 ~]# docker run -it --name test1 ubuntu:latest 
root@d74c046e084e:/# dd if=/dev/zero of=/dev/null &		# 开始占用cpu

# 查看cpu使用情况
root@d74c046e084e:/# top 
    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
      9 root      20   0    2736   1180   1092 R  90.0   0.0   0:26.90 dd 		# 可见该处cpu占用到了90%
      
# 查看被限制优先级的容器的cpu占用情况
    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND	# 可见只能使用10%的cpu了
      8 root      20   0    2736   1080    992 R   9.0   0.0   1:42.46 dd 
      
# 如果两个都没有限制的容器均开始抢占则互相平分cpu算力,一边50%,不再

三、限制内存的使用

示例

cpp 复制代码
# 开启nginx限制内存
[root@docker-node1 ~]# docker run -d --name test --memory 200M --memory-swap 200M nginx:1.26 
07eaa4c6be323e61b11d306ffdf2b7ceb409edd3cda8b3a7655b3365753c660c

# 查看
[root@docker-node1 ~]# cat /sys/fs/cgroup/memory/docker/07eaa4c6be323e61b11d306ffdf2b7ceb409edd3cda8b3a7655b3365753c660c/memory.memsw.limit_in_bytes
209715200

# 安装检测工具
[root@docker-node1 ~]# rpm -ivh libcgroup-0.41-19.el8.x86_64.rpm
[root@docker-node1 ~]# rpm -ivh libcgroup-tools-0.41-19.el8.x86_64.rpm

# 检测
[root@docker-node1 ~]# cgexec -g memory:docker/07eaa4c6be323e61b11d306ffdf2b7ceb409edd3cda8b3a7655b3365753c660c dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=200M
已杀死

[root@docker-node1 ~]# df -h
文件系统               容量  已用  可用 已用% 挂载点
devtmpfs               4.0M     0  4.0M    0% /dev
tmpfs                  1.8G  194M  1.6G   11% /dev/shm	# /dev/shm 是 Linux 系统中(不是磁盘!),专为进程间高速共享数据设计的内存虚拟文件系统。它像一块"内存白板"------多个程序能同时读写它,速度比磁盘快千倍,但断电即消失。你向 /dev/shm 写文件时,直接存入内存的 page cache	

四、限制Docker的磁盘IO

示例

cpp 复制代码
# 创建容器并使用dd命令写入
[root@docker-node1 ~]# docker run -it --name test --rm ubuntu:latest 
root@46806e7c5239:/# dd if=/dev/zero of=/bigfile bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes (1.0 GB, 1000 MiB) copied, 3.25502 s, 322 MB/s
# 可以看见IO速度非常快

# 重新创建限制的容器并dd命令写入
[root@docker-node1 ~]# docker run -it --rm --device-write-bps /dev/sda:30M ubuntu:latest 
root@ea955e653e89:/# dd if=/dev/zero of=/bigfile bs=1M count=1000 oflag=direct 
1000+0 records in
1000+0 records out
1048576000 bytes (1.0 GB, 1000 MiB) copied, 33.3383 s, 31.5 MB/s
# 可以看见IO速度被限制
相关推荐
XDHCOM2 小时前
Docker怎么设置Redis?
redis·docker·容器
xlq223222 小时前
41.线程封装与互斥
linux·开发语言
Flying pigs~~2 小时前
检索增强生成RAG项目tools_01:Docker 极简实战
运维·人工智能·docker·容器·大模型·agent·rag
Jaygee-2 小时前
GMSSH 是什么?一款面向 AI 时代的可视化服务器运维系统
运维·服务器
赴前尘3 小时前
Linux/Unix 系统中以后台方式运行程序
linux·服务器·unix
b***25113 小时前
比斯特自动化动力电池组半自动生产线的工艺革新与效率提升
运维·自动化
打码人的日常分享4 小时前
新型智能建造解决方案
运维·人工智能·安全·系统安全·制造
默|笙4 小时前
【Linux】线程互斥与同步_同步(2)_环形队列
linux·运维·服务器