docker(八):Docker资源限制

  默认状况下,一个容器是没有任何资源限制的,它可以耗尽当前主机内核可以调度给容器的全部资源,就像拥有饥饿者能力的猪头帝同样,永远吃不饱。这显然是不合理的,由于资源吃多了会被制裁的。在 linux 系统中,若是内核探测到当前主机已经没有可用的内存分配给某些重要的系统进程,它就会启动 OOM killer 或者触发 kernel panic,详情请查看另外一篇文章Linux OOM killer。OOM killer 会杀死符合条件的进程,docker daemon 也有可能会被 kill。为此 docker 调整了 docker daemon 的 OOM 优先级,可是 docker container的优先级没有被调整啊,怎么办?小场面,道友慢慢听我道来。html

  docker run 有参数来调整 docker container 的 oom_score,使之不会被干掉,且调完优先级后咱们仍然是须要限制 dockercontainer 的资源使用的,否则用完了宿主机的资源,别的系统进程就木得用了,限制资源分为 Memory 和 CPU 两块。linux

Memory Limit

  • Introductiondocker

    • 每个参数指定的值的单位能够是b/k/m/g
  • Argumentsapi

    • -m or --memoryapp

      • 限制一个容器可用的物理内存,此参数最小值为4M
    • --memory-swap *ide

      • 限制一个容器可使用交换分区的大小,此参数只有在设置了 -m 时才有意义。值有下表中的几种状况。
      • 容器中使用 free 命令看到的信息没有意义,具体还要根据表格中的方式计算。
    • --memory-swappiness函数

      • 控制进程将物理内存交换到swap分区的倾向,默认系数为60。系数越小,就越倾向于使用物理内存。取值范围为0-100。
      • 当值为0时,表示尽可能不使用swap分区。
      • 当值为100时,表示尽可能使用swap分区。
      • 若是不设置,则值从主机继承。
    • --memory-reservation性能

      • 启用弹性的内存共享,当宿主机资源充足时,容许容器尽可能多地使用内存,当检测到内存竞争或者低内存时,强制将容器的内存下降到 memory-reservation 所指定的内存大小。按照官方说法,不设置此选项时,有可能出现某些容器长时间占用大量内存,致使性能上的损失。
    • --kernel-memory测试

      • 内核内存,不会被交换到swap上。通常状况下,不建议修改。
    • --oom-kill-disableui

      • 禁止容器被 OOM killer 杀掉。前提是已经设置了-m。
-m or --memory --memory-swap 功能
正数 M 正数 N 容器的可用总空间为 N,其中物理内存为 M,swap 为 N-M;若N=M,则表示无可用 swap 资源。
正数 M 0 至关于未设置 swap。
正数 M unset 若宿主机启用了 swap,则容器的可用 swap 为 2*M。
正数 M -1 若宿主机启用了 swap,则容器可最大可以使用主机上的全部swap资源。
  • Example
# 为了防止容器不会由于OOM而被kill掉,就须要在docker run启动时加上这个参数--oom-kill-disable或者指定--oom-score-adj--oom-score-adj的值为-1000
# 为了测试出限制效果,咱们须要用到一个叫作stress的压力测试镜像。
[root@docker1 ~]# docker search stress
NAME                      DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
progrium/stress                                                           29                                      [OK]
polinux/stress            Stress tool in a Docker (Alpine) Raspberry P…   8                                       [OK]
[root@docker1 ~]# docker pull polinux/stress
# 查看命令的帮助信息,会看到有这么一条示例信息
`stress' imposes certain types of compute stress on your system

Usage: stress [OPTION [ARG]] ...
 -?, --help                显示帮助信息
     --version            显示版本号
 -v, --verbose          详细显示
 -q, --quiet               静默模式
 -n, --dry-run           显示已完成的指令状况
 -t, --timeout N        指令运行N秒后中止
     --backoff N         等待N微秒后开始运行
 -c, --cpu N              产生N个进程,每一个进程反复计算随机数的平方根
 -i, --io N                  产生N个进程,每一个进程反复调用sync()将内存中的内容写入到磁盘。
 -m, --vm N              产生N个进程,每一个进程不断分配和释放内存。
     --vm-bytes B      指定分配内存的大小,默认256M
     --vm-stride B      不断的给部份内存赋值,让COW发生。
     --vm-hang N       指定每一个消耗内存的进程在分配到内存后转入睡眠状态N秒,而后释放内存,一直重复执行这个过程。
     --vm-keep           一直占用内存,区别于不断释放并从新分配内存
 -d, --hdd N              产生N个不断执行 write 和 unlink 函数的进程(建立文件,写入内容,删除文件)
     --hdd-bytes B      指定建立的文件大小

Example: stress --cpu 8 --io 4 --vm 2 --vm-bytes 128M --timeout 10s
# 测试内存限制。-m参数指定了容器最多使用256M内存,使用stress进行压力测试,我没有指定--vm-bytes,默认256M,因此2和进程最可能是会用到512M内存。
[root@docker1 ~]# docker run --name stress -it -m 256m --rm polinux/stress:latest stress --vm 2
# 新打开窗口查看容器使用资源情况,会发现限制成功。
[root@docker1 ~]# docker stats
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
24adcc32c8cb        stress              41.63%              256MiB / 256MiB   100%              508B / 0B           303kB / 239MB       3
# 若是docker run有报以下信息,是由于stress指定分配的内存超过了docker run -m预设值的两倍。-m 指定个257m就不会自动退出了。
[root@docker1 ~]# docker run --name stress -it -m 256m --rm polinux/stress:latest stress --vm 2
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 2 vm, 0 hdd
stress: FAIL: [1] (415) <-- worker 7 got signal 9
stress: WARN: [1] (417) now reaping child worker processes
stress: FAIL: [1] (451) failed run completed in 7s

CPU Limit

  • Introduction

    • 默认状况下,每个容器均可以无限制使用宿主机上的全部CPU资源。咱们能够经过一些参数去限制它。
    • 1.13版本之前的docker只支持CFS调度器(非实时进程调度器);1.13版本以后支持Realtime调度器(实时进程调度器)。
  • Arguments

    • --cpus=<value>

      • 按照下面--cpu-shares的举例,假如是四核CPU,容器B不用,容器A就能用400%?显然不合理,因此可使用--cpus来限制容器可使用的CPU核数。例如--cpus=0.5。
    • --cpu-period=<value>

      • 限制容器最多能使用CPU多长时间,默认100微秒。1.13版本后可使用--cpus替代。
    • --cpu-quota=<value>

      • 更精细的CPU限制。1.13版本后可使用--cpus替代。
    • --cpuset-cpus

      • 限制容器只能使用哪一个CPU核心。上面使用--cpus设置容器可使用的CPU核数,但限制不了使用哪一个核心,这个使用量可能在核心1上,也多是核心2上,也多是各使用一部分。
    • --cpu-shares

      • 设置为共享式CPU,按权重的比例来分配,这是一个软限制。好比容器A权重为512,容器B权重为1024,那CPU的资源将分红三份,容器A占1/3,容器B占2/3;假如容器B用不到CPU的计算能力,那容器A将拥有CPU所有使用权。
  • Example

# 这里咱们依然使用stress来作CPU的压力测试。由于我只有一核,因此--cpu的预设值能够设置为1或者忽略此选项。
[root@docker1 ~]# cat /proc/cpuinfo| grep "processor"| wc -l
1
[root@docker1 ~]# docker run --name stress -it --cpus 1 --rm polinux/stress:latest stress --cpu 8
# 使用top命令看到有8个子进程
[root@docker1 ~]# docker top stress        
[root@docker1 ~]# docker stats
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
e8fc27bd1897        stress              99.93%              128KiB / 976.3MiB   0.01%               648B / 0B           0B / 0B             9
# 有时会稍稍超过100%,是正常的。若是是多核CPU,还能够加上--cpuset-cpus的参数来限制容器只能使用哪一个核心,好比--cpuset-cpus 0,2。限制容器只能使用第一个核心和第三个核心。还可以使用--cpu-shares来共享CPU资源,好比四核CPU,起两个容器,而后查看stats,会发现,两个容器的CPU使用量加起来在400%左右。这里就不演示了,命令以下:
[root@docker1 ~]# docker run --name stress01 -it --cpu-shares 512 --rm polinux/stress:latest stress --cpu 8
[root@docker1 ~]# docker run --name stress02 -it --cpu-shares 1024 --rm polinux/stress:latest stress --cpu 8

   

写做不易,转载请注明出处,谢谢~~

相关文章
相关标签/搜索