概述
在平时本地运行一些资源消耗比较高的容器的时候,你可能有时会不爽一个容器就把机器搞得卡地不行,这个时候你就想将这个容器关掉了,但是有不能关,不知道你有没有这个困扰,至少我是有的,所以这里就介绍一下 Docker 怎么限制容器的资源消耗。
CPU
Docker 限制 CPU 有几个维度:
- 简单:限制 CPU 核数,这个很好理解
- 使用方式:
[[email protected]]# docker run --cpus=4
表示允许使用 4 个核心
- 使用方式:
- 复杂:基于 CPU 时间片的限制,docker 是基于 CFS 的调度实现,这是老版本使用的,新版本都推荐使用简单的方式
- 使用方式:
[[email protected]]# docker run --cpu-period=100000 --cpu-quota=200000
表示每个 CPU 使用的时间是 100 ms,这个容器最多使用 200ms(相当于限制了 2 个核,但是不是绝对)
- 使用方式:
但是上面这两个在 Go 程序中有问题,当用 Go 代码获取 CPU Number 的时候,会获取到宿主机上的所有 core,这对于 Go 来说不合理。
除此之外,docker 还提供了其他的 cpu 选项,不细说了,简单描述一下:
cpuset-cpus
:绑定容器只能使用哪些核cpu-shares
:当多个容器抢 CPU 时间时,可以通过这个值按比例分配 CPU 时间
Docker container 有个问题,那就是在 VM 里面运行 Container,当你扩容了 VM 之后,Container 的 CPU 核数并不会增加,解决方式是手动修改 container 的 cgroup 配置:
内存
内存的限制选项也好几个,我挑 4 个有意义的说一下吧:
- 限制内存大小:
[[email protected]]# docker run -m 200m
只能使用 200M 的内存,多了就 OOM - 限制内存软大小:
[[email protected]]# docker run --memory-reservation 200m
在系统内存紧张的时候限制使用 200M 的内存,多了也没什么,这其实比较鸡肋 - 内核内存使用限制:
[[email protected]]# docker run --kernel-memory 200m
只能使用 200m 的内核内存,多了就 OOM - OOM 设置:
[[email protected]]# docker run --oom-kill-disable
进程超内存了不要 OOM,那怎么办,就申请不到内存咯
磁盘
限制磁盘大小
默认 Docker 只能使用 10 G 的 Volume,如果想要更大一些,需要修改启动参数:
[root@liqiang.io]# cat /etc/docker/daemon.json
{
"storage-driver": "devicemapper",
"storage-opts": [
"dm.basesize=40G"
]
}
限制磁盘 IO
这个选项就比较多了,直接看下列表吧:
--blkio-weight uint16 Block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)
--blkio-weight-device list Block IO weight (relative device weight) (default [])
--device-read-bps list Limit read rate (bytes per second) from a device (default [])
--device-read-iops list Limit read rate (IO per second) from a device (default [])
--device-write-bps list Limit write rate (bytes per second) to a device (default [])
--device-write-iops list Limit write rate (IO per second) to a device (default [])
使用示例:
# 这是限制磁盘的
[root@liqiang.io]# docker run -it --rm --device-write-bps /dev/sda:50kb ubuntu /bin/bash
root@9eab6510cccf:/# time dd if=/dev/zero of=test.out bs=1M count=1024 oflag=direct
1048576 bytes (1.0 MB, 1.0 MiB) copied, 20.4818 s, 51.2 kB/s
# 这是限制文件的
[root@liqiang.io]# docker run -it --rm --device-write-bps /dev/dm-x:50mb centos /bin/bash
- 具体怎么找文件的设备名,可以参考这个:How to limit IO speed in docker and share file with system in the same time?
网络
网络的需求就太常见了,但是根据我查找资料,Docker 官方似乎还没有支持这个功能,但是,有网友简单地用 tc 命令直接在容器内部实现了,操作方式为:
[root@liqiang.io]# docker run --rm -it centos:7 /bin/sh
tc qdisc add dev eth0 handle 1: ingress
tc filter add dev eth0 parent 1: protocol ip prio 50 u32 match ip src 0.0.0.0/0 police rate 1mbit burst 10k drop flowid :1
tc qdisc add dev eth0 root tbf rate 1mbit latency 25ms burst 10k`
这个可以用来限制 eth0 interface 的速度为 1M,具体可以参照:How can I rate limit network traffic on a docker container。