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
-
功能:创建一个新的容器并运行一个命令。
-
语法:
docker run [OPTIONS] IMAGE [COMMAND] [ARG ...]
-
别名:
docker 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
- 功能:列出容器。
- 语法:
docker ps [OPTIONS]
- 别名:
docker 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
- 功能:创建一个新的容器但是不启动它。
- 语法:
docker create [OPTIONS] IMAGE [COMMMAND] [ARG...]
- 别名:
docker 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
- 功能:启动一个或者多个处于停止状态的容器。
- 语法:
后面的docker start [OPTIONS] CONTAINER [CONTAINER...]
CONTAINER
可以是容器的名字,容器 id 的前缀(docker ps
出来的容器 id),或者完整的容器 id (docker ps --no-trunc
出来的容器 id)。 - 别名:
docker container start
- 演示:
如下图:我们使用docker create
命令创建一个容器但是不运行,之后我们再使用docker start
启动这个处于 Created 状态的容器。
如下图:使用 docker start
启动一个处于 Exited 状态的容器。
docker stop
- 功能:停止一个或者多个处于 running 状态的容器。
- 语法:
docker stop [OPTIONS] CONTAINER [CONTAINER...]
- 别名:
docker container stop
- 参数:
- -s 或 –signal:给容器发送一个信号。
- 演示:
如下图:我们后台启动一个 nginx 镜像的容器,使用docker stop
命令能够将其停止!
docker restart
- 功能:重启一个或者多个容器。
- 语法:
docker restart [OPTIONS] CONTAINER [CONTAINER...]
- 别名:
docker container restart
- 参数:
- -s 或 –signal:给容器发送一个信号。
- 演示:
如下图:我有一个正在运行的容器,docker ps
显示该容器已经运行了 12 分钟,使用docker restart
命令之后再次docker ps
可以看到该容器的运行时间变成了 12 秒。
docker kill
- 功能:“杀死” 一个处于 running 状态的容器,和我们在学习 linux 的时候的 kill 命令很像。
- 语法:
docker kill [OPTIONS] CONTAINER [CONTAINER...]
- 别名:
docker 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 命令参数。
- 语法:
docker top CONTAINER [ps OPTIONS]
- 别名:
docker container top
- 说明:这个
[ps OPTINONS]
的意思就是:我们之前学习的 ps 命令有哪些选项,这里就可以写哪些选项。 - 演示:
如下图:我们使用docker top
命令查看正在运行的容器内的进程信息,一个没加 ps 命令的选项,一个加了部分 ps 命令的选项。
docker stats
- 功能:显示容器资源的使用情况,包括:CPU,内存,网络 I/O 等。
- 语法:
docker stats [OPTIONS] [CONTAINER...]
- 别名:
docker 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
- 功能:查看容器的详细信息。
- 语法:
docker container inspect [OPTIONS] CONTAINER [CONTAINER...]
- 别名:
docker inspect # 查看镜像详细信息可以使用 docker inspect 查看容器也可以用,Docker 引擎会自动识别你要查看的是镜像还是容器的!
- 参数:
- -f:指定返回的模板文件。如:table,json 等等。
- -s:显示总的文件大小。
- 注意:
docker inspect
会自动检查是镜像还是容器然后显示相信信息 - 演示:
演示就不演示了,docker inspect
出来的信息很多,其中有我们已经学过的,也有我们现在还没有学过的!不过不用担心,之后我们会慢慢接触到他们的!
docker logs
- 功能:查看容器日志。
- 语法:
docker logs [OPTINONS] CONTAINER
- 别名:
docker 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
- 功能:连接到正在运行的容器。
- 语法:
docker attach [OPTINONS] CONTAINER
- 别名:
docker container attach
- 参数:
- –sig-proxy:是否将接收到的所有信号代理给进程。默认是 true,如果设置为 false,退出的时候不会影响容器,否则则会导致容器退出。
- 演示:
如下图:我有一个正在后台运行的 nginx 镜像的容器,我们使用docker attach
连接到这个正在运行的容器,我们使用浏览器能访问到 nginx 服务器,并且打印出来了日志信息。可见使用docker attach
将终端的标准输入、输出和错误(或三者的任意组合)附加到正在运行的容器上。这样,你就可以查看它的输出或对它进行交互式控制,就像直接在终端中运行命令一样。然后我们按下ctrl + c
就能直接退出容器。
当我们将 --sig-proxy
参数设置为 false,我们再按下 ctrl + c
并不会退出容器!!
docker exec
- 功能:在一个正在运行的容器中执行命令。
- 语法:
docker exec [OPTINONS] CONTAINER COMMAND [ARG...]
- 别名:
docker 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
- 功能:在容器和宿主机之间拷贝文件。
- 语法:
docker 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
可以是文件或目录。 - 别名:
docker 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
-
功能:检查容器文件系统上文件或目录的更改。
-
语法:
docker diff CONTAINER
-
说明:列出容器的文件系统中自容器创建以来已更改的文件和目录。会显示三种不同类型的更改:
A
:添加一个文件或者目录。C
:修改一个文件或者目录。D
:删除一个文件或者目录。
-
别名:
docker container diff
-
演示:
如下图:我们查看 mynginx 这个容器的文件系统更改情况。
docker commit
- 功能:从容器创建一个新的镜像。
- 语法:
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
- 别名:
docker 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
- 功能:用于列出指定容器的端口映射。
- 语法:
docker port CONTAINER [PRIVATAE_PORT[/PROTO]]
- 别名:
docker container port
- 说明:后面的
[PRIVATE_PORT[/PROTO]]
就是指定端口,指定协议。 - 演示:
使用docker port
查看端口映射
docker pause
- 功能:停止一个或者多个容器中的所有进程。
- 语法:
docker pause CONTAINER [CONTAINER...]
- 别名:
docker container pause
- 演示:
使用docker pause
命令暂停容器中的所有进程,可以看到 pause 之后容器的状态是 Paused。
docker unpause
- 功能:恢复一个或者多个容器中的所有进程。
- 语法:
docker unpause CONTAINER [CONTAINER...]
- 别名:
docker container unpause
- 演示:
我们使用docker unpause
命令将刚才处于 Paused 状态的容器启动起来!
docker rm
- 功能:删除一个或者多个容器。
- 语法:
docker rm CONTAINER [CONTAINER...]
- 别名:
docker container rm
- 参数:
- -f:通过 SIGKILL 信号强制删除一个处于 running 状态中的容器。
- 演示:
如下图:我们使用dcoker rm
删除一个处于停止状态的容器:
如下图:我们尝试使用 docker rm
不加 -f
参数删除一个处于 running 状态的容器,可以看到直接报错啦!报错信息也是给得非常详细哈!然后我们加上 -f
参数就能强制删除这个正在运行的容器啦!
docker export
- 功能:导出一个文件的内容为 tar 文件。
- 语法:
docker export [OPTIONS] CONTAINER
- 别名:
docker container export
- 参数:
- -o:写入到指定文件。
- 演示:
如下图:我们使用 nginx 镜像启动一个容器,并将 nginx 服务器的主页进行修改:
使用浏览器访问 nginx 服务器:可以看到结果没问题!
然后,我们将这个修改过 nginx 主页的容器 export 出来个 tar 文件!
怎么将这个 tar 文件恢复出来呢?这就要用之前在 docker 镜像常见命令中没讲的docker image import
命令啦!
docker image import
- 功能:从归档文件中创建镜像。
- 语法:
docker image import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
- 别名:
docker 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
- 功能:给一个容器重命名。
- 语法:
docker rename CONTAINER NEW_NAME
- 别名:
docker container rename
- 演示:
如下图:我们使用docker rename
给一个容器重命名。
docker container prune
- 功能:删除所有停止的容器。
- 语法:
docker container prune [OPTIONS]
- 参数:
- -f 或 –force:删除的是否不提示是否确认。
- 演示:
如下图:我们使用docker container prune
删除所有停止的容器,因为没有加上-f
选项,所以会提示我们是否确认删除。
docker update
- 功能:更新容器的配置。
- 语法:
docker update [OPTIONS] CONTAINER [CONTAINER...]
- 别名:
docker container update
- 参数:
- –cpus:cpu 数量。
- –cpu-cpus:使用哪些 cpu。
- –memory:内存限制。
- –cpu-period:用来指定容器对 CPU 的使用要在多长时间内做一次重新分配。
- –cpu-quota:用来指定在这个周期内,最多有多少时间可以用来跑这个容器。
演示:
如下图:我们用 nginx 镜像启动并运行一个容器,然后执行一个命令将 CPU 打满!
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
更新的内存,是无法更新成功的!
docker update -m 10m --memory-swap 10m mynginx # 这个交换内存的选项不设置的话默认是无限大的!当 -m 设置的大小和 --memory-swap 设置的大小是一样的话,就表示真实能够使用的物理内存是多大了
容器批量处理技巧
如下图所示:我的本地有好多正在运行的容器,我想直接把他们全部暂停掉!应该怎么做呢?还记得我们直接学过的 docker ps
中的 -q
这个选项吧!他只输出容器的 ID,那我们就会想能不能将 docker ps -q
得到的所有容器 id 喂给 docker stop
呢?还真行!Docker 引擎支持这么做!
命令这么写:
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 对象。