容器资源限制
默认情况下, 容器没有资源限制 ,可以使用主机内核调度程序允许的尽可能多的给定资源。 Docker 提供了控制容器可以 使用多少内存或 CPU 的方法 。
1.内存限制
##使用progrium/stress对容器进行压力测试
docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 280M
##参数说明
-m:设置内存使用额
--memory-swap:设置内存+swap使用额(如果不指定 默认为-m两倍)
--vm:启动一个内存工作线程
--vm-bytes:每个线程分配量
-----------------------------------------------------------------------------------
##显示结果 因为分配量没有尝过300M所以会一直循环
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogvm worker 1 [6] forked
stress: dbug: [6] allocating 293601280 bytes ...
stress: dbug: [6] touching bytes in strides of 4096 bytes ...
-----------------------------------------------------------------------------------
##分配超过300M时,strees报错容器退出
docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 310M
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogvm worker 1 [6] forked
stress: dbug: [6] allocating 325058560 bytes ...
stress: dbug: [6] touching bytes in strides of 4096 bytes ...
stress: FAIL: [1] (416) <-- worker 6 got signal 9
stress: WARN: [1] (418) now reaping child worker processes
stress: FAIL: [1] (422) kill error: No such process
stress: FAIL: [1] (452) failed run completed in 1s
2.CPU限制
与内存限额不同,通过-c设置的cpu资源并不是绝对数量,而是一个相对的权重值。
##设置c-A的cup share为1024
docker run --name "con-A" -it -c 1024 progrium/stress --cpu 1
参数说明:
-c:设置cpu share
--cpu:设置cpu工作线程数量
-------------------------------------------------------------
##设置c-B的cpu share为512
docker run --name "con-B" -it -c 512 progrium/stress --cpu 1
-------------------------------------------------------------
top查看容器对cpu的使用情况
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2322 root 20 0 7304 96 0 R 66.7 0.0 4:22.70 stress
2424 root 20 0 7304 96 0 R 33.3 0.0 1:56.83 stress
##当两个容器都需要使用cpu时 c-A是c-B的两倍
这种情况只会发生在cpu资源紧张的情况下,当c-A空闲时,c-B会获得全部资源
##退出c-A再次查看
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2424 root 20 0 7304 96 0 R 99.7 0.0 3:12.58 stress
3.Block IO限制
Block IO指的是磁盘读写,docker可以通过设置权重,bps等方式限制容器读写磁盘带宽。默认情况下,所有容器能平等的读写磁盘。
docker run -it --blkio-weight 600 --device-write-bps /dev/sda:30M centos
##参数说明
--blkio-weight:设置权重
--device-write-bps:限制bps
time dd if=/dev/zero of=test.out bs=1M count=800 oflag=direct
##oflag=direct指定用direct IO方式写文件
800+0 records in
800+0 records out
838860800 bytes (839 MB, 800 MiB) copied, 26.836 s, 31.3 MB/s
real 0m26.854s
user 0m0.000s
sys 0m0.761s
--------------------------------------------------------------------
##对比测试 没有限速
docker run -it --blkio-weight 300 centos
time dd if=/dev/zero of=test.out bs=1M count=800 oflag=direct
800+0 records in
800+0 records out
838860800 bytes (839 MB, 800 MiB) copied, 1.03089 s, 814 MB/s
real 0m1.034s
user 0m0.001s
sys 0m0.642s
容器底层技术
1.Cgroup
Cgroups提供了以下功能:
-
限制进程组可以使用的资源(Resource limiting):比如memory子系统可以为进程组设定一个memory使用上限,进程组使用的内存达到限额再申请内存,就会出发OOM(out ofmemory) 进程组的优先级控制(Prioritization ):比如可以使用cpu子系统为某个进程组分配cpu share
-
记录进程组使用的资源量(Accounting ):比如使用cpuacct子系统记录某个进程组使用的cpu时间
-
进程组隔离(Isolation):比如使用ns子系统可以使不同的进程组使用不同的namespace,以达到隔离的目的,不同的进程组有各自的进程、网络、文件系统挂载空间
-
进程组控制(Control):比如使用freezer子系统可以将进程组挂起和恢复
Cgroup位置 cd /sys/fs/cgroup/cpu/docker/ ll drwxr-xr-x. 2 root root 0 5月 29 11:09 8951a64bfc808fcbfd289287b50316f7f7aa7e6e9d4be088ed1f35f9514a7a68 -rw-r--r--. 1 root root 0 5月 29 10:28 cgroup.clone_children --w--w--w-. 1 root root 0 5月 29 10:28 cgroup.event_control -rw-r--r--. 1 root root 0 5月 29 10:28 cgroup.procs -r--r--r--. 1 root root 0 5月 29 10:28 cpuacct.stat -rw-r--r--. 1 root root 0 5月 29 10:28 cpuacct.usage -r--r--r--. 1 root root 0 5月 29 10:28 cpuacct.usage_percpu -rw-r--r--. 1 root root 0 5月 29 10:28 cpu.cfs_period_us -rw-r--r--. 1 root root 0 5月 29 10:28 cpu.cfs_quota_us -rw-r--r--. 1 root root 0 5月 29 10:28 cpu.rt_period_us -rw-r--r--. 1 root root 0 5月 29 10:28 cpu.rt_runtime_us -rw-r--r--. 1 root root 0 5月 29 10:28 cpu.shares -r--r--r--. 1 root root 0 5月 29 10:28 cpu.stat -rw-r--r--. 1 root root 0 5月 29 10:28 notify_on_release -rw-r--r--. 1 root root 0 5月 29 10:28 tasks 进入容器ID文件中 查看 cpu.shares cat cpu.shares 512 ##与设置相同
2.namespace
目前Linux内核总共实现了6种Namespace:
- IPC:隔离System V IPC和POSIX消息队列。
- Network:隔离网络资源。
- Mount:隔离文件系统挂载点。每个容器能看到不同的文件系统层次结构。
- PID:隔离进程ID。
- UTS:隔离主机名和域名。
- User:隔离用户ID和组ID。
1.mount namespace
容器有自己的文件系统,可以mount与umount,不会影响到系统本身的文件系统
2.UTS namespace
让容器拥有自己的hostname,默认情况下容器的hostname为自己的短id,可以通过-h进行设置
docker run -it centos bash
[root@65aa84d6ba4f /]# hostname
65aa84d6ba4f
##
docker run -it -h test1 centos bash
[root@test1 /]# hostname
test1
3.IPC namespace
让容器拥有自己的共享内存和信号量,来实现进程之间的通信,不会与host的ipc混在一起
4.PID namespace
容器用有自己的一套pid系统,在host中可以使用ps axf查看容器进程,容器中的pid不对应host中的pid
5.Network namespace
容器拥有自己独立的网卡 ip 路由等资源
6.User namespace
让容器能够自己管理用户,在host中无法查看容器用户
docker exec -it 4d224fa6 bash
[root@test1 /]# useradd tt1
[root@test1 /]# exit
exit
[root@localhost ~]# id tt1
id: tt1: no such user