4-9-docker容器命名和资源配额控制
本节所讲内容:
1、docker容器命名和重命名
2、创建docker容器实例时挃定主机名
3、docker容器资源配额控制之cpu
4、docker容器资源配额控制之内存
5、docker容器资源配额控制之IO
6、docker 数据映射
前期准备:
[root@xuegod63 ~]# systemctl start docker
导入镜像:
[root@xuegod63 ~]# docker load -i centos-lastest-docker-image.tar
1 docker容器命名和重命名
容器命名语法:docker run -itd --name容器实例名容器镜像名要执行的命令
容器重命名语法:docker rename 旧容器名新容器名
例1:运行一个名字为docker1的容器
[root@localhost ~]# docker run -idt --name docker1 centos /bin/sh
09d7ad07efa1da3e0741e3fed76ffa20ead4f86a6d30ff7132f608c5851ecd44
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
09d7ad07efa1 centos "/bin/sh" 5 seconds ago Up 4 seconds docker1
例2:将docke1容器重命名
[root@localhost ~]# docker rename docker1 docker2
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
09d7ad07efa1 centos "/bin/sh" 55 seconds ago Up 54 seconds docker2
2 创建docker容器实例时指定主机名
语法:docker run -it --name 容器名-h 指定主机名镜像/bin/bash
例1:
[root@localhost ~]# docker run -it --name docker3 -h docker63.cn centos /bin/sh
sh-4.2# hostname
docker63.cn
sh-4.2#
3 docker容器资源配额控制
启动docker容器时,指定cpu,内存,硬盘性能等的硬件资源使用份额
Docker通过cgroup来控制容器使用的资源配额,包括CPU、内存、磁盘三大方面,基本覆盖了常见的资源配额和使用量控制。
cgroup概述:
cgroup是Control Groups的缩写,是Linux内核提供的一种可以限制、记录、隔离进程组所使用的物理资源(如cpu、memory、磁盘IO等等) 的机制,被LXC、docker等很多项目用于实现进程资源控制。cgroup将任意进程进行分组化管理的Linux 内核功能。cgroup本身是提供将进程进行分组化管理的功能和接口的基础结构,I/O 或内存的分配控制等具体的资源管理功能是通过这个功能来实现的。
为什么要进行硬件配额?当多个容器运行时,防止某容器把所有的硬件都占用了。(比如一台被黑的容器)
3.1 例1:给容器实例分配512权重的cpu使用份额
[root@localhost ~]# docker run --help|grep cpu-shares
-c, --cpu-shares int CPU shares (relative weight)
cpu配额参数:
-c, --cpu-shares int CPU shares (relative weight)在创建容器时指定容器所使用的CPU份额值。
cpu-shares的值不能保证可以获得1个vcpu或者多少GHz的CPU资源,仅仅只是一个弹性的加权值。
默认情况下,每个docker容器的cpu份额都是1024。单独一个容器的份额是没有意义的,只有在同时运行多个容器时,容器的cpu加权的效果才能体现出来。
例如,两个容器A、B的cpu份额分别为1000和500,在cpu进行时间片分配的时候,容器A比容器B多一倍的机会获得CPU的时间片,但分配的结果取决于当时主机和其他容器的运行状态,实际上也无法保证容器A一定能获得CPU时间片。比如容器A的进程一直是空闲的,那么容器B是可以获取比容器A更多的CPU时间片的。极端情况下,比如说主机上只运行了一个容器,即使它的cpu份额只有50,它也可以独占整个主机的cpu资源。
问:两个容器A、B的cpu份额分别为1000和500,1000+500> 1024 是超出了吗?没有。A使用1024的2/3 ,B 使用1024的1/3 。
cgroup只在容器分配的资源紧缺时,也就是说在需要对容器使用的资源进行限制时,才会生效。因此,无法单纯根据某个容器的cpu份额来确定有多少cpu资源分配给它,资源分配结果取决于同时运行的其他容器的cpu分配和容器中进程运行情况。
例1:给容器实例分配512权重的cpu使用份额
语法:cat /sys/fs/cgroup/cpu/docker/容器ID/cpu.shares
[root@localhost ~]# docker run -itd --cpu-shares 512 centos /bin/bash
35a688b46b6e9a33aadd78427bb6e65b47a35737d83a870565808f3fb1beea02
[root@localhost ~]# cat /sys/fs/cgroup/cpu/docker/35a688b46b6e9a33aadd78427bb6e65b47a35737d83a870565808f3fb1beea02/cpu.shares
512
注:稍后,我们启劢多个容器,测试一下是丌是只能使用512份额的cpu资源。单独一个容器,看丌出来
3.2 了解CPU周期控制
讲cgroup,希望开拓一下眼界!
docker提供了--cpu-period、--cpu-quota两个参数控制容器可以分配到的CPU时钟周期。
--cpu-period是用来指定容器对CPU的使用要在多长时间内做一次重新分配
--cpu-quota是用来指定在这个周期内,最多可以有多少时间片断用来跑这个容器。
跟--cpu-shares不同的,--cpu-period和--cpu-quota是指定一个绝对值,而且没有弹性在里面,容器对CPU资源的使用绝对不会超过配置的值。
cpu-period和cpu-quota的单位为微秒(μs)。cpu-period的最小值为1000微秒,最大值为1秒(10^6 μs),默认值为0.1秒(100000 μs)。cpu-quota的值默认为-1,表示不做控制。
1秒=1000毫秒1毫秒=1000
查看最终生成的cgroup的cpu周期配置:
[root@localhost ~]# cat /sys/fs/cgroup/cpu/docker/35a688b46b6e9a33aadd78427bb6e65b47a35737d83a870565808f3fb1beea02/cpu.cfs_period_us
100000
[root@localhost ~]# cat /sys/fs/cgroup/cpu/docker/35a688b46b6e9a33aadd78427bb6e65b47a35737d83a870565808f3fb1beea02/cpu.cfs_quota_us
-1
注: cpu-quota的值默认为-1,表示不做控制
3.3 CPU core核心控制
参数:--cpuset可以绑定CPU
对多核CPU的服务器,docker还可以控制容器运行限定使用哪些cpu内核和内存节点,即使用--cpuset-cpus和--cpuset-mems参数。对具有NUMA拓扑(具有多CPU、多内存节点)的服务器尤其有用,可以对需要高性能计算的容器进行性能最优的配置。如果服务器只有一个内存节点,则–cpuset-mems的配置基本上不会有明显效果。
云主机:普通云主机,独立云主机(硬件资源独占)
扩展:
SMP、NUMA、MPP体系结构介绍
从系统架构来看,目前的商用服务器大体可以分为三类:
1、即对称多处理器结构(SMP:SymmetricMulti-Processor)例:x86 服务器,双路服务器
2、非一致存储访问结构(NUMA:Non-UniformMemoryAccess)例:IBM 小型机pSeries 690
3、海量并行处理结构(MPP:MassiveParallelProcessing)。例:大型机
NUMA例子:IBM pSeries 690
扩展:taskset命令
taskset设定cpu亲和力,taskset能够将一个或多个进程绑定到一个或多个处理器上运行。
参数:
-c, --cpu-list 以列表格式显示和指定CPU
-p, --pid 在已经存在的pid 上操作
例1:设置只在1和2号cpu运行sshd进程程序
pid 1450's current affinity list: 0-3
pid 1450's new affinity list: 1,2
例2:查看ID为1的进程在哪个cpu上运行
[root@xuegod63 ~]# taskset-cp 1
pid 1's current affinity list: 0-3
例3:设置nginx cpu亲和力
在conf/nginx.conf中,有如下一行:
worker_processes 1;
这是用来配置nginx启动几个工作进程的,默认为1。而nginx还支持一个名为worker_cpu_affinity的配置项,也就是说,nginx可以为每个工作进程绑定CPU。如下配置:
worker_processes 3;
worker_cpu_affinity 0010 0100 1000;
这里0010 0100 1000是掩码,分别代表第2、3、4颗cpu核心。
重启nginx后,3个工作进程就可以各自用各自的CPU了。
例4:物理机一共有16个核心,创建的容器只能用0、1、2这三个内核。
[root@xuegod63 ~]# docker run -itd --name cpu1 --cpuset-cpus 0-2 centos
14540b6b0f3f5e2487a26d751765fd67dbb57708f8a412525595361b4b53865b
[root@xuegod63 ~]# cat /sys/fs/cgroup/cpuset/docker/14540b6b0f3f5e2487a26d751765fd67dbb57708f8a412525595361b4b53865b/cpuset.cpus
0-2
进入容器测试:
通过docker exec <容器ID或名字> taskset -c -p 1(容器内部第一个进程编号一般为1),可以看到容器中进程与CPU内核的绑定关系,可以认为达到了绑定CPU内核的目的。
[root@xuegod63 ~]# docker exec cpu1 taskset -cp 1
pid 1's current affinity list: 0-2
3.4 CPU配额控制参数的混合使用
来个综合实例
在上面这些参数中,cpu-shares控制只发生在容器竞争同一个内核的时间片时,如果通过cpuset-cpus指定容器A使用内核0,容器B只是用内核1,在主机上只有这两个容器使用对应内核的情况,它们各自占用全部的内核资源,cpu-shares没有明显效果。
cpu-period、cpu-quota这两个参数一般联合使用,在单核情况或者通过cpuset-cpus强制容器使用一个cpu内核的情况下,即使cpu-quota超过cpu-period,也不会使容器使用更多的CPU资源。
cpuset-cpus、cpuset-mems只在多核、多内存节点上的服务器上有效,并且必须与实际的物理配置匹配,否则也无法达到资源控制的目的。
例1:测试cpuset-cpus和cpu-shares混合使用运行效果,就需要一个压缩力测试工具stress来让容器实例把cpu跑满。
先扩展:stress命令
概述:linux系统压力测试软件Stress。stress可以测试Linux系统cpu/menory/IO/disk的负载。
下载页:
http://people.seas.harvard.edu/~apw/stress/
注:也可以使用epel源中的stress-xxx.rpm 。MK教你一个源码编译通用版本。
安装stress,进行压力测试
[root@xuegod63 ~]# tar zxvf stress-1.0.4.tar.gz
[root@xuegod63 ~]# cd stress-1.0.4/
[root@xuegod63 stress-1.0.4]#./configure
[root@xuegod63 stress-1.0.4]# make -j 4
[root@xuegod63 stress-1.0.4]# make install
stress参数解释
-?显示帮助信息
-v显示版本号
-q不显示运行信息
-n显示已完成的指令情况
-t--timeoutN指定运行N秒后停止
--backoffN等待N微妙后开始运行
-c产生n个进程每个进程都反复不停的计算随机数的平方根,测试cpu
-i产生n个进程每个进程反复调用sync(),sync()用于将内存上的内容写到硬盘上,测试io
-m --vm n 产生n个进程,每个进程不断调用内存分配malloc和内存释放free函数,测试内存
--vm-bytes B指定malloc时内存的字节数(默认256MB)
--vm-hang N指定在free栈的秒数
-d--hadd n产生n个执行write和unlink函数的进程
-hadd-bytes B指定写的字节数
--hadd-noclean不unlink
注:时间单位可以为秒s,分m,小时h,天d,年y,文件大小单位可以为K,M,G
例1:产生2个cpu进程,2个io进程,20秒后停止运行
[root@xuegod63 stress-1.0.4]# stress-c 2 -i 2 --verbose --timeout 20s
#如果执行时间为分钟,改5s 为1m
[root@xuegod63 stress-1.0.4]# stress -c 2 -i 2 --verbose --timeout 20s
stress: info: [9898] dispatching hogs: 2 cpu, 2 io, 0 vm, 0 hdd
stress: dbug: [9898] using backoff sleep of 12000us
stress: dbug: [9898] setting timeout to 20s
stress: dbug: [9898] --> hogcpu worker 2 [9899] forked
stress: dbug: [9898] --> hogio worker 2 [9900] forked
stress: dbug: [9898] using backoff sleep of 6000us
stress: dbug: [9898] setting timeout to 20s
stress: dbug: [9898] --> hogcpu worker 1 [9901] forked
stress: dbug: [9898] --> hogio worker 1 [9902] forked
stress: dbug: [9898] <--worker 9899 signalled normally
stress: dbug: [9898] <--worker 9901 signalled normally
stress: dbug: [9898] <--worker 9902 signalled normally
stress: dbug: [9898] <--worker 9900 signalled normally
stress: info: [9898] successful run completed in 20s
查看:
例1:测试cpuset-cpus和cpu-shares混合使用运行效果,就需要一个压缩力测试工具stress来让容器实例把cpu跑满。当跑满后,会不会去其他cpu上运行。如果没有在其他cpu上运行,说明cgroup资源限制成功。
如图:
创建两个容器实例:
[root@xuegod63 ~]# docker run -itd --name cpu2 --cpuset-cpus 0,1 --cpu-shares 512 centos /bin/bash
[root@xuegod63 ~]# docker run -tid --name cpu3 --cpuset-cpus 0,1 --cpu-shares 1024 centos/bin/bash
进入cpu2,使用stress测试进程是不是只在cpu0,1上运行:
[root@xuegod63 ~]# docker exec -it cpu2 /bin/bash
[root@4e55d99ba29e /]# yum install openssh-clients -y#安装scp命令
[root@7cfed28beb4f /]# scp -r root@192.168.1.63:/usr/local/stress ./ #把编译好的stress复制到容器中,因为容器上没有make命令。
[root@7cfed28beb4f /]# /stress/bin/stress -c 2 --verbose --timeout 10m
在物理机上使用top按1快捷链查看,每个cpu使用情况:
可看到正常。只在cpu0,1上运行
然后进入cpu3,使用stress测试进程是不是只在cpu0,1上运行:
[root@xuegod63 ~]# docker exec -it cpu3/bin/bash
[root@4e55d99ba29e /]# yum install openssh-clients -y#安装scp命令
[root@7cfed28beb4f /]# scp -r root@192.168.1.63:/usr/local/stress ./ #把编译好的stress复制到容器中,因为容器上没有make命令
[root@4e55d99ba29e /]# cd stress/
[root@7cfed28beb4f /]# ./stress/bin/stress -c 2 --verbose --timeout 10m
在物理机上使用top 按1快捷链查看,每个cpu使用情况:
注:两个容器只在cpu0,1上运行。且cpu3是cpu2使用cpu的2倍。说明--cpu-shares限制资源成功
例3:动态修改,将cpu3的cpu.shares改为512
[root@xuegod63 ~]# docker ps | grep cpu3
c3a592236333 centos "/bin/bash" 8 minutes ago Up 8 minutes cpu3
[root@xuegod63 ~]# ls /sys/fs/cgroup/cpu/docker/ | grep c3a592236333
c3a5922363332d3764bcaa40bb24f32ebf885e0b9dd91b3b2d61764715d4b42a
echo 512 > /sys/fs/cgroup/cpu/docker/c3a5922363332d3764bcaa40bb24f32ebf885e0b9dd91b3b2d61764715d4b42a/cpu.shares
再在物理上查看cpu使用率:
可以看到两个容器的CPU占比趋于平均。
3.5 当容器中服务或命令运行结束后,自动删除容器
--rm 当容器命令运行结束后,自动删除容器
[root@xuegod63 ~]# docker run --help | grep rm
--rm Automatically remove the container when it exits
作用:当容器命令运行结束后,自动删除容器。应用场景:在某些环境下,可能需要大量的新建docker虚拟机,然后仅仅运行几秒钟,然后就彻底删除,如运行单元测试等,测试弹性云计算,需要创建1万虚拟机,运行1个小时,模拟双11的压力。1小时后自动删除。
docker UI web 10000.
例:
[root@xuegod63 ~]# docker run -it --rm --name mk centos sleep 5
物理上查看:
[root@xuegod63 ~]# docker ps | grep mk
6c75a9317a6b centos "sleep 5" 6 seconds ago Up 4 seconds mk
等5s后,再查看:
[root@xuegod63 ~]# docker ps | grep mk#自动删除了
4 内存
Docker提供参数-m, --memory=""限制容器的内存使用量。
例1:允许容器使用的内存上限为128M:
[root@xuegod63 ~]# docker run -itd -m 128m centos
83aefc3fd639c061271a7cd8a2418d328647ebf3fa5974779e89e3db0350dd56
查看:
[root@xuegod63 ~]# cat /sys/fs/cgroup/memory/docker/83aefc3fd639c061271a7cd8a2418d328647ebf3fa5974779e89e3db0350dd56/memory.limit_in_bytes
134217728
注:也可以使用tress进行测试--vm
5 限制硬盘读写速度IO
[root@xuegod63 ~]# docker run --help | grep write-b
--device-write-bps value Limit write rate (bytes per second) to a device (default [])#限制此设备上的写速度(bytes per second),单位可以是kb、mb或者gb。
情景:防止某个Docker 容器吃光你的磁盘I / O资源
例1:设置容器硬盘的最高读取速度设定为1MB/s。
[root@xuegod63 ~]# docker run -it --name disk1 --device-write-bps/dev/sda:1mb centos /bin/bash
[root@4252ae898a45 /]# time $(dd if=/dev/zero of=f1.txt bs=1M count=100 && sync)#测试
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 0.744085 s, 141 MB/s
real0m4.981s#使用5s左右。1秒写20M
user0m0.006s
sys0m0.810s
6 docker 数据映射
语法:docker run -itd -v /src:/dstcentos bash // -v 用来指定挂载目录, 冒号:前面的/src为本地目录,冒号:后面的/dst为容器里的目录
例1:把物理机上的/var/www/html映射到/opt
[root@xuegod63 ~]# docker run -it --name data_test3 -v /var/www/html:/opt centos bash
[root@f8709b5ab0b1 /]# touch /opt/index.html
物理机查看:
[root@xuegod63 ~]# ls /var/www/html/
index.html
总结:
本节所讲内容:
1、docker容器命名和重命名
2、创建docker容器实例时挃定主机名
3、docker容器资源配额控制之cpu
4、docker容器资源配额控制之内存
5、docker容器资源配额控制之IO
6、docker 数据映射