docker学习-docker容器运行

docker run是启动容器的方法,能够用三种指定的方式指定容器启动时执行的命令。
(1)CMD指令
(2)ENTRYPOINT指令
(3)在docker run中命令行中指定
可是docker run并不能长期保持running状态,咱们常常须要进入到容器中去作一些工做,好比查看日志、调试、启动其余进程等。有两种进入容器的方式:attach和exec。linux

docker attach

首先启动一个容器,保持后台长期运行docker

docker run -d ubuntu /bin/bash -c "while true; do sleep 1; echo i_am_a_container;done

首先检查容器的ID数据库

docker ps -a

docker学习-docker容器运行

CONTAINER ID就是容器的编号,其实就是容器ID前12个字符,又叫短ID
IMAGE就是base IMAGE
NAMES是容器的名称,在启动容器的时候能够经过 --name参数显式的为容器命名。ubuntu

经过docker attach能够attach到容器启动命令的终端。bash

docker attach 1e5cc7e3b22b

docker学习-docker容器运行
经过短ID attach到了容器的启动命令终端,以后看到的是echo每秒输出一次打印信息
能够经过ctl+p,而后ctl+q退出attach终端网络

docker exec

经过docker exec进入相同的容器ide

docker exec -it 1e5cc7e3b22b bash

docker学习-docker容器运行
说明
一、-it 以交互的形式打开终端,执行bash
二、能够像普通linux同样执行命令,显示了容器启动的进程
三、退出容器工具

docker exec命令格式以下:学习

docker exec -it <container> bash |sh

attach vs exec

二者的主要区别以下:
一、attch直接进入容器启动命令的终端,不会启动新的进程
二、exec则是在容器中打开新的终端,并且能够启动新进程
三、若是想直接在终端中查看启动命令的输出,用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学习-docker容器运行

资源限制

一个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

说明:
一、--vm1:启动1个内存工做线程
二、--vm-bytes 280M,每一个线程分配280MB内存
docker学习-docker容器运行
过程:
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 命名:
docker学习-docker容器运行
目录中包含全部与 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 从磁盘中删除容器

相关文章
相关标签/搜索