一、Docker容器命名和重命名
1、docker容器命名和重命名
命名语法:docker run -d --name 容器实例名 容器镜像名 要执行的命令
重命名语法:docker rename 旧容器名 新容器名
1.运行一个名为docker1的容器
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 5d0da3dc9764 15 months ago 231MB
hub.c.163.com/library/tomcat latest 72d2be374029 5 years ago 292MB
[root@localhost ~]# docker run -itd --name docker1 centos bash
025394ef749c67d7078d0b4dabd2e24a17a7f0e33ea153eb1f85f70248817041
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
025394ef749c centos "bash" 15 seconds ago Up 14 seconds docker1
2.重命名容器docker1
[root@localhost ~]# docker rename docker1 docker2
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
025394ef749c centos "bash" About a minute ago Up About a minute docker2
2、创建docker容器实例时指定容器主机名
语法:docker run -it --name 容器名 -h 指定主机名 镜像 /bin/bash
[root@localhost ~]# docker run -itd --name docker4 -h docker15.cn hub.c.163.com/library/tomcat bash
c95e2fd46297fb56d2a036ec25d13baf928b948e2dc1aeadb7a6206d8a739882
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c95e2fd46297 hub.c.163.com/library/tomcat "bash" 5 seconds ago Up 4 seconds 8080/tcp docker4
025394ef749c centos "bash" 7 minutes ago Up 7 minutes docker2
3、docker容器开机自动启动
语法:docker run --restart=always -itd --name 容器名 镜像 /bin/bash
参数: --restart=always #在容器退出时总是重启容器
[root@localhost ~]# docker run --restart=always -itd --name docker5 centos bash
d76433aa21c15ab2f0bc9b378349beabcc110aebaa20e0bfd13fc87e2bff7a52
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d76433aa21c1 centos "bash" 22 seconds ago Up 21 seconds docker5
c95e2fd46297 hub.c.163.com/library/tomcat "bash" 5 minutes ago Up 5 minutes 8080/tcp docker4
025394ef749c centos "bash" 13 minutes ago Up 13 minutes docker2
[root@localhost ~]# systemctl restart docker
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d76433aa21c1 centos "bash" 58 seconds ago Up 1 second docker5
#####重启服务后,只剩一个docker5在运行
Docker容器重启策略:
no --> 默认策略,在容器退出时不重启容器
on-failure --> 在容器非正常退出时(退出状态非0),才会重启容器
on-failure:3 --> 在容器非正常退出时重启容器,最多重启3次
always --> 在容器退出时总是重启容器
unless-stopped --> 在容器退出时总是重启容器,但是不考虑在docker守护进程启动时就已经停止的容器
#可以通过update命令重置策略
语法:docker update --restart=always 容器ID或名字
二、Docker容器资源配额控制 --CPU
Docker通过cgroup来控制容器使用的资源配额,包括CPU,内存,磁盘三大方面,基本覆盖了常见的资源配额和使用量控制
cgroup概述:cgroup是Control Group的缩写,是Linux内核提供的一种可以限制,记录,隔离进程组所使用的物理资源的机制,如:cpu、memory、磁盘IO等。被LXC,docker等很多项目用于实现进程资源控制。cgroup将任意进程进行分组化管理的Linux内核功能。cgroup本身是提供将进程进行分组化管理的功能和接口的基础结构,I/O或内存的分配控制等具体的资源管理功能是通过这个功能实现。
1、指定docker容器可以使用的cpu份额
给容器分配512权重的cpu使用份额
cpu配额参数:-c , --cpu-shares int CPU shares (relative weight) 在创建容器时指定容器所使用的CPU份额值。cpu-shares的值不能保证可以获得一个vcpu 或者多少GHz的CPU资源,仅仅只是一个弹性的加权值。
默认每个docker容器的cpu份额值都是1024,在同一个cpu核心上,同时运行多个容器时,容器的cpu加权的效果才能体现出来。
1.1、两个容器A、B的cpu份额分别为1000和500,结果如何?
情况1:A和B正常运行,在cpu进行时间片分配的时候,容器A比容器B多一倍的机会获得CPU的时间片。
情况2:分配的结果取决于当时其他容器的运行状态。如A的进程一直是空闲的,那么B是可以获取比A更多的cpu时间片,比如主机上只运行了一个容器,即使它的cpu份额只有50,它也可以独占整个主机的cpu资源。
cgroup只在多个容器同时争抢同一个cpu资源时,cpu配额才会生效,因此,无法单纯根据某个容器的cpu份额来确定有多少cpu资源分配给它,资源分配结果取决于同时运行的其他容器的cpu分配和容器中进程运行的情况。
例1:给容器实例分配512权重的cpu使用份额
参数: --cpu-share 512
[root@localhost ~]# docker run -it --cpu-shares 512 centos bash
[root@fd1264e2ada1 /]# cat /sys/fs/cgroup/cpu/cpu.shares
512
2、CPU core 核心控制
参数:--cpuset 可以绑定CPU
对多核cpu服务器,docker还可以控制容器运行限定使用哪些cpu内核的内存节点,即使用 --cpuset-cpus 和 --cpuset-mems 参数。对具有NUMA拓扑(具有多CPU,多内存节点)的服务器尤其有用,可以对需要高性能计算的容器进行性能最优的配置,如果服务器只有一个内存节点,则--cpuset-mems 的配置基本不会有明显效果。
taskset设定cpu亲和力,taskset能够将一个或多个进程绑定到一个或多个处理器上运行。
参数:
-c , --cpu-list 以列表格式显示和指定cpu
-p , --pid 在已经存在的pid 上操作
例1:设置只在cpuID是1和2的cpu上运行sshd进程程序,第一个cpu是0。
[root@filebeat ~]# ps -aux | grep sshd #查看pid号
root 1177 0.0 0.1 105996 4072 ? Ss 22:30 0:00 /usr/sbin/sshd -D
[root@filebeat ~]# taskset -cp 1177 #不指定cpu是查看进程当前使用cpu
pid 1177's current affinity list: 0-7
[root@filebeat ~]# taskset -cp 1,2 1177 #指定sshd在cpu1,2上运行
pid 1177's current affinity list: 0-7
pid 1177's new affinity list: 1,2
为什么把进程绑定到cpu上,运行效率会高?
当cpu数量很多时,需要绑定进程到cpu上,这样可以减少cpu上下文(缓存)切换的开销,节约时间。
例2:物理机有8个核心,创建的容器只能用0、1、2这三个核心
[root@filebeat ~]# docker run -it --name cpu1 --cpuset-cpus 0-2 centos /bin/bash
[root@01d74975624f /]# cat /sys/fs/cgroup/cpuset/cpuset.cpus
0-2
[root@01d74975624f /]# taskset -cp 1
pid 1's current affinity list: 0-2
3、CPU配额控制参数的混合使用
当上面这些参数,cpu-shares 控制只发生在容器竞争同一个cpu的时间片时有效。
如果通过cpuset-cpus 指定容器A使用cpu0 ,容器B指定用cpu1,在主机上只有这两个容器使用对应内核的情况,它们各自占用全部的内核资源,cpu-shares 没有明显效果。
如何才能有效果?
容器A和容器B配置上cpuset-cpus 值并都绑定到同一个cpu上,然后同时抢占cpu资源,就可以有效果了。
测试cpu-shares 和 cpuset-cpus 混合使用运行效果,需要一个压缩力测试工具stress来让容器实例把 cpu 跑满。
Linux系统压力测试软件Stress,可以测试Linux系统 cpu/memory/IO/disk 的负载。
#使用epel源安装stress
[root@localhost ~]# yum install epel-release -y
[root@localhost ~]# yum install -y stress
stress参数:
-? 显示帮助信息
-v 显示版本号
-q 不显示运行信息
-n 显示已完成的指令情况
-t --timeout N 指定运行N秒后停止
--backoff N 等待N微妙后开始运行
-c 产生 n 个进程 ,每个进程都反复不停的计算随机数的平方根,测试cpu
-i 产生 n 个进程 ,每个进程反复调用 sync(),sync()用于将内存上的内容写到硬盘上,测试硬盘
-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@localhost ~]# stress -c 2 -i 2 --verbose --timeout 20s
stress: info: [112137] dispatching hogs: 2 cpu, 2 io, 0 vm, 0 hdd
stress: dbug: [112137] using backoff sleep of 12000us
stress: dbug: [112137] setting timeout to 20s
stress: dbug: [112137] --> hogcpu worker 2 [112138] forked
stress: dbug: [112137] --> hogio worker 2 [112139] forked
stress: dbug: [112137] using backoff sleep of 6000us
stress: dbug: [112137] setting timeout to 20s
stress: dbug: [112137] --> hogcpu worker 1 [112140] forked
stress: dbug: [112137] --> hogio worker 1 [112141] forked
stress: dbug: [112137] <-- worker 112141 signalled normally
stress: dbug: [112137] <-- worker 112140 signalled normally
stress: dbug: [112137] <-- worker 112138 signalled normally
stress: dbug: [112137] <-- worker 112139 signalled normally
stress: info: [112137] successful run completed in 20s
例2:创建两个容器实例:docker10 和 docker20 ,让docker10和 docker20 只运行在cpu0 和 cpu1 上,最终测试 docker10 和 docker20使用 cpu 的百分比。
docker run -itd --name docker10 --cpuset-cpus 0,1 --cpu-shares 512 centos /bin/bash
docker run -itd --name docker20 --cpuset-cpus 0,1 --cpu-shares 1024 centos /bin/bash
yum -y install epel-release
yum -y install stress
stress -c 2 -v -t 10m #运行两个进程把cpu占满
进入docker20,使用stress测试进程是不是只在cpu0,1上运行,且docker20 上运行的stress使用cpu百分比
是docker10的2倍
总结:两个容器只在cpu0,1 上运行,说明cpu绑定限制成功,而docker20 是 docker10 使用cpu的2倍,说明--cpu-shares 限制资源成功。