docker run 是启动容器的方法,容器启动后返回的是 “长 ID”,我们可以通过这个长 ID 去访问这个容器,也可以通过启动时指定的名字访问这个容器。docker ps 能够看到容器的 “短 ID”,通过短 ID 同样可以访问这个容器,甚至只要能够唯一标识这个容器也可使用更短的 ID。

docker run 中的 —name 指定了镜像的 NAMES
文中示例的“长 id ”就是:
d019223e9f72ded7ac037235f766b0314db99de21905111b97491ba9cebb5571
文中示例的“短 id ”则是:
d019223e9f72
如需使用“更短 id ”,则可截取“短 id ”的前 4 位
-d 指定容器以后台方式运行;
--restart 指定容器的重启策略,默认值 no,容器退出时不要重启。
on-failure [:max-retries] 只在容器以非 0 状态码退出时重启。max-retries 可以指定尝试重启容器的次数;always 不管退出状态码是什么始终重启容器。当指定容器退出后,docker daemon 将无限次数地重启容器。例:「—restart=on-failure:3」
--name 指定容器的名称。
容器的生命周期依赖于启动时执行的命令,只要该命令不结束,容器也就不会退出。理解了这个原理,我们就可以通过执行一个长期运行的命令来保持容器的运行状态。
我们经常需要进到容器里去做一些工作,比如查看日志、调试、启动其他进程等。有两种方法进入容器:attach 和 exec。
通过 docker attach 可以 attach 到容器启动命令的终端,可通过 Ctrl+p 然后 Ctrl+q 组合键退出 attach 终端。

用法:docker attach [容器名 | 容器 ID]
例如:docker attach 7c38

通过 docker exec 进入相同的容器。docker exec -ti [容器名 | 容器 ID] bash 是执行 exec 最常用的方式。-ti 以交互模式打开 pseudo-TTY,执行 bash,其结果就是打开了一个 bash 终端。

用法:docker exec -it [容器名 | 容器 ID] bash
例如:docker exec -it 7c38 bash

attach 与 exec 主要区别如下:
attach 直接进入容器 启动命令的终端,不会启动新的进程。
exec 则是在容器中打开新的终端,并且可以启动新的进程。
启动、停止、重启、杀死容器:
docker start|stop|restart|kill [容器名|容器ID]



有时我们只是希望暂时让容器暂停工作一段时间,比如要对容器的文件系统打个快照,这时可以执行 docker pause,打完之后就可以唤醒容器。
挂起、唤醒容器:
docker pause/unpause [容器名|容器ID]

docker rm -f [容器名|容器ID]-f 参数可以强制删除运行中的容器。
可以用如下命令删除所有已退出的容器(慎用):
docker rm $(docker ps -a -q -f status=exited)可以用如下命令强制删除所有容器(慎用):
docker rm -f $(docker ps -a -q)docker rm 是删除容器,而 docker rmi 是删除镜像
对容器的生命周期有了大致的理解,下面这张状态机很好地总结了容器各种状态之间是如何转换的。
容器有五种状态:已创建、运行中、已挂起、已停止、已销毁。
我们可以通过执行命令让 docker 在这五种状态间转换。

docker run 是 docker pull(如果镜像不存在)、docker create、docker start 的复合命令
在开始之前,我们先制作一个 stress 的 docker 镜像,用于后面的压测
$ mkdir $(date +%F)
$ cd $(date +%F)
$ cat > Dockerfile << 'EOF'
# 使用官方的 Ubuntu 镜像作为基础镜像
FROM ubuntu
# 设置环境变量,避免交互式配置提示
ENV DEBIAN_FRONTEND=noninteractive
# 更新包列表并安装 stress
RUN apt-get update && \
apt-get install -y --no-install-recommends \
stress && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# 设置默认的工作目录
WORKDIR /stress
# 默认命令:显示帮助信息
CMD ["stress", "--help"]
EOF
$ docker build -t my-stress:latest .
查看镜像
$ docker images
与操作系统类似,容器可使用的内存包括两部分:物理内存和 swap。
Docker 通过下面两组参数来控制容器内存的使用量。
-m 或 --memory:设置内存的使用限额,例如 100M, 2G。
--memory-swap:设置 内存 + swap 的使用限额。
当我们执行下面命令:
docker run -m 200M --memory-swap=300M centos其含义是允许该容器最多使用 200M 的内存和 100M 的 swap。默认情况下,上面两组参数为 -1,即对容器内存和 swap 的使用没有限制。如果在启动容器时只指定 -m 而不指定 --memory-swap,那么 --memory-swap 默认为 -m 的两倍。
内存限额测试:
docker run --name stress -it -m 300M my-stress stress --vm 1 --vm-bytes 280M --timeout 30未超过限额,容器启动成功

docker run --name stress -it -m 300M my-stress stress --vm 1 --vm-bytes 1G --timeout 30超过限额,容器失败退出

Docker 可以通过 -c 或 --cpu-shares 设置容器使用 CPU 的权重。如果不指定,默认值为 1024。
与内存限额不同,通过 -c 设置的 cpu share 并不是 CPU 资源的绝对数量,而是一个相对的权重值。某个容器最终能分配到的 CPU 资源取决于它的 cpu share 占所有容器 cpu share 总和的比例。
CPU 限额测试:
# 启动cpu_a,--cpu-shares为1024
# --cpu 用来设置工作线程的数量,宿主机是 16 核 CPU,设置为 16 表示使用所有 CPU
docker run --name cpu_a -it -c 1024 -d my-stress stress --cpu 16
# 启动cpu_b,cpu-shares为512
# --cpu 用来设置工作线程的数量,宿主机是 16 核 CPU,设置为 16 表示使用所有 CPU
docker run --name cpu_b -it -c 512 -d my-stress stress --cpu 16
查看容器资源的使用情况
docker stats
可以看到,当 CPU 资源紧张时,--cpu-shares 设置为 1024 的容器占用 CPU 的时间大约是设置为 512 的容器的两倍。
Block IO 是另一种可以限制容器使用的资源。Block IO 指的是磁盘的读写,docker 可通过设置权重、限制 bps 和 iops 的方式控制容器读写磁盘的带宽。
目前 Block IO 限额只对 direct IO(不使用文件缓存)有效。
默认情况下,所有容器能平等地读写磁盘,可以通过设置 --blkio-weight 参数来改变容器 block IO 的优先级。
--blkio-weight 与 --cpu-shares 类似,设置的是相对权重值,默认为 500。在下面的例子中,blockio_a 读写磁盘的带宽是 blockio_b 的两倍。
docker run -it --name blockio_a --blkio-weight 600 ubuntu
docker run -it --name blockio_b --blkio-weight 300 ubuntu可通过以下参数控制容器的 bps 和 iops:
--device-read-bps,限制读某个设备的 bps
--device-write-bps,限制写某个设备的 bps
--device-read-iops,限制读某个设备的 iops
--device-write-iops,限制写某个设备的 iops
磁盘 IO 限额测试:

失败了,具体原因不明⋯⋯
cgroup 实现资源限额:
通过 cgroup 可以设置进程使用 CPU、内存 和 IO 资源的限额
--cpu-shares、-m、--device-write-bps 实际上就是在配置 cgroup
cgroup 配置目录:/sys/fs/cgroup/cpu|memory|blkio/docker
namespace 实现资源隔离:
Mount 让容器看上去拥有整个文件系统
UTS 让容器有自己 hostname
IPC 让容器有自己的共享内存和信号量
PID 让容器有自己的进程空间
Network 让容器有自己的网络空间
User 让容器有自己的用户