容器资源限制

发布时间 2024-01-06 21:09:44作者: FuShudi

资源限制

在我们使用docker跑容器的时候,但从理论上来说,只要不对容器做限制,那么他是有可能把你的物理机的计算资源给占满的,为了避免这种情况发生,所以我们可以对容器做一定的限制

内存限制

我们先通过命令查看容器占用的资源

[root@docker ~]# free -h
              total        used        free      shared  buff/cache   available
Mem:          3.8Gi       724Mi       859Mi        59Mi       2.3Gi       2.8Gi
Swap:         3.9Gi        10Mi       3.9Gi
[root@docker ~]# docker stats
CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT     MEM %     NET I/O         BLOCK I/O    PIDS
9a7eace0b2a4   nginx     0.00%     6.609MiB / 3.798GiB   0.17%     162MB / 163MB   1.7MB / 0B   3

在这里我们可以看见 cpu占用率目前是0 内存使用了6.6M,没有对内存做限制,我们物理机的内存也就是3.8G,也就是说,只要这个容器里面跑的任务足够吃内存,那么他是会将我们物理机的内存给用光的
所以我们现在来看看如何限制容器的资源

我现在启动一个centos的容器,限制他的内存最多可以使用500M
如果不知道使用什么参数可以使用 docker help run 去查看帮助

[root@docker ~]# docker run -itd --name os1 -m 500m centos:7
[root@docker ~]# docker stats os1
CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT   MEM %     NET I/O     BLOCK I/O   PIDS
af387346eb9c   os1       0.00%     1.395MiB / 500MiB   0.28%     946B / 0B   0B / 0B     1

现在我们可以看见他的内存的LIMIT变成了500m,那么如果容器的内存用超了会发生什么呢?
是会直接被停止还是不让这个容器运行其他的任务了呢,我们可以来看看

# 我们将内存限制到6M,然后我们在容器内运行一些任务来看看
[root@docker ~]# docker run -itd --name os2 -m 6m centos:7
63187fd92ff985c7ca0f531b69a4d86bb29efecb260aeba7e058846ee65a6878
[root@docker ~]# docker stats os2
CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT   MEM %     NET I/O     BLOCK I/O   PIDS
63187fd92ff9   os2       0.00%     1.398MiB / 6MiB     23.31%    656B / 0B   0B / 0B     1
# 我们现在可以看见,他的内存被限制到了6m,那么我们进入容器执行一些命令
# 我们使用dd命令,dd命令不指定direct的话他是会先将内容读到内存然后再下盘的
# 这条命令的意思是写一个5M的文件,写到/tmp/test1 然后这5M是会先读到内存里的
[root@63187fd92ff9 /]# dd if=/dev/zero of=/tmp/test1 bs=5M count=1 
1+0 records in
1+0 records out
5242880 bytes (5.2 MB) copied, 0.136385 s, 38.4 MB/s
# 我们可以发现,他是可以成功的
# 我们再来写1个10M的文件
[root@63187fd92ff9 /]# dd if=/dev/zero of=/tmp/test2 bs=10M count=1 
Killed
[root@63187fd92ff9 /]# yum install vim
Killed

我们可以发现,当他内存不够的时候,他是会直接kill掉这个任务的,并不会执行,这个容器也没有被docekr停止掉
所以结论就是当容器的内存不够的时候,那么这个容器暂时是起不了新的任务的

cpu限制

# 我们首先来使用lscpu看看cpu的信息
[root@docker ~]# lscpu 
Architecture:        x86_64
CPU op-mode(s):      32-bit, 64-bit
Byte Order:          Little Endian
CPU(s):              2
On-line CPU(s) list: 0,1
# 我们可以看见CPU(s)这里写的是2,那么说明我们的物理机是有2个cpu核心的
# 下一行的在线cpu编号是0和1
# 我们首先限制这个容器的所有任务都必须跑在cpu0上,这样可以避免频繁的cpu上下文切换
[root@docker ~]# docker run -itd --name os4 --cpuset-cpus 0 centos:7
8474df87ae10bb638712a3913cea2733ae2556f3bf3253ba47f888b7811bee52
# 我们现在进入这个容器,执行命令,然后再退出来查看
[root@docker ~]# docker exec -it os4 /bin/bash
# 这条命令并不会发生什么,但是会一直持续跑
[root@8474df87ae10 /]# cat /dev/zero > /dev/null &
[1] 28
[root@8474df87ae10 /]# cat /dev/zero > /dev/null &
[2] 29
[root@8474df87ae10 /]# cat /dev/zero > /dev/null &
[3] 30
[root@8474df87ae10 /]# cat /dev/zero > /dev/null &
[4] 31
[root@8474df87ae10 /]# jobs
[1]   Running                 cat /dev/zero > /dev/null &
[2]   Running                 cat /dev/zero > /dev/null &
[3]-  Running                 cat /dev/zero > /dev/null &
[4]+  Running                 cat /dev/zero > /dev/null &
# 我们现在使用快捷键 Ctrl+p+q退出容器,在物理机上查看这个任务是否跑在了0号cpu上
[root@docker ~]# ps mo pid,comm,psr `pgrep cat`
    PID COMMAND         PSR
 151675 cat               -
      - -                 0
 151693 cat               -
      - -                 0
 151777 cat               -
      - -                 0
 151778 cat               -
      - -                 0
# 这里显示的psr就是这个任务跑在哪个cpu上,这里全都是0,所以这个限制是生效的