Docker | 容器 |(二)

29 篇文章 0 订阅
27 篇文章 0 订阅

                        --昨夜西风凋碧树,独上高楼,望尽天涯路

  • 资源限制

运行在docker host上的若干容器,每个都需要CPU、内存和IO资源。对于KVM、VMware等虚拟化技术,用户可以控制分配多少CPU、内存资源给每个虚拟机。对于容器,Docker也提供了类似的机制避免某个容器占用太多的资源而影响其他容器乃至整个系统。

1.内存限额

与操作系统类似,容器可使用的内存包括两部分:物理内存和swap。Docker通过下面两个参数来控制内存使用量:                     

(1)-m或--memory:设置内存的使用限额。

(2)--memory-swap:设置内存+swap的使用限额

当我们使用如下命令:

docker run -m 200M --memory-swap=300M ubuntu

意思是允许该容器最多使用200MB内存和100MB 的swap。默认情况下上面两组参数为-1,即对容器内存和swap的使用没有限制

下面使用progrium/stress镜像来学习如何为容器分配内存。该镜像可用于对容器执行压力测试:

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

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

 因为280M内存在可分配的范围(300M)内,所以工作线程能够正常工作,其过程时:

1.分配280M内存

2.释放280M内存

3.分配280M内存

...

  一直循环

如果让工作线程分配的内存超过300M,结果是:分配的内存超多限额,stress线程报错,容器退出。

如果在启动容器时只指定-m而不指定--memory-swap,那么--memory-swap默认为-m的两倍,比如:

docker run -it -m 200M ubuntu

容器最多使用200M物理内存和200Mswap 

2.CPU限额

默认设置下,所有的容器可以平等地使用host CPU资源并且没有限制。

Docker可以通过-c或--cpu-shares设置容器使用CPU地权重。如果不指定默认是1024。

与内存限额不同,通过-c设置的cpu share并不是CPU资源的绝对数量,而是一个相对的权重值。某个容器最终能够分配到的CPU资源取决于它的cpu share占所有容器cpu share总和的比例。即就是通过cpu share可以设置容器使用CPU的优先级。

比如在host中启动两个容器A ,B。A的cpu share是B的两倍。当两个cpu都需要资源时,A得到的是B的两倍。

--cpu用来指定工作线程数,由于我当前docker host有两个cpu,所以指定--cpu 2。

(1)启动container_A,cpu shares为1024:

 (2)启动container_B,cpu shares为512:

 (3)在host中执行top查看cpu的使用情况,container_A是container_B的两倍:

(4)现在暂停container_A,然后用top显示container_B在container_A暂停下来的时候可以占满整个cpu:

3.Block IO带宽限额

Block IO是另一种可以限制容器使用的资源。Block IO指的是磁盘的读写,docker可以设置权重、限制bps和iops的方式控制容器读写磁盘的带宽。

(1)block IO权重

默认情况下,所有的容器能平等地读写磁盘,可以通过--blkio-weight参数来改变block IO的优先级。--blkio-weight与-cpu-shares类似,设置的是相对权重值,默认是500。如下,container_A读写磁盘的带宽是container_B的两倍:

(2)限制bps和iops

bps:每秒读写的数据量;iops:每秒IO的次数

通过下面的参数控制容器的bps和iops:

--device-read-bps:限制读某个设备的bps

--device-write-bps:限制写某个设备的bps

--device-read-iops:限制读某个设备的iops

--device-write-iops:限制写某个设备的iops

显示容器写/dev/sda的速率为30MB/s:

 

通过dd测试在容器中读写磁盘的速度。因为容器的文件系统是在host /dev/sda上的,在容器中写文件相当于对host /dev/sda进行写操作。另外,oflag=direct指定用dircet IO方式写文件,这样--device-write-bps才能生效。
结果表明bps没有超过30MB/s(这个地方每次都会超过30,达到31.5,还没找到原因)。

作为对比测试,如果不限速,结果如下:

  • 容器底层技术

cgroup和namespace是很重要的两种实现容器的底层技术。cgroup实现资源限额,namespace实现资源隔离

(1)cgroup

cgroup全称Control Group。Linux操作系统通过cgroup可以设置进程使用CPU、内存和IO资源的限额(对于--cpu-shares、-m、--device-write-bps实际上就是在配置cgroup。
运行一个容器,然后我们可以看到在/sys/fs/cgroup下找到cgroup,在/sys/fs/cgroup/cpu/docker下,Linux会为每一个容器创建一个cgroup目录,以容器的长ID命名:

 

目录中包含所有与cpu相关的cgroup配置,文件cpu.shares保存的就是--cpu-shares的配置,值为512。同理,/sys/fs/cgroup/memory/docker和/sys/fs/cgroup/blkio/docker中保存的是内存以及Block IO的cgroup配置。

(2)namespace

每个容器中,我们看到的文件系统、网卡等资源,这些资源看上去是容器自己的。即使host上有一块物理网卡,但是每个容器也会认为自己有一块独立的网卡,这种方式使得容器更像一个独立的计算机。

Linux实现这种方式的技术是namespace。namespace管理着host中全局唯一的资源,实现了容器间资源的隔离(使得每个容器都觉得只有自己在使用它)。

Linux使用了6中namespace,分别对应6钟资源:Mount、UTS、IPC、PID、Network和User。

 

1.Mount namespace

Mount namespace让容器看上去拥有整个文件系统。

容器拥有自己的/目录,可以执行mount和umount命令。这些操作只在当前容器中生效,不会影响到host和其他容器。

2.UTS namespace

UTS namespace让容器有自己的hostname。默认容器的hostname是它的短ID,可以通过-h或者-hostname参数设置:

3.IPC namespace

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

4.PID namespace

容器在host中以进程的形式运行。例如当前host中运行了两个容器:

通过ps axf可以查看容器进程:

所有的容器进程都挂在dockerd进程下,同时也可以看到容器自己的子进程。当进到某个容器,ps就只能看到自己的进程了:

而且进程的PID不同于host中对应进程的PID,容器中PID=1的进程当然也不是host的init进程。也就是说:容器拥有自己独立的一套PID,就是PID namespace提供的功能。

5.Network namespace

Network namespace让容器拥有自己独立的网卡、IP、路由等资源。

6.User namespace

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

在容器中创建了用户luffy,但是host中并不会创建相应的用户。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值