目录
一.docker资源管理概述
二.CPU资源的优化
三.内存资源的优化
三.磁盘I/O读写的优化
一.docker资源管理概述
- 由于一台主机可以放多个容器,默认的情况下,docker没有对容器镜像硬件资源的限制
- 当容器负载过高时会尽可能的占用宿主机的资源,所以有时候我们需要对容器的资源使用设置一个上限
- 使用systemctl-cgtop动态查看各个资源的使用情况(依据该情况对docker容器进行资源分配)
[root@cloud ~]# systemd-cgtop
Path Tasks %CPU Memory Input/s Output/s
/ 55 4.5 2.7G - -
/system.slice - 3.6 468.6M - -
/system.slice/aegis.service 3 3.3 109.5M - -
/user.slice 3 0.9 11.0M - -
/system.slice/containerd.service 1 0.2 83.0M - -
/system.slice/aliyun.service 1 0.0 2.4M - -
/system.slice/tuned.service 1 0.0 13.0M - -
/system.slice/rsyslog.service 1 0.0 2.9M - -
/system.slice/atd.service 1 - - - -
/system.slice/auditd.service 1 - 1.3M - -
/system.slice/chronyd.service 1 - 532.0K - -
/system.slice/crond.service 1 - 716.0K - -
/system.slice/dbus.service 1 - 36.0K - -
/system.slice/docker.service 1 - 228.5M - -
/system.slice/lvm2-lvmetad.service 1 - - - -
/system.slice/network.service 1 - 1.9M - -
/system.slice/polkit.service 1 - 7.9M - -
- 对于docker资源的控制,分别由内存、CPU、磁盘的读写等,下面具体说明
二.CPU资源的优化
- 默认情况下,每一个容器可以使用宿主机上的所有CPU资源,但是大多数系统使用的资源调度算法CFS(完全公平调度器)
- CFS公平调度每一个工作进程
- 进程分为CPU密集型和IO密集性两类
- 系统内核会实时监控系统进程,当某个进程占用CPU资源时间过长时,内核会调整该进程的优先级
- 下面是使用docker命令限制cpu资源时的一些参数
参数名 | 解释 |
--cpu-shares | cpu资源提供一组容器使用,组内的容器按比例使用cpu资源,cpu资源被负载打的容器占用(按照压缩比例分配), 当空闲进行运行起来时,cpu资源会被分配到其他容器 |
--cpus=value | 指定cpu核心数量 |
--cpuset-cpus | 指定容器只能运行在那个cpu核心上(绑定cpu);核心使用0,1,2,3编号 |
--cpu-quota | 指定cpu的使用上限的百分比 |
- 查看Linux系统的cpu详细信息
##查看详细信息
[root@cloud ~]# cat /proc/cpuinfo
##查看CPU的核数
[root@cloud ~]# cat /proc/cpuinfo | grep "processor"
processor : 0
processor : 1
[root@cloud ~]#
- 对于cpu的使用率的限制
## --name 指定容器的名字
## --cpu-quota 200000 指定该容器对于cpu的使用率上限是20%
[root@cloud ~]# docker run --name c0 --cpu-quota 200000 nginx:latest
[root@cloud ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2a0222c54f1a nginx:latest "nginx -g 'daemon of…" About an hour ago Up 1 second 80/tcp c0
[root@cloud ~]#
- 对于cpu的比例分配
##-i表示输入,-t表示绑定终端,-d表示开启守护进程
[root@cloud ~]# docker run -itd --name c1 --cpu-shares 512 httpd
cfa4b5f14f75ef2f30d884d11341582396401c767675a11b43e029a40a1ea207
[root@cloud ~]# docker run -itd --name c2 --cpu-shares 1024 httpd
118e74d7fa84f5d1fcac7e6ed028e185fde6d2c6edceab89a10ab609d7bd9052
[root@cloud ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
118e74d7fa84 httpd "httpd-foreground" 9 seconds ago Up 8 seconds 80/tcp c2
cfa4b5f14f75 httpd "httpd-foreground" 20 seconds ago Up 18 seconds 80/tcp c1
2a0222c54f1a nginx:latest "nginx -g 'daemon of…" 2 hours ago Exited (0) 2 minutes ago c0
[root@cloud ~]#
- 对于cpu核数的限制
[root@cloud ~]# cat /proc/cpuinfo | grep processor
processor : 0
processor : 1
[root@cloud ~]# docker run -itd --name c3 --cpuset-cpus 0,1 httpd
271eaa8de989f1decf23ddada071db801348e607c6a4ed3b6ee2ad0671482d4a
[root@cloud ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
271eaa8de989 httpd "httpd-foreground" 5 seconds ago Up 4 seconds 80/tcp c3
118e74d7fa84 httpd "httpd-foreground" 3 minutes ago Up 3 minutes 80/tcp c2
cfa4b5f14f75 httpd "httpd-foreground" 3 minutes ago Up 3 minutes 80/tcp c1
2a0222c54f1a nginx:latest "nginx -g 'daemon of…" 2 hours ago Exited (0) 6 minutes ago c0
[root@cloud ~]#
三.内存资源的优化
- 默认情况下,docker没有对容器内存进行限制,即容器可以使用主机提供的所有内存。
- 如果不对容器进行内存上的限制,会造成一些危险。比如某个容器运行了恶意的内存消耗软件,或者代码有内存泄漏,很可能导致主机内存耗尽,导致服务不可用。
- 对于上述情况,docker会设置docker daemon的OOM(out of memory)值,使其在内存不足时被杀死的优先级降低。此外,也可以为每个容器设置内存的上限,一旦超过这个上限,容器也会被杀死,而不消耗主机的内存
- 虽然,限制内存上限虽然能够保护主机,但是也可能会伤害到容器里的服务。如果服务设置的内存上限太小,会导致服务还在正常工作的时候就被OOM杀死。如果设置过大,就会因为调度器算法浪费内存。合理的做法包括:
1.为应用做内存压力测试,理解正常业务需求下使用的内存情况,然后才能进入生成环境使用
2.限制容器的内存使用上限
3.尽可能保证主机的资源充足,一旦通过监控发现资源不足,就进行扩容或者对容器进行迁移
4.如果内存资源充足,尽量不使用swap,swap的使用会导致内存计算复杂,对调度器非常不友好
- 在docker启动参数中,和内存限制有关的包括(参数的值一般是指内存大小,内存单位分别有b(bytes),k(kb),m(mb),g(gb)),参数情况如下:
参数 | 解释 |
-m 或者 --memory | 容器能够使用的最大内存大小,最小值为4m |
--memory-swap | 容器能够使用的swap大小 |
--memory-swappiness | 默认情况下,主机可以把容器使用的匿名页(anonymous page)swap出来,可以设置一个0-100之间的值,代表 允许swap出来的比例 |
--memory-reservation | 设置一个内存使用的soft limit,如果docker发现主机内存不足,就会执行OOM操作。 这个值必须小于 -m 设置的值 |
--kernel-memory | 容器能够使用的kernel memory大小,最小值为4m |
--oom-kill-disable | 是否运行OOM的时候杀死容器。只有设置 -m,才可以把这个选项false,否则容器会耗尽主机内存,而且导致主机应用被杀死 |
- 实例如下
[root@cloud ~]# free -m
total used free shared buff/cache available
Mem: 3789 223 664 0 2900 3282
Swap: 0 0 0
[root@cloud ~]# docker run -itd --name c4 -m 512m httpd:latest
a1834d69cb55e6809211d381d6ca7c2acfe52cbc11be37293f48c2bfb52e2d0a
[root@cloud ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1834d69cb55 httpd:latest "httpd-foreground" 5 seconds ago Up 4 seconds 80/tcp c4
271eaa8de989 httpd "httpd-foreground" 28 minutes ago Exited (0) 27 minutes ago c3
118e74d7fa84 httpd "httpd-foreground" 32 minutes ago Exited (0) 27 minutes ago c2
cfa4b5f14f75 httpd "httpd-foreground" 32 minutes ago Exited (0) 27 minutes ago c1
2a0222c54f1a nginx:latest "nginx -g 'daemon of…" 2 hours ago Exited (0) 34 minutes ago c0
[root@cloud ~]#
- 观察docke容器的资源使用情况
[root@cloud ~]# docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
a1834d69cb55 c4 0.00% 14.1MiB / 512MiB 2.75% 0B / 0B 0B / 0B 82
三.磁盘I/O读写的优化
- IO资源同样也是操作系统的一种非常重要的资源,通常包含了对硬盘的读写,网络数据的交换等等
- 控制容器的读写硬盘的方法:
1.设置容器读写硬盘资源的权重
2.限制bps(数据量)和iops(次数)
bps:byte per second,每秒读写的字节数(,即读写速率)
iops:io per second,每秒IO的次数
- 设置权重
在使用docker run启动容器时,提供参数--blkio-weight int 可以帮助我们控制容器读写磁盘(block IO)的优先级
- 限制bps和iops
1.--device-read-bps(限制读某个设备的bps)
2.--device-write-bps(限制写入某个设备的bps)
3.--device-read-iops(限制读某个设备的iops)
4.--device-write-iops(限制写入某个设备的iops)
- 实例