写在前面

在前面我们学习了docker镜像相关的知识,接下来再来学习另一个核心概念—容器。容器是镜像的一个运行实例,所不同的是,镜像是静态的只读文件,而容器则是带有运行时需要的可写文件层,同时容器中的应用进程处于运行状态。

可以将其类比到面向对象编程中的对象和类的关系,其中类实例化出对象,正如这里的容器是镜像的一个运行实例一般。

如果认为虚拟机是模拟运行的一整套操作系统,包括内核、应用运行环境、其他系统环境以及跑在上面的应用;那么Docker容器就是独立运行的一个或者一组运用,以及它们必需的运行环境。

接下将围绕容器来进行学习,主要包含创建、启动、终止、删除容器,进入容器内执行操作、通过导入导出操作实现容器迁移等内容。

创建容器

用户可以理解为对容器的操作就像直接操作应用一般,非常简单且快速。

新建容器

开发者可以使用docker create [container]命令来新建一个容器。

举个例子,开发者可以使用ubuntu:latest镜像创建一个容器,使用的命令如下:

1
2
3
4
5
[root@envythink ~]# docker create -it ubuntu:latest
dffcf8e21a51005939759eeab30cc772c8dcb948aa74d50530c84c80bd483ba2
[root@envythink ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dffcf8e21a51 ubuntu:latest "/bin/bash" 13 seconds ago Created eloquent_margulis

但是请注意,使用docker create [container]命令新建的容器处于停止状态,开发者可以使用docker start [container]命令来启动它。

细心的朋友肯定发现我们在docker create [container]命令中加入了-it参数,其实这就是选项参数。选项参数包括三大类:与容器运行模式相关、与容器环境配置相关、与容器资源限制和安全保护相关。接下来笔者从网上和书籍中贴了几张选项参数的图片,这些需要平时去记忆:

(1)create命令与容器运行模式相关的选项如下所示:

(2)create命令与容器环境和配置相关的选项如下所示:

(3)create命令与容器资源限制和安全保护相关的选项如下所示:

其他选项还包括:

  • -l或者--label=[],它表示以键值对方式指定容器的标签信息;
  • --label-file=[],它表示从文件中读取标签信息。

启动容器

在前面提到过开发者可以使用docker start [container]命令来启动一个已经创建的容器。

举个例子,如开发者可以启动之前基于ubuntu:latest创建的容器,使用的命令如下:

1
2
3
4
5
6
7
8
[root@envythink ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dffcf8e21a51 ubuntu:latest "/bin/bash" 18 minutes ago Created eloquent_margulis
[root@envythink ~]# docker start df
df
[root@envythink ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dffcf8e21a51 ubuntu:latest "/bin/bash" 19 minutes ago Up 15 seconds eloquent_margulis

请注意这里可以使用CONTAINER ID来唯一标识容器,或者可以标识唯一容器的一小部分,最后使用docker ps来查看正在运行的容器实例。

新建并启动容器

是不是觉得前面的docker create [container]命令非常鸡肋,创建了容器居然不去运行,还需要借助于docker start [container]命令来启动,其实在实际工作中这种场景也是存在的。但是docker也提供了另一个将两者功能合一的命令docker run [container]docker run [container]命令可以直接新建并启动容器。也就是说docker run [container]命令等价于先执行docker create [container]命令,再执行docker start [container]命令。

举个例子,下面的命令将会输出一个“hello,world”,然后容器就自动终止运行:

1
2
[root@envythink ~]# docker run ubuntu:latest /bin/echo "hello,world"
hello,world

不过这看起来与本地直接执行/bin/echo "hello,world"感觉没什么区别,但实际上区别大着呢。

当开发者使用docker run [container]来创建并启动容器时,Docker在后台运行的标准操作如下所示:
(1)检查本地是否存在指定的镜像,如果不存在就从Docker Hub公有仓库下载;
(2)利用镜像创建一个容器,并启动该容器;
(3)分配一个文件系统给容器,并在只读的镜像层外面挂载一层可读写层;
(4)从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去;
(5)从网桥的地址池配置一个IP地址给容器;
(6)执行用户指定的应用程序;
(7)执行完毕后容器被自动终止运行。

下面的命令用来启动一个bash终端,并运行用户进行交互:

1
2
3
4
5
[root@envythink ~]# docker run -it ubuntu:latest /bin/bash
root@773716d33b57:/# echo "hello,beijing"
hello,beijing
root@773716d33b57:/# exit
exit

其中的-t选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入中,而-i选项则让容器的标准输入保持打开,获取更多命令可以使用man docker-run命令来查看。

可以看到前面笔者在容器内的交互模式下执行了echo "hello,beijing"命令且进行了输出。如果用户在容器内使用ps命令查看进程,可以发现该容器内只运行了bash应用,并没有运行其他的无法进程,且开发者可以使用Ctrl+d或者exit命令来退出容器:

1
2
3
4
5
6
7
[root@envythink ~]# docker run -it ubuntu:latest /bin/bash
root@3b25fe814a4d:/# ps
PID TTY TIME CMD
1 pts/0 00:00:00 bash
8 pts/0 00:00:00 ps
root@3b25fe814a4d:/# exit
exit

请注意这个root@3b25fe814a4d@后面一串字符串是新创建的容器的id。

对于所创建的bash容器来说,当用户使用exit命令退出bash进程之后,容器也会自动退出,这是因为对于容器来说,当其中的应用退出后,容器的使命就完成了,因此没有继续运行的必要。

开发者可以使用docker container wait CONTAINER [CONTAINER...]子命令来等待容器退出,并打印退出返回结果。

但是在某些时候,开发者执行docker run [container]命令的时候可能会出错,进而导致无法正常执行,容器会出错直接退出并默认返回命令的退出错误码,这里笔者列举3种常见的错误代码:
(1)125,这是docker daemon执行出错,像指定了不支持的docker命令参数时就会出现这个问题;
(2)126,表示指定的命令无法执行,像权限出错就会出现这个问题;
(3)127,表示内的命令无法找到。

守护态运行

通常而言,我们都希望docker容器在后台以守护态(Daemonized)形式运行,此时开发者可以通过在创建容器的时候添加-d参数来实现这一目的:

1
2
[root@envythink ~]# docker run -d ubuntu:latest /bin/sh -c "while true;do echo 'hello,world';sleep 1;done"
64dbc7b21e8a48d607c926f810d2beda069df2bd0f853b151cf6fa5104c90448

可以看到上面的命令就会使新创建的容器在后台运行,容器启动后会返回一个唯一的id,开发者可以通过docker ps或者docker container ls命令来查看容器信息:

1
2
3
4
5
6
[root@envythink ~]# docker ps 
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
64dbc7b21e8a ubuntu:latest "/bin/sh -c 'while t…" 23 seconds ago Up 22 seconds agitated_ramanujan
[root@envythink ~]# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
64dbc7b21e8a ubuntu:latest "/bin/sh -c 'while t…" 53 seconds ago Up 52 seconds agitated_ramanujan

查看容器输出

开发者如果想要获取容器的输出信息,可以使用docker logs [container]命令,请注意该命令还支持以下6个选项参数:
(1)-details表示打印详细信息;
(2)-f或者-follow表示持续保持输出;
(3)-since string表示输出从某个时间开始的日志;
(4)-tail string表示输出最近的若干日志;
(5)-t或者-timestamps表示显示时间戳信息;
(6)-until string表示输出某个时间之前的日志。

停止容器

在学习完创建和运行容器之后,接下来开始学习如何停止容器,这里主要学习docker容器的pause/unpausestop/prune命令。

暂停容器

开发者可以使用docker pause CONTAINER [CONTAINER...]命令来暂停一个运行中的容器。

举个例子,使用之前的ubuntu:latest镜像启动一个别名为envy的容器,并将其暂停,相应的命令如下:

1
2
3
4
5
6
7
8
9
10
[root@envythink ~]# docker run --name envy -d -it ubuntu /bin/bash
ea5b220af8a6f043efd123caa7b7cb6b2777d2ca4c40c0be930b436a27f75cbe
[root@envythink ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ea5b220af8a6 ubuntu "/bin/bash" 14 seconds ago Up 13 seconds envy
[root@envythink ~]# docker pause envy
envy
[root@envythink ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ea5b220af8a6 ubuntu "/bin/bash" 28 seconds ago Up 27 seconds (Paused) envy

请注意开发者如果想恢复处于paused状态的容器,可以使用docker unpause CONTAINER [CONTAINER...]命令。

终止容器

前面学习的是如何暂停容器,接下来开始学习如何终止容器的运行,那么可以使用docker stop [container]命令。注意该命令也可以携带参数-t或者--time=10,表示先向容器发送SIGTERM信息,等待一段超时时间后(默认为10秒钟),再发送SIGKILL信号来终止容器运行:

1
2
3
4
5
[root@envythink ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ea5b220af8a6 ubuntu "/bin/bash" 10 minutes ago Up 10 minutes envy
[root@envythink ~]# docker stop envy -t=10
envy

请注意尽管容器被终止运行了,但是它默认还是存在的,此时如果开发者想要自动清除所有处于停止状态的容器,可以使用docker container prune命令。前面大家也都看到了docker stop [container]是一种缓慢终止容器运行的命令,如果开发者想要立即强制终止容器的运行,可以使用docker kill [container]命令来直接发送SIGKILL信息进而强行终止容器的运行。

请注意,当docker容器中指定的应用终止时,容器也会自动终止,这里的指定是指该容器只允许了一个应用的容器。前面我们都是启动了一个只有终端应用在运行的容器,开发者通过使用exit或者Ctrl+d组合键来退出终端时,那么所创建的容器也会立即终止运行,处于stopped状态。

在前面我们使用docker ps命令来查看正在运行的容器实例信息;使用docker ps -a命令来查看所有容器的信息,无论是否正在运行,其实还可以使用docker ps -qa命令来查看所有容器的ID,无论是否正在运行:

1
2
3
[root@envythink ~]# docker ps -qa
8ecea713c87b
dffcf8e21a51

同样开发者可以使用docker start [container]命令来将处于终止状态的容器重新启动:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@envythink ~]# docker run --name envy -d -it ubuntu /bin/bash
91e08c629e4420c6569b9a8718896d6284d05cf134540b70d862de8c19667db9
[root@envythink ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
91e08c629e44 ubuntu "/bin/bash" 7 seconds ago Up 6 seconds envy
[root@envythink ~]# docker pause envy
envy
[root@envythink ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
91e08c629e44 ubuntu "/bin/bash" 24 seconds ago Up 23 seconds (Paused) envy
[root@envythink ~]# docker unpause envy
envy
[root@envythink ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
91e08c629e44 ubuntu "/bin/bash" 36 seconds ago Up 35 seconds envy
[root@envythink ~]# docker stop envy
envy
[root@envythink ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@envythink ~]# docker start envy
envy
[root@envythink ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
91e08c629e44 ubuntu "/bin/bash" About a minute ago Up 2 seconds envy

可以看到处于暂停状态的容器,使用docker ps命令还是可以看到它在运行,只是状态变成了Paused,而处于终止状态的容器,使用docker ps命令是无法看到它的信息,因为它是真的没有在运行。

还有一个命令是docker restart [container],它会将一个处于运行态的容器先终止,然后再重新启动:

1
2
3
4
5
6
7
8
[root@envythink ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
91e08c629e44 ubuntu "/bin/bash" 6 minutes ago Up 38 seconds envy
[root@envythink ~]# docker restart envy
envy
[root@envythink ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
91e08c629e44 ubuntu "/bin/bash" 6 minutes ago Up 1 second envy

发现问题了么,其实上面那个命令就是重启容器罢了,因此STATUS的时间会清零。

进入容器

在前面我们讲过,如果在创建容器的时候添加-d参数,那么容器启动后就会进入后台,用户是无法看到容器中的信息,也无法进行操作,此时如果开发者还是想进入容器进行操作,可以使用官方推荐的attach或者exec命令。

attach命令

attach是Docker自带的命令,其使用的格式如下:

1
docker attach [container] [--detach-keys[=[]]]] [--no-stdin] [--sig-proxy[=true]] CONTAINER

可以看到这个命令中有三个选项参数:
(1)--detach-keys[=[]],它表示指定退出attach模式的快捷键序列,默认是CTRL-p CTRL-q;
(2)--no-stdin=true|false,它表示是否关闭标准输入,默认是保持打开;
(3)--sig-proxy=true|false,它表示是否代理收到的系统信号给应用进程,默认为true。

举个例子,新建一个别名为envy的容器,使其在后台运行,然后进入到该容器中:

1
2
3
4
[root@envythink ~]# docker run -itd --name envy ubuntu:latest
8d4d82f1ae231c2c510fa76abe122ee1a5428e1422ed22b116aad67031ee91b5
[root@envythink ~]# docker attach envy
root@8d4d82f1ae23:/#

但是请注意,当多个窗口同时attach同一个容器的时候,所有窗口都会同步显示,且当某个窗口因执行某些命令而阻塞时,此时其他窗口也无法执行任何操作,这是它的一个缺点。

exec命令

docker1.3开始提供了另一个比较方便的命令exec,可以在运行中的容器内直接执行任意命令。其使用的格式如下:

1
2
docker exec [container] [-d|--detach] [--detach-keys[=[]]]] [-i|--interactive] [--privileged] [-t|--tty] [-u|--user[=USER]] 
CONTAINER COMMAND [ARG...]

可以看到这个命令中有很多个选项参数,其中较为重要的如下:
(1)-d|--detach,表示在容器中后台执行命令;
(2)--detach-keys="",表示指定将容器切回后台的按键;
(3)-e|--env=[],表示指定环境变量列表;
(4)-i|--interactive=true|false,表示打开标准输入接受用户输入命令,默认值为false;
(5)--privileged=true|false,表示是否给执行命令以最高权限,默认值为false;
(6)-t|--tty=true|false,表示是否分配伪终端,默认值为false;
(7)-u|--user="",表示执行命令的用户名或ID。

还记得前面刚创建的envy容器么,接下来尝试进入到该容器中,并启动一个bash:

1
2
3
4
5
[root@envythink ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8d4d82f1ae23 ubuntu:latest "/bin/bash" 30 minutes ago Up About a minute envy
[root@envythink ~]# docker exec -it 8d4d82f1ae23 /bin/bash
root@8d4d82f1ae23:/#

可以看到这个命令会打开一个新的bash终端,能在不影响容器内其他应用的前提下,用户可以与容器进行交互。

请注意,笔者推荐通过指定-it参数来保持标准输入打开,且分配一个伪终端,然后通过exec命令对容器执行操作。

既然前面都已经进入到容器内,那么就可以尝试查看容器内的用户和进程信息:

1
2
3
4
5
6
7
root@8d4d82f1ae23:/# w
14:19:16 up 2:01, 0 users, load average: 0.00, 0.01, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root@8d4d82f1ae23:/# ps -aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 4100 1992 pts/0 Ss+ 14:17 0:00 /bin/bash
root 23 0.0 0.0 5880 1408 pts/1 R+ 14:19 0:00 ps -aux

删除容器

开发者可以使用docker rm [container]命令来删除处于终止或退出状态的容器,其对应的格式为docker rm [container] [-f|--force] [-l|--link] [-v|--volumes] CONTAINER [CONTAINER...]。解释一下上述命令中的选项参数:
(1)-f, --force[=false],是否强行终止并删除一个正处于运行状态的容器。
(2)-l, --link[=false],表示删除容器的链接,但是保留容器;
(3)-v, --volumes[=false],表示删除容器挂载的数据卷。

举个例子查看正在运行的容器,并强制删除该容器:

1
2
3
4
5
[root@envythink ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9f4e9a358ac3 ubuntu:latest "/bin/bash" 45 seconds ago Up 8 seconds envy
[root@envythink ~]# docker rm -f=true 9f4e9a358ac3
9f4e9a358ac3

请注意,默认情况下使用docker rm [container]命令只能删除已经处于终止或者退出状态的容器,无法删除正处于运行状态的容器。但是当我们在docker rm [container]命令内添加了-f=true参数时,Docker就会先发送一个SIGKILL信号给容器,来终止其中的应用,之后就强制删除该容器。

导入和导出容器

在实际工作中,我们经常需要将一个容器从A系统迁移到B系统中,此时可以使用Docker自身提供的导入和导出功能。

导出容器为文件

所谓的导出容器,是指将一个已经创建的容器到出为一个文件,注意此时无论该容器是否处于运行状态,开发者都可以使用docker export [container]命令来进行导出,其对应的格式为docker export [container] [-o|--output[=""]] CONTAINER。其中的-o选项参数用于指定导出的tar文件的名称,也可以直接通过重定向来实现。

接下来举个例子,分别演示导出一个正在运行的别名为lichee的容器为the_run_exapmle.tar文件;一个已经停止运行的别名为envy的容器为the_stop_example.tar文件,相应的操作命令如下:

1
2
3
4
5
6
7
8
9
10
11
12
[root@envythink envythink]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
83f7959b96c9 ubuntu:latest "/bin/bash" 59 seconds ago Up 33 seconds lichee
115d0747638e ubuntu:latest "/bin/bash" About a minute ago Exited (0) About a minute ago envy
[root@envythink envythink]# docker export -o the_run_exapmle.tar lichee
[root@envythink envythink]# docker export envy > the_stop_example.tar
[root@envythink envythink]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
83f7959b96c9 ubuntu:latest "/bin/bash" 2 minutes ago Up 2 minutes lichee
115d0747638e ubuntu:latest "/bin/bash" 3 minutes ago Exited (0) 3 minutes ago envy
[root@envythink envythink]# ls
the_run_exapmle.tar the_stop_example.tar

之后开发者就可以将导出的两个tar文件迁拷贝到其他机器上,然后再通过即将介绍的导入命令导入到系统中,进而实现容器的迁移。

导入容器为镜像

之前导出的容器tar文件可以通过docker import [container]命令导入变成镜像,其对应的格式为docker import [-c|--change[=]] [-m|--message[=MESSAGE]] file |URL|- [REPOSITORY[:TAG]]。解释一下上述命令中的选项参数:
(1)-c|--change[=],表示在导入容器的同时执行对容器进行修改的Dockerfile指令;
(2)-m|--message[=MESSAGE],表示导入镜像时设置的提交信息;

举个例子,将之前我们导出的the_stop_example.tar文件导入到系统中,并成为一个example/ubuntu:v1.0的镜像:

1
2
3
4
5
[root@envythink envythink]# docker import the_stop_example.tar example/ubuntu:v1.0
sha256:8f60b46a28166e775e1b94b9a24b8b4737634994432e36e1d84fe34ed5282d9c
[root@envythink envythink]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
example/ubuntu v1.0 8f60b46a2816 4 seconds ago 72.9MB

还记得之前在学习docker镜像的时候,我们使用docker load [image]命令来导入一个镜像,这个看似与这里介绍的docker import [container]命令相似,其实差别很大。

docker import [container]命令用于导入一个容器快照文件到本地镜像库。容器快照文件将丢弃所有的历史记录和元数据信息,也就是仅仅保存容器当时的快照状态,体积较小,且导入时可以重新指定标签等元数据信息;

docker load [image]命令用于导入镜像存储文件到本地镜像库。镜像存储文件将保存完整记录,包括所有的历史记录和元数据信息,它的体积更大。

查看容器

现在来学习几个和查看容器相关的命令,如inspect、top和stats等。

inspect查看容器详情信息

开发者如果想查看容器的详情信息,可以使用docker inspect [OPTIONS] NAME|ID [NAME|ID...] 命令,注意此命令会以JSON格式来返回容器的具体信息,如容器ID,创建时间、路径、状态、镜像、配置等各项信息。

举个例子,使用docker inspect命令来查看之前创建的别名为lichee的容器的信息:

1
[root@envythink envythink]# docker inspect lichee

注意上面也可以使用容器的ID,其查询结果为(部分):

top查看容器内进程

开发者如果想查看一个处于运行状态的容器内的进程,可以使用docker top CONTAINER命令,这个命令和Linux系统中的top命令非常相似,会打印出容器内的进程信息,包括PID、用户、时间和命令等。

举个例子,查看之前别名为lichee的容器,注意此时该容器已经处于运行状态:

1
2
3
[root@envythink envythink]# docker top lichee
UID PID PPID C STIME TTY TIME CMD
root 2486 2469 0 10:57 pts/0 00:00:00 /bin/bash
stats命令查看统计信息

开发者也可以使用docker stats [OPTIONS] [CONTAINER...]命令来查看统计信息,该命令会显示CPU、内存、存储、网络等使用情况的统计信息。这个OPTIONS可选参数有:
(1)-a, --all[=false],表示是否输出所有容器统计信息,默认是输出仅在运行中的容器信息;
(2)--format="",表示格式化输出信息;
(3)-f, --filter=,表示以指定的条件来过滤容器;
(4)-no-stream,表示不持续输出,默认会自动更新持续实时结果;
(5)--no-trunc[=false],表示不截断输出信息。

举个例子,查看当前所有处于运行状态容器的系统资源使用统计情况:

1
2
3
[root@envythink envythink]# docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
83f7959b96c9 lichee 0.00% 552KiB / 1.777GiB 0.03% 1.1kB / 0B 0B / 0B 1

其他容器命令

前面学习的都是常用的容器命令,接下来学习一些不常使用,但是使用起来可以大幅度减轻工作负担的命令,如cp、diff、port和update命令。

cp命令复制文件

开发者可以使用docker cp命令在容器和主机之间复制文件,其对应的格式为docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-或者docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH。这个OPTIONS可选参数有:
(1)-a, --archive[=false],打包模式,复制文件会带有原始的uid/gid信息;
(2)-L, --follow-link[=false],跟随软连接。当原路径为软连接时,默认只复制连接信息,如果使用该选项时则会复制连接的目标内容。

举个例子,将当前目录下的test.txt文件复制到别名为lichee的容器的/tmp目录下,使用的命令为:

1
[root@envythink envythink]# docker cp test.txt lichee:/tmp/

那么问题来了,我们怎么知道文件是否复制成功了呢?此时可以使用docker inspect lichee来查看其对应的目录:

当然开发者也可以直接使用find / -name test.txt命令来进行全文搜索:

1
2
3
4
[root@envythink envythink]# find / -name test.txt
/var/lib/docker/overlay2/dbc7f1e67edbca3dd4be913bd465ff2bc3c64b518d4c7eb8f7aebc1a791c0b0b/diff/tmp/test.txt
/var/lib/docker/overlay2/dbc7f1e67edbca3dd4be913bd465ff2bc3c64b518d4c7eb8f7aebc1a791c0b0b/merged/tmp/test.txt
/home/envythink/test.txt

可以看到这个文件被复制到了diff和merged目录下的tmp目录中,diff顾名思义就是容器内文件的变更,merged是合并的意思。

diff命令查看文件变更

开发者可以使用docker diff命令来查看容器内文件系统的变更,其对应的格式为 docker diff CONTAINER

举个例子,开发者查看别名为lichee的容器内的数据修改情况,可以使用docker diff命令:

1
2
3
4
5
[root@envythink envythink]# docker diff lichee
C /root
A /root/.bash_history
C /tmp
A /tmp/test.txt

其中的C表示改变,A表示新增。

port命令查看端口映射

开发者可以使用docker port命令来查看容器的端口映射情况,其对应的格式为docker port CONTAINER [PRIVATE_PORT[/PROTO]]

举个例子,开发者查看别名为lichee的容器的端口映射情况,可以使用docker port命令:

1
2
3
4
[root@envythink envythink]# docker container port lichee
[root@envythink envythink]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
83f7959b96c9 ubuntu:latest "/bin/bash" 14 hours ago Up 55 minutes lichee

由于这里别名为lichee的容器没有设置端口,因此其端口映射为空,无任何信息输出。

update命令更新配置

开发者可以使用docker update命令来更新容器的一些运行时配置,主要是资源限制份额,其对应的格式为docker update [OPTIONS] CONTAINER [CONTAINER...]。这个OPTIONS可选参数有:
(1)--blkio-weight=0,uint16类型,表示更新块IO限制,取值在10~1000之间,默认为0,代表无限制;
(2)--cpu-period=0,int类型,表示限制CPU调度器CFS(Completely Fair Scheduler)的使用时间,单位为微秒,最小为1000;
(3)--cpu-quota=0,int类型,表示限制CPU调度器CFS配额,单位为微秒,最小为1000;
(4)--cpu-rt-period=0,int类型,表示限制CPU调度器CFS的实时周期,单位为微秒;
(5)--cpu-rt-runtime=0,int类型,表示限制CPU调度器CFS的实时运行时,单位为微秒;
(6)--c, --cpu-shares=0,int类型,表示限制CPU使用份额;
(7)--cpus=,decimal类型,表示限制CPU个数;
(8)--cpu-period=0,int类型,表示限制CPU;
(9)--cpuset-cpus="",string类型,表示允许使用的CPU核,如0-3, 0,1;
(10)--cpuset-mems="",string类型,表示允许使用的内存块,如0-3, 0,1;
(11)--kernel-memory=0,bytes类型,表示限制使用的内核内存;
(12)-m, --memory=0,bytes类型,表示限制使用的内存;
(13)--memory-reservation=0,bytes类型,表示内存软限制;
(14)--memory-swap=0,bytes类型,表示内存加上缓存区的限制,-1表示对缓冲区无限制;
(15)--restart="",string类型,表示容器退出后的重启策略。

这些参数较多,这个命令在涉及到程序优化的时候才会使用,一般使用的不多。

举个例子,限制总配额为1秒,别名为lichee的容器所占用时间为10%,此时的代码为:

1
2
3
4
[root@envythink envythink]# docker update --cpu-quota 1000000 lichee
lichee
[root@envythink envythink]# docker update --cpu-period 100000 lichee
lichee

小结

本篇主要介绍了docker容器相关的一些重要操作,如创建、启动、查看、删除、守护态运行、停止、导入、导出等,当然这些已经能满足大部分的工作场景,在必要的时候开发者可以使用docker container help命令来查看docker支持的容器操作子命令。
在生产环境中,为了提高容器的高可用和安全,一般都会合理使用资源限制参数来管理容器的资源消耗,并通过指定合适的容器重启策略来自动重启退出的容器。当然也可以使用如HAProxy、F5等负载均衡软硬件来自动切换发生故障的应用容器,进而实现容器的高可用目的。