Docker的资源限制实战篇
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一.资源限制概述
默认情况下,容器没有资源限制,可以使用系统所有资源。docker 通过 docker run 配置容器的内存,cpu, 磁盘io使用量。 其中许多功能都要求您的内核支持Linux功能。 要检查支持,可以使用docker info命令。 如果内核中禁用了某项功能,您可能会在输出结尾处看到警告,如"WARNING: No swap limit support"。 对于Linux 主机,如果没有足够的内容来执行重要的系统任务,将会抛出OOM或者Out of Memory Exception(内存溢出、内存泄漏、内存异常), 随后系统会开始杀死进程以释放内存。每个进程都有可能被kill,包括Dockerd和其它的应用程序。如果重要的系统进程被Kill,会导致整个系统宕机。
内存资源限制: 产生OOM异常时,Docker尝试通过调整Docker守护程序上的OOM优先级来减轻这些风险,以便它比系统上的其他进程更不可能被杀死。 容器上的OOM优先级未调整,这使得单个容器被杀死的可能性比Docker守护程序或其他系统进程被杀死的可能性更大,不推荐通过在守护程序或容器上手动设置--oom-score-adj为极端负数,或通过在容器上设置--oom-kill-disable来绕过这些安全措施。 Docker 可以强制执行硬性内存限制,即只允许容器使用给定的内存大小。 Docker 也可以执行非硬性内存限制,即容器可以使用尽可能多的内存,除非内核检测到主机上的内存不够用了。
CPU资源限制: 一个宿主机,有几十个核心的CPU,CPU为可压缩资源,但是有成百上千的进程,那么这么多进程怎么执行的? 实时优先级:0-99 非实时优先级(nice):-20-19,对应100-139的进程优先级Linux kernel进程的调度基于CFS(Completely Fair Scheduler),完全公平调度 CPU密集型的场景:
优先级越低越好,计算密集型任务的特点是要进行大量的计算,消耗CPU资源,比如计算圆周率、对视频进行高清解码等等,全靠CPU的运算能力 IO密集型的场景:
优先级值调高点,涉及到网络、磁盘IO的任务都是IO密集型任务,这类任务的特点是CPU消耗很少,任务的大部分时间都在等待IO操作完成(因为IO的速度远远低于CPU和内存的速度),比如Web应用,高并发,数据量大的动态网站来说,数据库应该为IO密集型。 博主推荐阅读: https://docs.docker.com/config/containers/resource_constraints/
二.限制容器对内存的访问实战案例
内存限制参数: -m or --memory=: 容器可以使用的最大内存量,如果您设置此选项,则允许的最小值为4m (4兆字节)。 --memory-swap *: 容器可以使用的交换分区大小,要在设置物理内存限制的前提才能设置交换分区的限制。该参数咱们可以忽略掉,因为在K8S 1.8.3版本中(https://github.com/kubernetes/kubernetes/blob/release-1.8/CHANGELOG-1.8.md),如果你的服务器开启了swap分区就会报错,而且生产环境并不建议使用swap分区,它可能会导致你的服务响应会很慢,但你检查了所有配置均是正常的,这会让你查无可查,禁用swap分区从你我做起。 --memory-swappiness: 设置容器使用交换分区的倾向性,值越高表示越倾向于使用swap分区,范围为0-100,0为能不用就不用,100为能用就用 --kernel-memory: 容器可以使用的最大内核内存量,最小为4m,由于内核内存与用户空间内存隔离,因此无法与用户空间内存直接交换,因此内核内存不足的容器可能会阻塞宿主主机资源,这会对主机和其他容器产生副作用。生产环境中尽量不要使用这个参数,如果内存不足的情况下就直接向领导申请加内存就好。 --memory-reservation: 允许您指定小于--memory的软限制,当Docker检测到主机上的争用或内存不足时会激活该限制,如果使用--memory-reservation,则必须将其设置为低于--memory才能使其优先。 因为它是软限制,所以不能保证容器不超过限制。 --oom-kill-disable: 默认情况下,发生OOM时,kernel会杀死容器内进程,但是可以使用--oom-kill-disable参数,可以禁止oom发生在指定的容器上,即 仅在已设置-m / - memory选项的容器上禁用OOM,如果-m 参数未配置,产生OOM时,主机为了释放内存还会杀死系统进程 swap限制: --memory-swap: 只有在设置了 --memory 后才会有意义。使用Swap,可以让容器将超出限制部分的内存置换到磁盘上。WARNING:经常将内存交换到磁盘的应用程序会降低性能 不同的设置会产生不同的效果: --memory-swap: 值为正数, 那么--memory和--memory-swap都必须要设置,--memory-swap表示你能使用的内存和swap分区大小的总和,例如: --memory=300m, --memory-swap=1g, 那么该容器能够使用 300m 内存和 700m swap,即--memory是实际物理内存大小值不变,而实际的计算方式为(--memory-swap)-(--memory)=容器可用swap --memory-swap: 如果设置为0,则忽略该设置,并将该值视为未设置,即未设置交换分区。 --memory-swap: 如果等于--memory的值,并且--memory设置为正整数,容器无权访问swap即也没有设置交换分区 --memory-swap: 如果设置为unset,如果宿主机开启了swap,则实际容器的swap值为2x( --memory),即两倍于物理内存大小,但是并不准确。 --memory-swap: 如果设置为-1,如果宿主机开启了swap,则容器可以使用主机上swap的最大空间。
1>.下载专门用于测试资源限制的镜像(https://hub.docker.com/r/lorel/docker-stress-ng)
[root@docker101.yinzhengjie.org.cn ~]# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE centos-haproxy v1.8.20 1858fe05d96f 5 days ago 606MB registry latest 708bc6af7e5e 5 days ago 25.8MB tomcat-app01 v0.1 bf45c22f2d5b 5 days ago 983MB tomcat-base 8.5.50 9ff79f369094 7 days ago 968MB jdk-base 1.8.0_231 0f63a97ddc85 7 days ago 953MB centos-base 7.6.1810 b4931fd9ace2 7 days ago 551MB centos centos7.6.1810 f1cb7c7d58b7 10 months ago 202MB [root@docker101.yinzhengjie.org.cn ~]# [root@docker101.yinzhengjie.org.cn ~]# docker image pull lorel/docker-stress-ng Using default tag: latest latest: Pulling from lorel/docker-stress-ng Image docker.io/lorel/docker-stress-ng:latest uses outdated schema1 manifest format. Please upgrade to a schema2 image for better future compatibility. More information at https://docs.docker.com/registry/spec/deprecated-schema-v1/ c52e3ed763ff: Pull complete a3ed95caeb02: Pull complete 7f831269c70e: Pull complete Digest: sha256:c8776b750869e274b340f8e8eb9a7d8fb2472edd5b25ff5b7d55728bca681322 Status: Downloaded newer image for lorel/docker-stress-ng:latest docker.io/lorel/docker-stress-ng:latest [root@docker101.yinzhengjie.org.cn ~]# [root@docker101.yinzhengjie.org.cn ~]# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE centos-haproxy v1.8.20 1858fe05d96f 5 days ago 606MB registry latest 708bc6af7e5e 5 days ago 25.8MB tomcat-app01 v0.1 bf45c22f2d5b 5 days ago 983MB tomcat-base 8.5.50 9ff79f369094 7 days ago 968MB jdk-base 1.8.0_231 0f63a97ddc85 7 days ago 953MB centos-base 7.6.1810 b4931fd9ace2 7 days ago 551MB centos centos7.6.1810 f1cb7c7d58b7 10 months ago 202MB lorel/docker-stress-ng latest 1ae56ccafe55 3 years ago 8.1MB [root@docker101.yinzhengjie.org.cn ~]# [root@docker101.yinzhengjie.org.cn ~]#