前言
在使用容器时(未被Kubernetes进行管理的情况下),我们单台主机上可能会跑几十个容器,容器虽然都相互隔离,但是用的却是与宿主机相同的内核,CPU、内存、磁盘等硬件资源。注:容器没有内核。默认情况下,容器没有资源限制,可以使用主机内核调度程序允许的尽可能多的给定资源;如果不对容器资源进行限制,容器之间就会相互影响,一些占用硬件资源较高的容器会吞噬掉所有的硬件资源,从而导致其它容器无硬件资源可用,发生停服状态。Docker提供了限制内存,CPU或磁盘IO的方法, 可以对容器所占用的硬件资源大小以及多少进行限制,我们在使用docker create创建一个容器或者docker run运行一个容器的时候就可以来对此容器的硬件资源做限制。
Docker核心
Docker分别使用Namespace和CGroup实现了对容器的资源隔离和资源限制,本文将会讲到怎么使用内核来调用CGroup对容器资源做限制。
OOM介绍
out of memorty
OOM:out of memorty的简称,称之为内存溢出
1.如果内存耗尽,内存将无法给予内存空间,内核检测到没有足够的内存来执行重要的系统功能,它会抛出OOM或Out of Memory异常,内存将会溢出,随之会有选择性的杀死相应的进程。
2.内存属于不可压缩性资源,如果执行这个进程的内存不够使用,这个进程它就会一直申请内存资源,直到内存溢出。
3.CPU属于可压缩性资源,所以CPU并不会出现这种情况,例如一个进程占用了一个核心100%的CPU,那么原本这个进程是需要占用200%的CPU资源,如果其它进程所占用的CPU核心并不需要多高的CPU频率,那么此进程就会占用掉空闲的CPU,如果其它进程也需要他自己核心的CPU频率,那么此进程就只能使用对它自己所使用CPU核心100%,因此叫做可压缩。
4.内存的有选择性:为什么不是杀死占用内存最高的进程呢?举个例子:例如我们运行了一个MySQL和一个Tomcat;这个MySQL原本是需要占用2G的内存资源,但他占用了1.9G;而Tomcat原本是需要占用500M的内存空间,可他占用了1G内存空间,这个时候当内存报异常OOM的时候,就会选择Tomcat进程进行发送kill -9的信号,进行杀死以释放内存。
5.当我们的一个重要的进程占用的内存超标而导致内存OOM的情况下,我们不希望内核来Kill掉我们这个进程,怎么办?我们可以调整内存OOM后kill进程的优先级,优先级越高越优先杀死,则反之 为此,Docker特地调整了docker daemon的OOM优先级,以免它被内核的杀死,但容器的优先级并未被调整
导致内存OOM
1.加载对象过大;
2.相应资源过多,来不及加载;