Docker容器
Docker启动容器
docker run命令启动容器,添加参数--name可以根据容器的性质和用途自行给容器命名,如果没有用--name参数,docker会自动给容器起名
进入容器的两种方法:attach、exec
通过docker attach可以attach到容器启动命令的终端,可通过Ctrl+p然后Ctrl+q组合键退出attach终端
通过docker exec进入相同的容器,说明如下:
1. -it以交互模式打开pseudo -TTY,执行bash,其结果就是打开一个bash终端
2. 进入容器中,容器的hostname就是“短ID”
3. 可以像在普通的Linux中一样执行命令
4. 执行exit退出容器,回到Docker host
docker exec -it <container> bash | sh是执行exec最常用的方式
attach与exec的区别
1. attach直接进入容器启动命令的终端,不会启动新的进程
2. exec则是在容器中打开新的终端,并且可以启动新的进程
3. 如果想直接在终端查看启动命令的输出,可以使用docker logs命令,-f参数可以持续打印输出
按用途容器大致可以分为两类:服务类容器和工具类容器
1. 服务类容器以daemon的形式运行,对外提供服务。比如web server,数据库等。通过-d参数以守护方式启动这类容器非常合适。如果需要排查问题,可以通过exec -it进入容器
2. 工具类容器通常给我们提供一个临时的工作环境,通常以run -it方式运行
容器常用的操作
stop/start/restart
通过docker stop可以停止运行的容器。容器在Docker host中实际上是一个进程,docker stop命令本质上是向该进程发送一个SIGTERM信号,如果想快速停止容器,可以使用docker kill命令
对于停止的容器,可以通过docker start启动,docker start会保留容器第一次启动时的所有参数
docker restart用于重启容器。用docker run命令启动容器时,可以加上参数--restart=always,意味着不论容器因何种原因退出,都立即重启。该参数的形式还可以是--restart=no-failure:3,意思是如果启动进程退出代码非0,则重启容器,最多重启三次
pause/unpause容器
docker pause可以让容器暂时停止工作,处于暂停状态的容器不会占用CPU资源,直到通过docker unpause恢复运行
删除容器
退出的容器依然会占用Docker host的文件系统资源,如果确定不再使用这些容器,可以使用docker rm来删除,docker rm一次可以指定多个容器,如果希望批量删除停止的容器,可以使用以下命令
docker rm -v $(docker ps -aq -f status=exited)
限制容器对内存的使用
内存限额
容器可使用内存包括两部分:物理内存和swap。Docker通过以下两个参数来控制容器内存的使用量
1. -m或--memory:设置内存的使用限额,如1G
2. --memory-swap:设置内存+swap使用限额
当我们执行docker run -m 200M --memory-swap=300M ubuntu,其含义是允许容器最多使用200M的内存和100M的swap。默认以上两个参数都为-1,即对容器的内存和swap的使用没有限制
下面使用progrium/stress镜像来学习如何为容器分配内存,该镜像可对容器执行压力测试,执行命令如下
docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 280M
--vm 1:启动一个工作线程
--vm-bytes 280M:每个线程分配280M内存
运行结果如下
因为280M在可分配范围(300M)内,因此工作线程可以正常工作,其过程为
1. 分配280M内存
2. 释放280M内存
3. 再分配280M内存
4. 再释放280M内存
5. 一直循环……
如果我们分配的内存超过300M,结果如下
如果分配内存超过限额,stress线程报错,容器自动退出
如果启动容器时只指定了-m参数而没有指定--memory-swap参数,那么--memory-swap默认是-m的两倍
限制容器CPU的使用
Docker可以通过-c或-cpu-shares设置容器使用CPU的权重。如果不指定,默认为1024。与内存限额不同的是,通过-c设置的cpu share并不是一个绝对的数值,而是一个相对的权重值。某个容器最终能分配到的CPU取决于它的cpu share占所有cpu share总和的比例。也就是说,通过cpu share可以设置容器cpu使用的优先级
下面继续用progrium/stress来做测试
1. 启动container_A,cpu share为1024
其中--cpu为当前host的CUP颗数,本机为2颗
2. 启动container_B,cpu share为512
3. 在host中执行top,查看容器对CPU的使用情况
container_A消耗是container_B的两倍
4. 暂停container_A
5. top显示container_B在container_A空闲时能够用满整个CPU
限制容器Block IO
block IO权重
默认情况下,所有容器能平等地读写磁盘,可以通过设置--blkio-weight参数来改变容器block IO的优先级。--blkio-weight与--cpu-shares类似,设置的是相对权重值,默认是500。下面例子是container_A读写磁盘的带宽是container_B的两倍
docker run -it --name container_A --blkio-weight 600 ubuntu docker run -it --name container_B --blkio-weight 300 ubuntu
限制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测试在容器中写磁盘的速度,oflag=direct指定用direct IO方式写文件,这样--device-write-bps才能生效。结果表明bps=23.3MB/s,没有超过30MB/s的限速
作为对比,如果不限速
cgroup实现资源限额,namespace实现资源隔离
Docker容器小结
下面是容器常用的操作命令
create:创建容器 run:运行容器 pause:暂停容器 unpause:取消暂停继续运行容器 stop:停止容器 kill:快速停止容器 start:开启容器 restart:重启容器 attach:attach到容器启动进程的终端 exec:在容器中启动新进程,通常使用-it参数 logs:显示容器启动进程的控制台输出,用-f持续打印 rm:删除容器