Docker管理控制相关资源

一台宿主机能够放多个容器,默认的状况下,Docker 没有对容器进行硬件资源的限制,当容器负载太高时会尽量的占用宿主机资源,因此有时候咱们须要对容器的资源使用设置一个上限,这里就须要管理 Docker 使用的资源。真正能够控制的只有内存和CPU。mysql

查看宿主机资源使用状况

Docker 使用 cgroups 归类运行在容器中的进程,这就使得咱们能够管理一组进程使用的资源。运行 systemd-cgls命令 就能够查看 cgroups树 :c++

├─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
├─docker
│ ├─93d5ecbdf58ff840f737c41adff9d0f9506aac036a1fd2f0c3f31edf696ce7f1
│ │ ├─24291 mysqld
│ │ ├─29404 bash
│ │ └─29480 mysql -uroot -px xxxx
│ ├─b1f53779101af8778ba8e8dfd0946a84e8c69b3d8b0b35cd8753c46d966ffba5
│ │ ├─23893 mysqld
│ │ ├─25112 bash
│ │ └─28740 mysql -uroot -px xxxx
│ └─57aff029f6c65c6bbe0edcb3f9b61b4c3a6253bd1093d2dfc8ec318dd2cc4b9b
│   ├─23667 mysqld
│   ├─24709 bash
│   └─29649 mysql -uroot -px xxxx
......

使用 systemd-cgtop 命令能够看到使用最多资源的进程。算法

1、CPU

默认状况下,每个容器可使用宿主机上的全部 CPU 资源,但大多数系统使用的资源调度算法是CFS(彻底公平调度器),它公平调度每个工做进程。进程分CPU密集型IO密集型两类。系统内核会实时监测系统进程,当某个进程占用 CPU 资源时间过长时,内核会调整该进程的优先级。sql

参数

参数名 做用
--cpu-share cpu资源提供给一组容器使用,组内的容器按比例使用cpu资源,当容器处于空闲状态时,cpu资源被负载大的容器占用,(按压缩方式比例分配),当空闲进行运行起来时,cpu资源会被分配到其余容器
--cpus= value 指定 cpu的核心数量
--cpuset-cpus 指定容器只能运行在哪一个cpu核心上(绑定cpu);核心使用0,1,2,3编号;
–cpu-share 随机指定cpu

实例:docker

docker run -di --name=os --cpus=2 centos:latest bash

2、设置内存

默认状况下,docker 并无对容器内存进行限制,也就是说容器可使用主机提供的全部内存。这固然是很是危险的事情,若是某个容器运行了恶意的内存消耗软件,或者代码有内存泄露,极可能会致使主机内存耗尽,所以致使服务不可用。对于这种状况,docker 会设置 docker daemon 的 OOM(out of memory) 值,使其在内存不足的时候被杀死的优先级下降。另外,就是你能够为每一个容器设置内存使用的上限,一旦超过这个上限,容器会被杀死,而不是耗尽主机的内存。centos

限制内存上限虽然能保护主机,可是也可能会伤害到容器里的服务。若是为服务设置的内存上限过小,会致使服务还在正常工做的时候就被 OOM 杀死;若是设置的过大,会由于调度器算法浪费内存。所以,合理的作法包括:bash

  • 为应用作内存压力测试,理解正常业务需求下使用的内存状况,而后才能进入生产环境使用
  • 必定要限制容器的内存使用上限
  • 尽可能保证主机的资源充足,一旦经过监控发现资源不足,就进行扩容或者对容器进行迁移
  • 若是能够(内存资源充足的状况),尽可能不要使用 swap,swap 的使用会致使内存计算复杂,对调度器很是不友好

docker 限制容器内存使用量app

在 docker 启动参数中,和内存限制有关的包括(参数的值通常是内存大小,也就是一个正数,后面跟着内存单位 bkmg,分别对应 bytes、KB、MB、和 GB):函数

参数 做用
-m 或 --memory 容器能使用的最大内存大小,最小值为 4m
--memory-swap 容器可以使用的 swap 大小
--memory-swappiness 默认状况下,主机能够把容器使用的匿名页(anonymous page)swap 出来,你能够设置一个 0-100 之间的值,表明容许 swap 出来的比例
--memory-reservation 设置一个内存使用的 soft limit,若是 docker 发现主机内存不足,会执行 OOM 操做。这个值必须小于 --memory 设置的值
--kernel-memory 容器可以使用的 kernel memory 大小,最小值为 4m。
--oom-kill-disable 是否运行 OOM 的时候杀死容器。只有设置了 -m,才能够把这个选项设置为 false,不然容器会耗尽主机内存,并且致使主机应用被杀死

关于 --memory-swap 的设置必须解释一下,--memory-swap 必须在 --memory 也配置的状况下才能有用。工具

  • 若是 --memory-swap 的值大于 --memory,那么容器能使用的总内存(内存 + swap)为 --memory-swap 的值,能使用的 swap 值为 --memory-swap 减去 --memory 的值
  • 若是 --memory-swap 为 0,或者和 --memory 的值相同,那么容器能使用两倍于内存的 swap 大小,若是 --memory 对应的值是 200M,那么容器可使用 400M swap
  • 若是 --memory-swap 的值为 -1,那么不限制 swap 的使用,也就是说主机有多少 swap,容器均可以使用

实例:

docker run -di --name=os -m=1g centos:latest bash

3、测试

1) 安装 Docker 容器

$ docker pull centos:latest

2) 运行容器并指定CPU 和内存

$ docker run -di --name=os --cpus=0.2 -m=512MB  centos:latest bash

3) 进入容器并安装压测工具

$ docker exec -it os bash

$ yum install wget gcc gcc-c++ make -y
$ yum install -y epel-release
$ yum install stress -y

4) 压测前观察 Docker 资源使用状况

$ docker stats

  5) 压测CPU

stress --cpu 2 --timeout 600

增长2个 CPU 进程,处理 sqrt() 函数函数,以提升系统CPU负荷,测试600S

6) 观察 Docker 资源使用状况

$ docker stats

能够看到容器 CPU 基本上不能彪到 20%以上了。

7)压测内存 

$ stress --vm 1 --vm-bytes 1g --timeout 600

新增1个 IO 进程,内存大小为 1G,发现进程直接被 kill 掉了

相关文章
相关标签/搜索