Docker 容器的生命周期
什么是容器?
通俗地讲,容器是镜像的运行实体。镜像是静态的只读文件,而容器带有运行时需要的可写文件层,并且容器中的进程属于运行状态。即容器运行着真正的应用进程。容 器有初建、运行、停止、暂停和删除五种状态。 虽然容器的本质是主机上运行的一个进程,但是容器有自己独立的命名空间隔离和资 源限制。也就是说,在容器内部,无法看到主机上的进程、环境变量、网络等信息, 这是容器与直接运行在主机上进程的本质区别。 容器是基于镜像创建的可运行实例,并且单独存在,一个镜像可以创建出多个容器。 运行容器化环境时,实际上是在容器内部创建该文件系统的读写副本。 这将添加一个 容器层,该层允许修改镜像的整个副本。
容器与镜像的关系类似于程序与代码的关系。代码(镜像)是静态的,包含了程序运行所需要的所有指令和数据;而程序(容器)是动态的,是代码在特定环境下的运行实例。通过镜像创建容器,我们可以方便地部署和管理应用程序,并确保每个应用程序都在一致和隔离的环境中运行。
在学习容器的常见命令之前,我们先来看看容器的生命周期吧!
容器的生命周期是容器可能处于的状态:
- created:初建状态。
- running:运行状态。
- stopped:停止状态。
- paused:暂停状态。
- deleted:删除状态。
各个生命周期的转换关系如图所示:
- docker create:创建容器后,不立即启动运行,容器进入初建状态。
- docker run:创建容器,并立即启动运行,进入运行状态。
- docker start:容器转为运行状态。
- docker stop:容器转入停止状态。
- docker kill:容器在故障时,执行 kill,容器将进入停止状态,这种操作容易丢失数据,除非必要,否则不建议使用。
- docker restart:重启容器,容器转入运行状态。
- docker pause:容器进入暂停状态。
- docker unpause:取消暂停状态,容器进入运行状态。
- docker rm:删除容器,容器进入删除状态。
- killed by out-of-memory:宿主机内存被耗尽,也被成为 OOM:非计划终止,这是会杀掉占用内存最多的容器。
- container process exited:出现容器被终止后,将进入是否应该 restart 的选择。
- yes:需要重启,容器执行 start 命令,转为运行状态。
- no:不需要重启,容器转为停止状态。
Docker 在处理 OOM 事件分为 3 中情况:
-
如果容器中的应用耗尽了主机系统分配给容器的内存限额,就会触发 OOM 事件。 例如,在容器当中,部署了一个 web 服务。假设主机分配给此容器的内存上限为 1G, 当脚本申请的内存大于 1G 时,此容器就会触发 OOM 事件。而在这种情况下,此容器将会被强制关闭。 但需要注意的是,此时关闭容器的并非是 Docker Daemon,而是宿主机操作系统。因 为一个容器其实就是一组运行在宿主机操作系统当中的进程,宿主机操作系统通过 cgroups 对这组进程设定资源上限,当这些进程申请的资源到达上限时,触发的是宿 主机操作系统的内核 OOM 事件,因此最终是由宿主机内核来关闭这些进程.
-
如果用户不想关闭这个容器,那么可以选择 --oom-kill-disable 来禁用 OOM-Killer。 使用此参数时,仍需要注意,如果使用 -m 设置了此容器内存上限,那么当容器到达内存资源上限时,主机不会关闭容器,但也不会继续向此容器继续分配资源,此时容器 将处于 hung 状态。只需要将最坏的情况封闭在一定范围之内,而不至于蔓延出去。
-
如果用户使用了 --oom-kill-disable,但也没有使用 -m 来设定上限,因而此时此容器将会尽可能多地使用主机内存资源。换言之,主机内存有多大,它就将用多大。
容器异常退出
每个容器内部都存在一个 Init 进程,容器中其他所有进程都是此进程的子进程。运行 的容器是因为 Init 进程在运行,如果一个子进程因为某种原因造成了退出,那么其父 进程也会同步退出,直至 Init 进程也退出。当 Init 进程退出时,也就代表着此容器被关 闭。ocker 目前没有办法知道此时的进程退出属于正常退出还是异常退出。当出现容器 关闭情况时,Docker Daemon 会尝试再次重新将此容器由 Stopped 状态转为 Running 状态。只有设置了--restart 参数的容器,Docker Daemon 才会去尝试启动,否则容器 会保持停止状态。
容器暂停
Docker"剥夺"了此容器的 CPU 资源。而其他资源,如 Memory 资源、Network 资源等还保留未动。如此一来,失去了 CPU 资源的进程,是不会被主机内核系统所调度的,所以此容器就处于"冰封"状态。
Docker Container (容器) 常见命令
docker run
-
功能:创建一个新的容器并运行一个命令。
-
语法:
bashdocker run [OPTIONS] IMAGE [COMMAND] [ARG ...]
-
别名:
bashdocker container run # 因为是属于容器的命令所以有这个 container,Docker 对命令进行了分类嘛
-
参数:
- -d:后台运行容器,并返回容器的 ID。
- -i:以交互模式运行容器,通常与 -t 选项同时使用。
- -P:随机端口映射,容器内部的端口随机映射到主机的端口。
- -p :指定端口映射,格式为:主机(宿主)端口:容器端口。
- -t:为容器分配一个伪输入终端,通常与 -i 选项同时使用。
- --name:为容器指定一个名称。
- -h :指定容器的 hostname。
- -e:设置环境变量。
- --cpuset-cpus :绑定容器到指定的 CPU 上运行。例如: --cpuset-cpus="0,1,2" 或者 --cpuset-cpus="0-2" 就是将容器绑定到 0-2 这三个 CPU 上面运行。
- -m:设置容器能够使用的内存的最大值。
- --rm:当容器退出的时候自动删除它,即容器退出的时候不会进入 Exited 状态,而是直接进入 Delete 状态。
-
演示:
如下图:我们使用 -d 选项让一个容器后台运行。使用 docker ps
命令可以看到容器正在运行!
busybox 是一个非常小的 Linux 发行版,它包含了许多基本的 UNIX 工具。当仅使用 busybox 镜像而不指定任何命令时,容器启动后会立即退出,因为它没有默认的前台进程来保持容器运行。你需要提供一个命令来让容器持续运行,例如 top。
如下图:我们使用 -i 选项运行一个容器,可以看到我们输入 ls 命令能够正常执行,能进行交互,只是交互的方式不友好!
上面就是仅使用 -i 选项的效果,当我们仅使用 -t 选项的时候,会为我们创建一个伪终端,但是没有加上 -i 选项就不能交互了!
因此,我们需要 -t -i 选项一起使用,才能达到理想的交互效果!
如下图:我们使用 nginx 镜像启动一个容器,-P 是随机端口映射,我们想要访问到 nginx 的主页就要看一下这个随机映射的端口是什么!
我们使用 docker ps 命令查看正在运行的容器,发现是主机的 32768 端口映射到了容器的 80 端口。在我们的服务器放行了 32768 的前提下,我们就能够使用公网 IP 加上端口号访问容器中启动的 nginx 服务啦!在本例中就是:47.108.251.0:32768
显然,这种随机映射的方式很不友好,我们在启动一个容器的时候,应该指定端口映射,而不是让系统来随机分配,这个时候我们就可以使用 -p 选项啦!
我们指定主机的 80 端口映射到容器的 80 端口,这样我们就可以使用 80 端口来访问容器中启动的 nginx 服务啦!
如下图:我们在运行容器的时候给容器指定一个名称。
如下图,我们可以使用 -h 选项指定容器的 hostname。
如下图:我们可以使用 -e 选项添加环境变量!
当我们使用 --rm 选项启动容器的时候,当容器退出的时候,我们使用 docker ps 命令是看不到我们之前启动的这个容器的,直接被删除了嘛!
如下图:并没有看到 NAME 为 test_--rm 的容器!
docker run 命令是由很多很多选项的哈!大家需要了解全部的选项可以到 docker hub 的官网上了解!
docker ps
-
功能:列出容器。
-
语法:
bashdocker ps [OPTIONS]
-
别名:
bashdocker container ls docker container list docker container ps
-
参数:
- -a :显示所有的容器,包括没有运行的。
docker ps
默认只列出处于running
状态的容器嘛。 - -f :根据过滤条件显示容器。下面是常用的过滤条件:
- status:状态可以是下面的任意一个:
created
,restarting
,running
,removing
,paused
,exited
, 或者dead
。例如:docker ps -f status=running
- name:根据容器的名字作为过滤条件。
- id:根据容器 id 作为过滤条件。
- status:状态可以是下面的任意一个:
- --format:指定返回的文件模板。json 或者 table 等等。
- -l:显示最近的一个容器。
- -n:列出最近创建的 n 个容器。
- --no-trunc:不截断输出。
- -q:只显示容器编号。
- -s:显示文件的大小。
- -a :显示所有的容器,包括没有运行的。
-
演示:
这个命令就不演示啦,大家可以自己试一试。
docker create
-
功能:创建一个新的容器但是不启动它。
-
语法:
bashdocker create [OPTIONS] IMAGE [COMMMAND] [ARG...]
-
别名:
bashdocker container create
-
参数:
- -i:以交互模式运行容器,通常与 -t 选项同时使用。
- -P:随机端口映射,容器内部的端口随机映射到主机的端口。
- -p :指定端口映射,格式为:主机(宿主)端口:容器端口。
- -t:为容器分配一个伪输入终端,通常与 -i 选项同时使用。
- --name:为容器指定一个名称。
- -h :指定容器的 hostname。
- -e:设置环境变量。
- --cpuset-cpus :绑定容器到指定的 CPU 上运行。例如: --cpuset-cpus="0,1,2" 或者 --cpuset-cpus="0-2" 就是将容器绑定到 0-2 这三个 CPU 上面运行。
- -m:设置容器能够使用的内存的最大值。
- --rm:当容器退出的时候自动删除它,即容器退出的时候不会进入 Exited 状态,而是直接进入 Delete 状态。
-
演示:
可以看到 docker create 的参数基本上和 docker run 的参数是一样的!docker create 没有 -d 选项吧!!
如下图:我们使用 docker create 命令创建一个容器但是没有运行它!可以看到这个容器的状态是 Created 状态哈!我们可以使用 docker start 启动处于 Created 状态的容器。
docker start
-
功能:启动一个或者多个处于停止状态的容器。
-
语法:
bashdocker start [OPTIONS] CONTAINER [CONTAINER...]
后面的
CONTAINER
可以是容器的名字,容器 id 的前缀(docker ps
出来的容器 id),或者完整的容器 id (docker ps --no-trunc
出来的容器 id)。 -
别名:
bashdocker container start
-
演示:
如下图:我们使用docker create
命令创建一个容器但是不运行,之后我们再使用docker start
启动这个处于 Created 状态的容器。
如下图:使用 docker start
启动一个处于 Exited 状态的容器。
docker stop
-
功能:停止一个或者多个处于 running 状态的容器。
-
语法:
bashdocker stop [OPTIONS] CONTAINER [CONTAINER...]
-
别名:
bashdocker container stop
-
参数:
- -s 或 --signal:给容器发送一个信号。
-
演示:
如下图:我们后台启动一个 nginx 镜像的容器,使用docker stop
命令能够将其停止!
docker restart
-
功能:重启一个或者多个容器。
-
语法:
bashdocker restart [OPTIONS] CONTAINER [CONTAINER...]
-
别名:
bashdocker container restart
-
参数:
- -s 或 --signal:给容器发送一个信号。
-
演示:
如下图:我有一个正在运行的容器,docker ps
显示该容器已经运行了 12 分钟,使用docker restart
命令之后再次docker ps
可以看到该容器的运行时间变成了 12 秒。
docker kill
-
功能:"杀死" 一个处于 running 状态的容器,和我们在学习 linux 的时候的 kill 命令很像。
-
语法:
bashdocker kill [OPTIONS] CONTAINER [CONTAINER...]
-
别名:
bashdocker container kill
-
参数:
- -s 或 --signal:给容器发送一个信号。
-
说明:
docker stop
默认发送的信号是SIGTERM
信号,这个默认的信号是可以通过Dockerfile
中的STOPSIGNAL
设置的,也可以通过docker run
中的--stop-signal
设置。而docker kill
默认发送的是SIGKILL
信号,这个信号可以通过参数-s
来调整。
例如:docker kill --signal=SIGHUB mycontainer
。 -
演示:
-
如下图:我们使用
docker kill
命令终止一个容器。
docker top
-
功能:查看容器中运行的进程信息,支持 ps 命令参数。
-
语法:
bashdocker top CONTAINER [ps OPTIONS]
-
别名:
bashdocker container top
-
说明:这个
[ps OPTINONS]
的意思就是:我们之前学习的 ps 命令有哪些选项,这里就可以写哪些选项。 -
演示:
如下图:我们使用docker top
命令查看正在运行的容器内的进程信息,一个没加 ps 命令的选项,一个加了部分 ps 命令的选项。
docker stats
-
功能:显示容器资源的使用情况,包括:CPU,内存,网络 I/O 等。
-
语法:
bashdocker stats [OPTIONS] [CONTAINER...]
-
别名:
bashdocker container stats
-
参数:
- -a 或 -all:显示所有的容器,包括没有运行的。自我感觉意义不大,容器都没运行你看他的资源使用情况作用不大!
- --format:指定返回的模板文件。如:table,json。
- --no-stream:显示你输入命令的那一刻,容器资源的使用情况,类似于快照读!
- --no-trunc:不截断输出。
-
返回的数据:
- CONTAINER ID 与 NAME:容器 ID 与名称。
- CPU % 与 MEM %:容器使用的 CPU 和内存的百分比。
- MEM USAGE / LIMIT:容器正在使用的总内存,以及允许使用的内存总量。
- NET I/O:容器通过其网络接口发送和接收的数据量。
- BLOCK I/O:容器从主机上的块设备读取和写入的数据量。
- PIDs:容器创建的进程或线程数。
-
演示:
如下图:我们启动一个 nginx 的镜像容器,然后通过浏览器访问到我们的 nginx 服务器。
下面我们一直点击刷新,看看 mynginx 容器的资源使用情况的变化:
可以看到主要是 NET I/O 在变化哈!CPU 也有变化,但是不多!
其他的选项就不演示了,比较简单!
docker container inspect
-
功能:查看容器的详细信息。
-
语法:
bashdocker container inspect [OPTIONS] CONTAINER [CONTAINER...]
-
别名:
bashdocker inspect # 查看镜像详细信息可以使用 docker inspect 查看容器也可以用,Docker 引擎会自动识别你要查看的是镜像还是容器的!
-
参数:
- -f:指定返回的模板文件。如:table,json 等等。
- -s:显示总的文件大小。
-
注意:
docker inspect
会自动检查是镜像还是容器然后显示相信信息 -
演示:
演示就不演示了,docker inspect
出来的信息很多,其中有我们已经学过的,也有我们现在还没有学过的!不过不用担心,之后我们会慢慢接触到他们的!
docker logs
-
功能:查看容器日志。
-
语法:
bashdocker logs [OPTINONS] CONTAINER
-
别名:
bashdocker container logs
-
参数:
- -f 或 --flow:持续跟踪日志输出。
- --since:显示某个开始时间的所有日志。
- -t 或 --timestamps:显示时间戳。
- -n 或 --tail:仅列出最新 N 条容器的日志。
-
演示:
如下图:我么使用docker logs -f
持续追踪这个 nginx 镜像容器的日志输出,可以看到随着我不断刷新网页,日志信息也会随着更新。
如果我们不加上-f
参数,那么就会输出历史的日志。
其他的参数就就不演示啦,都比较简单,大家可以在自己的电脑上试一试。
容器的日志文件在哪里
其实容器的日志是保存在一个文件中的!
- 我们先输入
docker info
命令查看一下 Docker 的根目录:
我的目录可能和你们查看到的目录不一样,因为我之前更改过 Docker Root Dir。 - 我们进入到这个目录:
- 然后我们进入
containers
目录:
- 这里面的目录名字是容器的完整 ID 哈!我们查看我们的 nginx 镜像的容器的完整容器 ID。
- 然后进入 nginx 镜像容器的目录:
- 进入到里面之后,我们看到有一个 容器完整 ID-json.log 这个里面就是以 json 文件格式保存的容器的日志啦!
- 我们可以看到日志的时间啊,日志类型等等。
docker attach
-
功能:连接到正在运行的容器。
-
语法:
bashdocker attach [OPTINONS] CONTAINER
-
别名:
bashdocker container attach
-
参数:
- --sig-proxy:是否将接收到的所有信号代理给进程。默认是 true,如果设置为 false,退出的时候不会影响容器,否则则会导致容器退出。
-
演示:
如下图:我有一个正在后台运行的 nginx 镜像的容器,我们使用docker attach
连接到这个正在运行的容器,我们使用浏览器能访问到 nginx 服务器,并且打印出来了日志信息。可见使用docker attach
将终端的标准输入、输出和错误(或三者的任意组合)附加到正在运行的容器上。这样,你就可以查看它的输出或对它进行交互式控制,就像直接在终端中运行命令一样。然后我们按下ctrl + c
就能直接退出容器。
当我们将 --sig-proxy
参数设置为 false,我们再按下 ctrl + c
并不会退出容器!!
docker exec
-
功能:在一个正在运行的容器中执行命令。
-
语法:
bashdocker exec [OPTINONS] CONTAINER COMMAND [ARG...]
-
别名:
bashdocker container exec
-
参数:
- -d:分离模式,在后台运行。
- -i:连接到容器的 STDIN,即使没有连接到这个容器!
- -t:分配一个伪终端。
- -e:设置环境变量。
- -u 或 --user :指定用户。格式:
<name|uid>[:<group|gid>]
- -w 或 --workdir:指定工作目录。
-
演示:
如下图:我在 nginx 镜像的容器中执行一个 echo 命令。
我在 nginx 镜像的容器中以交互式模式执行 bash 命令:
如上图,我们执行 bash 命令之后,就能和容器进行交互啦!在这个过程中我们没有进入容器哦!只是在和容器中启动的一个 bash 进程在进行交互!因此我们在输入 exit 命令退出的时候,只是退出了 bash 进程!而不会退出容器和容器中的其他进程!
docker cp
-
功能:在容器和宿主机之间拷贝文件。
-
语法:
bashdocker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|- # 将容器中的文件拷贝到宿主机 docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH # 将宿主机中的文件拷贝到容器
-
说明:如果为
SRC_PATH
或DEST_PATH
指定了-
,还可以从STDIN
或STDOUT
流式传输tar
压缩包。CONTAINER
可以是运行中的容器,也可以是停止运行的容器。SRC_PATH
或DEST_PATH
可以是文件或目录。 -
别名:
bashdocker container cp
-
演示:
我们启动一个 nginx 镜像容器,然后修改这个 nginx 服务器的主页!如下图,nginx 服务器主页的 html 文件是在:/usr/share/nginx/html
目录下的!因为容器中没有 vim / vi 所以有拷贝到宿主机修改index.html
文件的需求!
-
首先我们将容器中的
/usr/share/nginx/html/index.html
文件给他拷贝到宿主机来!我们先创建一个目录用来放这个文件,然后进入到这个目录里面,使用docker cp
命令将容器中的这个文件拷贝到当前目录就行啦!
-
然后我们使用
vim index.html
编辑这个文件,将 "Welcome to nginx!" 改为 "Welcome to docker!"。最后::wq
保存退出。
-
最后,我们将修改好的文件拷贝回容器中去!然后再使用浏览器访问这个 nginx 服务器看看效果。
可以看到,成功将 nginx 服务器的首页改啦!
docker diff
-
功能:检查容器文件系统上文件或目录的更改。
-
语法:
bashdocker diff CONTAINER
-
说明:列出容器的文件系统中自容器创建以来已更改的文件和目录。会显示三种不同类型的更改:
A
:添加一个文件或者目录。C
:修改一个文件或者目录。D
:删除一个文件或者目录。
-
别名:
bashdocker container diff
-
演示:
如下图:我们查看 mynginx 这个容器的文件系统更改情况。
docker commit
-
功能:从容器创建一个新的镜像。
-
语法:
bashdocker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
-
别名:
bashdocker container commit
-
参数:
- -a:提交镜像的作者。
- -c :使用
Dockerfile
指令来创建镜像,可以修改启动指令!现在没法讲,后面讲镜像制作的时候再来吧! - -m:提交时的说明文字。
- -p:在提交的时候将容器暂停,默认 -p 为 true 表示默认是暂停的!
-
演示:
如下图:我们使用docker commit
命令将 mynginx 容器提交为镜像,在提交的过程中容器会被暂停,但是这个暂停的过程不好演示,你可以尝试一直刷新浏览器来试试!可以看到提交成功之后再本地就会多出这个镜像啦!
我们使用docker image inspect
查看这个镜像的详细信息:可以看到保留了很多原容器镜像的诸多信息,docker commit
将原容器提交为镜像时,原容器中增加的环境变量也会被包含到新镜像的 env 中!!!
你不是说,docker commit
会将原容器的信息提交为镜像嘛,我们之间不是修改了 nginx 的主页嘛!首先,我们将原来的那个容器 stop 掉,然后使用 commit 出来的镜像重新启动一个容器!发现确实是将原容器的信息保存啦!因为我们访问到的是 Welcome to docker!
嘛!
docker port
-
功能:用于列出指定容器的端口映射。
-
语法:
bashdocker port CONTAINER [PRIVATAE_PORT[/PROTO]]
-
别名:
bashdocker container port
-
说明:后面的
[PRIVATE_PORT[/PROTO]]
就是指定端口,指定协议。 -
演示:
使用docker port
查看端口映射
docker pause
-
功能:停止一个或者多个容器中的所有进程。
-
语法:
bashdocker pause CONTAINER [CONTAINER...]
-
别名:
bashdocker container pause
-
演示:
使用docker pause
命令暂停容器中的所有进程,可以看到 pause 之后容器的状态是 Paused。
docker unpause
-
功能:恢复一个或者多个容器中的所有进程。
-
语法:
bashdocker unpause CONTAINER [CONTAINER...]
-
别名:
bashdocker container unpause
-
演示:
我们使用docker unpause
命令将刚才处于 Paused 状态的容器启动起来!
docker rm
-
功能:删除一个或者多个容器。
-
语法:
bashdocker rm CONTAINER [CONTAINER...]
-
别名:
bashdocker container rm
-
参数:
- -f:通过 SIGKILL 信号强制删除一个处于 running 状态中的容器。
-
演示:
如下图:我们使用dcoker rm
删除一个处于停止状态的容器:
如下图:我们尝试使用 docker rm
不加 -f
参数删除一个处于 running 状态的容器,可以看到直接报错啦!报错信息也是给得非常详细哈!然后我们加上 -f
参数就能强制删除这个正在运行的容器啦!
docker export
-
功能:导出一个文件的内容为 tar 文件。
-
语法:
bashdocker export [OPTIONS] CONTAINER
-
别名:
bashdocker container export
-
参数:
- -o:写入到指定文件。
-
演示:
如下图:我们使用 nginx 镜像启动一个容器,并将 nginx 服务器的主页进行修改:
使用浏览器访问 nginx 服务器:可以看到结果没问题!
然后,我们将这个修改过 nginx 主页的容器 export 出来个 tar 文件!
怎么将这个 tar 文件恢复出来呢?这就要用之前在 docker 镜像常见命令中没讲的docker image import
命令啦!
docker image import
-
功能:从归档文件中创建镜像。
-
语法:
bashdocker image import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
-
别名:
bashdocker import
-
说明:您可以指定一个 URL 或-(破折号),直接从 STDIN 获取数据。URL 可以指向包含文件系统的存档(.tar、.tar.gz、.tgz、.bzip、.tar.xz 或 .txz),也可以指向 Docker 主机上的单个文件。如果指定的是一个压缩包,Docker 会在容器中相对于 /(根目录)对其解压缩。如果指定单个文件,则必须指定主机内的完整路径。要从远程位置导入,请指定以 http:// 或 https:// 协议开头的 URI。
-
参数:
- -c 或 --change:现在没法讲,这个选项会将 Dockerfile 指令应用到镜像。
- -m:提交时的说明文字!
-
演示:
刚刚我们不是使用docker export
导出了一个 tar 归档文件嘛,现在我们使用docker import
命令来创建一个镜像吧!
如下图:我们将这个 tar 文件导出为test_import:v1
这样一个镜像,并且使用-m
参数附加了一些描述信息。
我们停掉之前启动的那个容器(之前的那个容器占用了我的服务器开放的端口,所以我将它停掉了),然后尝试使用docker import
导出的test_import:v1
镜像运行容器,可是直接报错了,无法启动!
我们使用docker image inspect
查看一下test_import:v1
这个镜像的详细信息。发现打印出来的信息中,Cmd,Env 啥的都没了!可见docker export
和docker import
这样的组合还是有很大的缺点的!!
我们查看原nginx
镜像的详细信息,找到 nginx 镜像的启动命令:
在docker run
使用test_import:v1
镜像启动容器的时候加上这个启动命令,就能成功运行啦!
可以看到通过浏览器访问,的确也是我们之前修改过的内容!
因为 docker export 导出 tar 归档文件的时候会有元数据的丢失,不建议使用哈
推荐使用 docker commit
docker save
docker load
这几个!
docker rename
-
功能:给一个容器重命名。
-
语法:
bashdocker rename CONTAINER NEW_NAME
-
别名:
bashdocker container rename
-
演示:
如下图:我们使用docker rename
给一个容器重命名。
docker container prune
-
功能:删除所有停止的容器。
-
语法:
bashdocker container prune [OPTIONS]
-
参数:
-
-f 或 --force:删除的是否不提示是否确认。
-
演示:
如下图:我们使用docker container prune
删除所有停止的容器,因为没有加上-f
选项,所以会提示我们是否确认删除。
docker update
-
功能:更新容器的配置。
-
语法:
bashdocker update [OPTIONS] CONTAINER [CONTAINER...]
-
别名:
bashdocker container update
-
参数:
-
--cpus:cpu 数量。
-
--cpu-cpus:使用哪些 cpu。
-
--memory:内存限制。
-
--cpu-period:用来指定容器对 CPU 的使用要在多长时间内做一次重新分配。
-
--cpu-quota :用来指定在这个周期内,最多有多少时间可以用来跑这个容器。
演示:
如下图:我们用 nginx 镜像启动并运行一个容器,然后执行一个命令将 CPU 打满!
bash
for i in `seq 1 $(cat /proc/cpuinfo |grep "physical id" |wc -l)`
do
dd if=/dev/zero of=/dev/null &
done
#说明:
# cat /proc/cpuinfo |grep "physical id" | wc -l 可以获得 CPU 的个数,
# 我们将其表示为 N
# seq 1 N 用来生成1到N之间的数字
# for i in seq 1 N; 就是循环执行命令,从1到N
# dd if=/dev/zero of=/dev/null 执行 dd 命令, 输出到/dev/null, 实际上
# 只占用 CPU, 没有 IO 操作
# 由于连续执行N个(N是 CPU 个数)的 dd 命令, 且使用率为 100%, 这时调度器
# 会调度每个 dd 命令在不同的 CPU 上处理,最终就实现所有CPU占用率 100%
然后我们启动另一个会话,输入 docker stats mynginx
查看容器资源的使用情况,可以看到 CPU 几乎打满了
然后我们再使用 docker update --cpu-period=100000 --cpu-quota=10000 mynginx
将容器的最大 CPU 占有率设置为 10%,可以看到就立即对容器生效啦!
像这种 CPU,内存使用的限制其实应该就是在 docker run
的时候设置好的!
如果你的容器使用的内存是超过 docker update -m
更新的内存,是无法更新成功的!
bash
docker update -m 10m --memory-swap 10m mynginx # 这个交换内存的选项不设置的话默认是无限大的!当 -m 设置的大小和 --memory-swap 设置的大小是一样的话,就表示真实能够使用的物理内存是多大了
容器批量处理技巧
如下图所示:我的本地有好多正在运行的容器,我想直接把他们全部暂停掉!应该怎么做呢?还记得我们直接学过的 docker ps
中的 -q
这个选项吧!他只输出容器的 ID,那我们就会想能不能将 docker ps -q
得到的所有容器 id 喂给 docker stop
呢?还真行!Docker 引擎支持这么做!
命令这么写:
bash
docker stop `docker ps -q`
# 或者这么写
docker stop $(docker ps -q)
可以看到一口气直接把他们全部停止了!
容器交互模式
attached 模式
- 我们使用
docker run
命令的时候不加-d
选项,就是 attached 模式,这样容器会在前台运行 - 如果是在 Linux 服务器上,按 Ctrl+C 就会停止掉 Docker 服务,很容易误操作,所以我们需要一个更好的,更稳定的模式,对应的是 detached 模式。如果是前台运行,网络断开的话,nginx 服务器就挂了!
- attached 模式仅适用于容器和程序的调试阶段。
detached 模式
- 在
docker container run
命令基础上加一个-d
或者--detach
选项表示 detached 模式, 即在后台执行, - 在后台运行,启动后显示容器 ID,并且可以输入任何命令,这不会影响后台运行的容器。
- 就算关掉窗口,断开网络容器依然继续运行,停止和删除容器都需要使用 shell 命令,减少了很多的误操作,
- 比起 attached 模式更建议使用,
detached 模式转 attached 模式:使用 docker attach 命令就好啦!
interactive 模式
- 当我们创建好一个容器之后, 可能需要去容器内部获取一些信息或执行一些命令,就
需要进入到交互式模式。 - 其实就是
docker run
的时候加上-ti
选项嘛。 - 退出交互模式使用
exit
命令就好啦!
常见问题
docker create、docker start 和 docker run 有什么区别?
docker create 命令从 Docker 映像创建一个全新的容器。但是,它不会立即运行它。
docker start 命令将启动任何已停止的容器。如果使用 docker create 命令创建容器,
则可以使用此命令启动它。
docker run 命令是创建和启动的组合,因为它创建了一个新容器并立即启动它。实际
上,如果 docker run 命令在您的系统上找不到上述映像,它可以从 Docker Hub 中提
取映像。
docker import 和 docker load 有什么区别?
想要了解 docker load
与 docker import
命令的区别,还必须知道 docker save
与 docker export
命令:
docker save images_name
:将一个镜像导出为文件,再使用docker load
命令将文件导入为一个镜像,会保存该镜像的的所有历史记录。比docker export
命令导出的文件大,很好理解,因为会保存镜像的所有历史记录。docker export container_id
:将一个容器导出为文件,再使用docker import
命令将容器导入成为一个新的镜像,但是相比docker save
命令,容器文件会丢失所有元数据和历史记录,仅保存容器当时的状态,相当于虚拟机快照。
既可以使用 docker load
命令来导入镜像库存储文件到本地镜像库,也可以使用docker import
命令来导入一个容器快照到本地镜像库。
两者的区别在于容器快照将会丢弃所有的历史记录和元数据信息,而镜像存储文件将保存完整记录,体积也会更大。
docker rm & docker rmi & docker prune 的差异?
docker rm
: 删除一个或多个容器。docker rmi
: 删除一个或多个镜像。docker prune
: 用来删除不再使用的 docker 对象。