Docker 资源限制

限制容器对内存的使用:

下载progrium/stress镜像 作为压力测试

[root@localhost ~]# docker pull progrium/stress
docker run --help
-m, --memory bytes 内存限制
--memory-reservation bytes 内存的软限制
--memory-swap bytes 内存+交换分区
--memory-swappiness int 优化容器内存交换

进行压力测试

docker run -m 200M --memory-swap=300M progrium/stress

--vm 1 --vm-bytes 290M --vm 1:启动一个内存工作线程

--vm-bytes 280M:每个线程分配280内存

因为280M在可分配的范围(300M)内,所以可以正常工作

一直循环分配,释放280M内存

docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 310M

一旦分配的内存超过限额,stress线程报错,容器退出

注:如果在容器启动时只指定 -m 而不指定–memory-swap
那么默认是-m的二倍,容器最多使用200M物理内存和200M swap

限制容器对CPU使用

默认模式下,所有容器是平等使用CPU资源并且没有限制

可以使用-c或- -cpu-shares设置容器使用CPU的权重,默认为1024

通过-c设置的权重并不是CPU资源的绝对数量,而是一个相对的权重值。某个容器最终能分配到的CPU资源取决于它的cpu share所占容器cpu share总和的比例
docker run --name "con_a" -it -c 1024 progrium/stress --cpu 1

docker run --name "con_b" -it -c 512 progrium/stress --cpu 1

con_a的cpu share是1024,con_b的cpu share是512,当都需要cpu资源时,con_a就是con_b的两倍

-c, --cpu-shares int 权重的设定
--cpus decimal 设定cpu的数量
--cpuset-cpus string 允许执行的cpu
--cpuset-mems string 允许执行的MEMs

限制容器的Block IO

Block IO指的是磁盘的读写,docker可通过设置权重,限制bps和iops的方式控制容器读写磁盘的带宽,目前只对 direct IO(不使用文件缓存)有效

block IO权重

默认情况下,所有容器可以平等读写磁盘,可以通过设置 - -blkio-weight参数来改变容器block IO的优先级,默认是500

docker run -it --name con_a --blkio-weight 600 centos7

docker run -it --name con_b --blkio-weight 300 centos7

con_a读写磁盘的带宽是con_b的两倍

限制bps和iops bps是byte per second,每秒读写的数据量
iops是io per second,每秒IO的次数

限制容器写/dev/sda的速率为30MB/s

docker run -it --device-write-bps /dev/sda:30MB centos7:latest /bin/bash

实现容器的底层技术

cgroup

cgroup全称Control Group,可以设置进程使用CPU,内存和IO资源的限额

启动一个容器

docker run --name "con_a" -it -c 1024 progrium/stress --cpu 1

在/sys/fs/cgroup/cpu/docker/目录里,linux会为每个容器创建一个cgroup目录,以容器长ID命名

目录中包含所有cpu相关的cgroup配置,文件cpu.shares保存的就是 - -cpu-shares的配置
/sys/fs/cgroup/memory/docker/保存的是内存的配置
/sys/fs/cgroup/blkio/docker/保存的是Block IO的配置

Mount namespace

Mount namespace让容器看上去拥有整个文件系统
容器有自己的/目录,可以执行mount,umount命令,不会影响到host

UTS namespace

UTS namespace让容器拥有自己的hostname,可以通过-h或- - hostname设置

IPC namespace

IPC namespace让容器拥有自己的共享内存和信号量来实现进程间通信,不会与host或其他的容器混在一起

PID namespace

PID namespace让容器拥有自己独立的PID

Network namespace

Network namespace让容器拥有自己独立的网卡,IP,路由等

User namespace

User namespace让容器能够管理自己的用户,host不能看到容器中创建的用户