docker学习-docker容器运行
docker run是启动容器的方法,可以用三种指定的方式指定容器启动时执行的命令。
(1)CMD指令
(2)ENTRYPOINT指令
(3)在docker run中命令行中指定
但是docker run并不能长期保持running状态,我们经常需要进入到容器中去做一些工作,比如查看日志、调试、启动其他进程等。有两种进入容器的方式:attach和exec。
为芮城等地区用户提供了全套网页设计制作服务,及芮城网站建设行业解决方案。主营业务为成都网站设计、成都网站建设、芮城网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!
docker attach
首先启动一个容器,保持后台长期运行
docker run -d ubuntu /bin/bash -c "while true; do sleep 1; echo i_am_a_container;done
首先检查容器的ID
docker ps -a
CONTAINER ID就是容器的编号,其实就是容器ID前12个字符,又叫短ID
IMAGE就是base IMAGE
NAMES是容器的名称,在启动容器的时候可以通过 --name参数显式的为容器命名。
通过docker attach可以attach到容器启动命令的终端。
docker attach 1e5cc7e3b22b
通过短ID attach到了容器的启动命令终端,之后看到的是echo每秒输出一次打印信息
可以通过ctl+p,然后ctl+q退出attach终端
docker exec
通过docker exec进入相同的容器
docker exec -it 1e5cc7e3b22b bash
说明
1、-it 以交互的形式打开终端,执行bash
2、可以像普通linux一样执行命令,显示了容器启动的进程
3、退出容器
docker exec命令格式如下:
docker exec -it bash |sh
attach vs exec
两者的主要区别如下:
1、attch直接进入容器启动命令的终端,不会启动新的进程
2、exec则是在容器中打开新的终端,而且可以启动新进程
3、如果想直接在终端中查看启动命令的输出,用attach,其他情况用exec
运行容器的最佳实践
按用途容器大致可以分为两类:服务类容器和工具的容器
前者以daemon的形式运行,对外提供服务,比如Web Server、数据库等。通过-d 以后台的方式启动这类容器是非常合适的,如果要排查问题,可以通过exec -it进入容器
后者容器通常能给我们提供一个临时的工作环境,通常以run -it方式进行
工具类容器多使用基础镜像,例如busybox,debian,ubuntu等
总结如下:
(1)当CMD,Entypoint和docker run命令行指定的命令运行结束时,容器停止
(2)通过-d参数在后台启动容器
(3)通过exec -it可以进入容器并执行命令
容器生命周期
stop/start/restart容器
docker stop:停止运行中的容器,容器在docker host中其实就是一个进程,该命令本质上是像该进程发送一个SIGTERM信号,也可通过docker kill命令快速停止容器
docker start: 对于停止的容器。可以通过该命令进行启动,会保留容器的第一次启动时的参数
docker restart :重启容器
pause/unpause容器
docker pause:让容器暂停,如需要对容器的文件系统打快照
unpause:处于pause状态的容器不会占用CPU资源,直到通过dokcer unpause恢复运行
删除容器
docker rm:使用docker一段时间后,host上可能会有大量已经退出的容器,这些容器依然会占用host的文件系统资源,可以使用docker rm进行删除
如果希望一次删除多个容器,则可以使用如下命令
docker rm -v $(docker ps -aq -f status=exited)
容器的状态机制
整个容器的生命周期状态机制,如下所示:
资源限制
一个docker host上会运行若干容器,每个容器都需要cpu,内存和IO资源。Docker提供了类似的机制避免某个容器因占用太多资源而影响到其他容器或者整个HOST的资源
内存限额
与操作系统类似,容器可使用的内存包括两个部分:物理内存和swap。Docker通过下面的两组参数来控制容器内存的使用量
(1)-m或 --memory:设置内存的使用限制
(2)--memory-swap:设置内存+swap的使用限制
例如:
docker run -m 200M --memory-swap=300M ubuntu
含义时允许该容器最多使用200M的内存和300MB的 swap。默认情况下,上面两组参数为-l,即对容器内存和swap的使用没有限制
测试使用progrium/stress镜像,该镜像可以用于对容器执行压力测试
docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 280M
说明:
1、--vm1:启动1个内存工作线程
2、--vm-bytes 280M,每个线程分配280MB内存
过程:
1分配280M内存
2释放280M内存
3再分配280M内存
4再释放
5 一致持续循环
cpu限制
默认设置下,所有的容器可以平等的使用hostCPU资源,而且没有限制
docker可以通过-c或者--cpu-shares设置容器使用cpu的权重,如果不指定,默认值1024
与内存限额不同,通过-c设置的cpu share并不是cpu资源的绝对数量,而是一个相对的权重值。某个容器最终能分配的到的CPU资源取决于它的cpu share总和和比例,换句话说通过cpu share可以设置容器使用CPU的优先级
docker run --name "container_A" -c 1024 ubuntu && docker run --name "container_B" -c 512 ubuntu
container_A的cpu share 1024,是containerB的两倍,当两个容器都需要CPU资源时,前者可以得到的cpu是后者的两倍
需要特别注意的是,这种按权重分配CPU的只会发生在CPU资源紧张的情况下。如果containerA处于空闲状态,这时为了充分利用CPU资源,containrB也可以分配到全部可用的cpu
Block IO带宽限制
Block IO是另一种可以限制容器资源,它是指磁盘的读写,docker可以通过设置权重,限制bsp和iops的方式控制容器读写磁盘的带宽。
IO权重
默认情况下,所有的容器能平等的读写磁盘,可以通过设置 --blkio-weight 参数来改变容器的block IO的优先级
--blkio-weight与--cpu-share类似,设置的是相对权重,默认为500
docker run -it --name container_A --blkio-weight 600 ubuntu && docker run --it --name container_B --blkio-weight 300 ubuntu
通过命令行设定,containerA的读写磁盘带宽是containerB的两倍
限制bps和iops
bsp是byte per second ,每秒读写的数据量
iops是ip per second,每秒IO的次数
可以通过以下参数控制容器的bsp和 iops
--device-read-bps,限制读某个设备的 bps。
--device-write-bps,限制写某个设备的 bps。
--device-read-iops,限制读某个设备的 iops。
--device-write-iops,限制写某个设备的 iops。
cgroup和namespace
cgropu和namespace是实现容器底层的最重要的两种技术。cgroup实现资源限制,namespace实现资源的隔离
cgroup
cgroup 全称 Control Group。Linux 操作系统通过 cgroup 可以设置进程使用 CPU、内存 和 IO 资源的限额。前面我们看到的--cpu-shares、-m、--device-write-bps 实际上就是在配置 cgroup。
可以在/sys/fs/cgroup中找到
docker run -it --cpu-shares 512 progrium/stress -c 1
记录容器ID。在 /sys/fs/cgrouXXXpu/docker 目录中,Linux 会为每个容器创建一个 cgroup 目录,以容器长ID 命名:
目录中包含所有与 cpu 相关的 cgroup 配置,文件 cpu.shares 保存的就是 --cpu-shares 的配置,值为 512。
同样的,/sys/fs/cgroup/memory/docker 和 /sys/fs/cgroup/blkio/docker 中保存的是内存以及 Block IO 的 cgroup 配置
namespace
在每个容器中,我们都可以看到文件系统,网卡等资源,这些资源看上去是容器自己的。拿网卡来说,每个容器都会认为自己有一块独立的网卡,即使 host 上只有一块物理网卡。这种方式非常好,它使得容器更像一个独立的计算机。
Linux 实现这种方式的技术是 namespace。namespace 管理着 host 中全局唯一的资源,并可以让每个容器都觉得只有自己在使用它。换句话说,namespace 实现了容器间资源的隔离。
Linux 使用了六种 namespace,分别对应六种资源:Mount、UTS、I*、PID、Network 和 User。
Mount namespace
Mount namespace 让容器看上去拥有整个文件系统。
容器有自己的 / 目录,可以执行 mount 和 umount 命令。当然我们知道这些操作只在当前容器中生效,不会影响到 host 和其他容器。
UTS namespace
简单的说,UTS namespace 让容器有自己的 hostname。 默认情况下,容器的 hostname 是它的短ID,可以通过 -h 或 --hostname 参数设置。
I P C namespace
IPC namespace 让容器拥有自己的共享内存和信号量(semaphore)来实现进程间通信,而不会与 host 和其他容器的 IPC 混在一起。
PID namespace
能够使容器能够拥有自己的PID
Network namespace
Network namespace 让容器拥有自己独立的网卡、IP、路由等资源。我们会在后面网络章节详细讨论。
User namespace
User namespace 让容器能够管理自己的用户,host 不能看到容器中创建的用户。
常用命令
以下是容器的常用操作命令
create 创建容器
run 运行容器
pause 暂停容器
unpause 取消暂停继续运行容器
stop 发送 SIGTERM 停止容器
kill 发送 SIGKILL 快速停止容器
start 启动容器
restart 重启容器
attach attach 到容器启动进程的终端
exec 在容器中启动新进程,通常使用 "-it" 参数
logs 显示容器启动进程的控制台输出,用 "-f" 持续打印
rm 从磁盘中删除容器
本文题目:docker学习-docker容器运行
本文网址:http://hbruida.cn/article/jsdgcg.html