默认情况下,容器是没有资源限制的,它会尽可能地使用宿主机能够分配给它的资源。Docker提供了一种控制分配多少量的内存、CPU或阻塞I/O给一个容器的方式,即通过在docker run或docker create命令时设置运行时配置的标志。

在Linux主机上,如果内核检测到没有足够的内存来执行重要的系统功能,它会抛出一个OOME(Out Of Memory Exception),一旦发生OOME,Linux就会开始查杀进程以释放内存。任何进程都有可能会被杀死,包括docker daemon和其他重要的应用程序。如果错误的进程被杀死,这可会降低整个系统的使用效果。

限制Docker使用内存


在Docker中可以强行限制容器的资源使用的限制,即只允许容器使用不超过给定数量的系统内存或其他软限制。下面介绍几个最常用的选项,我们可以在docker run或docker create创建容器时指定,用以限制容器的资源使用限制。

选项 描述
-m 或 -memory= 容器可以使用的最大内存量。如果你设置了此选项,那么允许的最小值为4m(4MB)。
–memory-swap 允许此容器交换到磁盘的内存量。
–kernel-memory 容器可以使用的最大内核内存量,允许的最小值是4m(4MB)。由于内核内存无法换出,因此内核内存不足的容器可能会阻塞主机资源,这可能会对主机和其他容器产生副作用。

限制Docker使用CPU


默认情况下,每个容器对主机CPU周期的访问权限是不受限制的。我们可以设置各种约束来限制给定容器访问主机的CPU周期。大多数用户使用和配置CFS调度程序(默认)或实时调度程序。下面介绍几个常用的选项,用于配置默认的CFS调度程序,以限制容器对于CPU的使用。

选项 描述
–cpus= 指定容器可以使用的可用CPU资源量,例如宿主机有4个CPU,那你可以给容器设置–cpus=”3.5”,则限制容器最多使用3.5个CPU。
–cpuset-cpus 限制容器可以使用的特定CPU或核心,例如宿主机有4个CPU,那你可以给容器设置–cpuset-cpus=”1,3”,则限制容器只能使用第2个和第4个CPU。。

实例


Docker的资源限制实现:
1
2
docker run --name stress -it --rm -m 256m lorel/docker-stress-ng:latest stress --vm 2
docker run --name stress --rm --cpus 1 lorel/docker-stress-ng:latest stress --cpu 4
Docker-compose的资源限制实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
version: "3"
services:
nginx:
container_name: nginx
restart: always
image: nginx:1.17.10
ports:
- 80:80
- 443:443
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf
- ./nginx/logs/:/var/log/nginx/
- ./nginx/cert/:/opt/plone41/etc/
environment:
- TZ=Asia/Shanghai
deploy:
resources:
limits:
cpus: '2'
memory: 2G
reservations:
cpus: '0.5'
memory: 200M
kubernetes的资源限制实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
kind: Deployment
apiVersion: apps/v1
metadata:
name: tomcat-deploy
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: tomcat
release: canary
template:
metadata:
labels:
app: tomcat
release: canary
spec:
containers:
- name: myapp
image: tomcat:8.5.50
ports:
- name: http
containerPort: 8280
readinessProbe:
exec:
command:
- cat
- /usr/local/tomcat/webapps/docs/index.html
initialDelaySeconds: 90
periodSeconds: 20
livenessProbe:
tcpSocket:
port: 8280
initialDelaySeconds: 120
periodSeconds: 20
resources:
requests:
memory: "1024Mi"
cpu: "500m"
limits:
memory: "1024Mi"
cpu: "500m"