前言
在云原生技术体系中,Docker 容器作为核心的运行单元,其操作的熟练度直接决定了应用交付与运维的效率。本文将依据实际的操作流程,深入剖析容器的创建、管理、状态流转、交互模式以及资源监控等关键知识点。我们将透过命令行交互的表象,理解 Docker 守护进程在后台的具体行为。
一、 容器基础操作全流程
容器的生命周期始于镜像。在启动任何容器之前,首要任务是确认本地环境中是否存在所需的基础镜像。
1. 镜像检查与获取
在进行容器实例化之前,通过 docker images 命令可以检索本地仓库中已下载的镜像资源。
bash
docker images nginx
执行上述命令后,终端会输出符合条件的镜像列表。

上图展示了命令的执行结果。可以看到,虽然指定了 nginx 关键字,但列表可能为空或者显示已有的版本。若本地不存在指定标签(Tag)的镜像,在后续执行运行命令时,Docker 守护进程会触发自动下载机制。
2. 容器的创建与启动
docker run 是 Docker 中功能最复杂、参数最多的命令之一。它负责将静态的镜像实例化为动态的进程。
bash
docker run -d --name myweb1 -p 8090:80 nginx:1.22.0
该命令包含几个关键参数的组合应用:
- -d (Detached):指示容器在后台运行,而非直接霸占当前的终端窗口。这是生产环境中服务的标准运行模式。
- --name myweb1:为容器指定一个具有业务含义的名称,便于后续管理。如果不指定,Docker 会生成随机名称。
- -p 8090:80:定义端口映射规则。宿主机的 8090 端口被绑定到容器内部的 80 端口。这意味着外部请求访问宿主机 8090 时,流量会被 iptables 规则转发至容器内的 Nginx 服务。
- nginx:1.22.0:指定具体使用的镜像版本。
由于本地环境中并未预先下载 nginx:1.22.0 这个特定版本,Docker 客户端检测到本地缺失后,自动向 Registry(通常是 Docker Hub)发起拉取请求。

上图中清晰地记录了这一过程:首先提示 "Unable to find image... locally",随即开始 "Pulling from library/nginx"。多行进度条代表了镜像的分层(Layer)结构,每一层都在并行下载,最终输出 Digest 摘要和 Status 状态,表明容器启动成功,并返回了一个长字符的容器 ID。
3. 验证容器运行状态
容器启动后,需要验证其是否处于预期的运行状态。
bash
docker ps
docker ps 命令仅显示当前处于 Running 状态的容器。

从上图的输出信息中,可以获取多维度的关键信息:
- CONTAINER ID:容器的唯一简短标识。
- IMAGE:使用的镜像版本。
- COMMAND :容器启动时执行的入口指令,此处为
/docker-entrypoint...。 - STATUS :显示
Up 6 seconds,表明容器已健康运行了 6 秒。 - PORTS :清晰地展示了
0.0.0.0:8090->80/tcp的端口转发关系。
4. 深入探查容器详情
当需要获取容器的元数据,如 IP 地址、挂载卷路径、环境变量或具体的配置参数时,docker ps 提供的信息已显不足,此时需要使用 inspect 命令。
bash
docker container inspect myweb1
bash
# 或者简写为
docker inspect myweb1

上图展示了 inspect 命令输出的 JSON 格式数据片段。这通常是一个庞大的数据结构,包含了容器的完整配置蓝图。运维人员可以通过解析这个 JSON 来排查网络模式(NetworkSettings)、挂载点(Mounts)以及状态代码(State)等深层问题。
5. 日志监控
对于后台运行(-d)的容器,其标准输出(STDOUT)和标准错误(STDERR)会被 Docker 守护进程捕获并存储。
bash
docker logs -f myweb1
参数 -f (follow) 类似于 Linux 的 tail -f,能够实时持续地输出日志流。

上图中显示了 Nginx 服务的启动日志以及可能的访问日志。这是排查应用启动失败或运行时错误的最直接手段。
6. 容器的停止与清理
完成任务后,为了释放系统资源,需要停止并移除容器。
bash
docker stop myweb1
该命令向容器内的主进程(PID 1)发送 SIGTERM 信号,给予进程优雅退出的时间。

上图简单返回了容器名称,表明停止操作已被接收并处理。
容器停止后,其文件系统仍然保留在磁盘上。若要彻底清除,需执行删除操作:
bash
docker rm myweb1

执行删除后,该容器及其内部的可写层数据将被永久移除(除非挂载了外部数据卷)。
二、 容器状态迁移机制
容器并非只有"运行"和"停止"两种状态,了解完整的状态机对于复杂场景的运维至关重要。
1. 仅创建不运行 (Created)
docker create 命令用于创建一个新容器,但并不立即启动它。这在需要预先分配容器资源或配置,但稍后才执行的场景中非常有用。
bash
docker create --name myweb2 -p 8079:80 nginx:1.23.3

上图中,命令执行后仅返回了一个长 ID,并未显示镜像拉取或启动日志(假设镜像已存在)。此时容器处于 Created 状态,占用存储空间但不占用 CPU 和内存资源。
2. 状态流转操作
启动容器:
将 Created 状态或 Exited 状态的容器转变为 Running 状态。
bash
docker start myweb2

强制终止 (Kill):
与 stop 不同,kill 直接发送 SIGKILL 信号,强制结束进程,不给进程清理资源或保存数据的机会。
bash
docker kill myweb2

重新启动 (Start 再次激活):
被 Kill 掉的容器处于 Exited 状态,可以通过 Start 再次拉起。
bash
docker start myweb2

优雅停止 (Stop):
标准的停止操作。
bash
docker stop myweb2

重启 (Restart):
restart 实际上是 stop 和 start 的组合动作。
bash
docker restart myweb2

注意上图中 docker restart 执行后,若立即查看 docker ps,会发现容器的 STATUS 时间被重置,表明进程被重新创建了。
暂停与恢复 (Pause/Unpause):
pause 不同于 stop,它利用 cgroups 的特性冻结容器内所有进程的 CPU 执行,但进程仍然存在于内存中,状态保持不变。
bash
docker pause myweb2

此时如果查看 docker ps,该容器状态会显示为 (Paused)。
解除暂停使用 unpause:
bash
docker unpause myweb2

容器瞬间恢复运行,且不涉及进程重启。
三、 容器的批量搜索与过滤技巧
当宿主机上运行着数十甚至上百个容器时,单纯使用 docker ps 配合人眼查找效率极低。Docker 提供了强大的 --filter (简写为 -f) 参数。
常用过滤参数速查表:
| 命令 | 功能解释 |
|---|---|
docker container ls -qf name=xxx |
仅返回名称匹配的容器 ID |
docker container ls --filter status=running |
筛选正在运行的容器 |
docker container ls -aq |
静默模式列出所有容器(含已停止)的 ID |
docker container ls --filter ancestor=xxx |
筛选基于指定镜像(名称或 ID)创建的所有容器 |
首先查看当前的容器环境全貌:

上图显示了若干个处于 Exited 或 Up 状态的容器,名字各异,环境较为杂乱。
1. 基于名称过滤
支持模糊匹配或精确匹配容器名称。
bash
docker ps -f name=mt1

上图结果精准定位到了名字包含 "mt1" 的容器。
2. 基于状态过滤
这是运维排查中最常用的功能,例如快速找出所有挂掉的容器。
bash
docker ps -f status=running

上图仅列出了正在运行的容器。
bash
docker ps -f status=exited

上图则列出了所有已停止退出的容器。
3. 基于镜像(祖先)过滤
当需要升级某个基础镜像或排查特定镜像版本产生的问题时,ancestor 过滤器非常有效。
通过镜像名称过滤:
bash
docker ps -f ancestor=nginx:1.23.3

上图展示了所有基于 nginx:1.23.3 版本启动的容器。
通过镜像 ID 过滤:
即使镜像标签发生变化,镜像 ID 通常是恒定的。
bash
docker ps -f ancestor=ac232364af84

结合 -a (所有状态) 和 -q (仅显示 ID) 参数,可以构建出强大的自动化脚本命令基础。
bash
docker ps -f ancestor=ac232364af84 -a

上图列出了基于该镜像的所有容器的完整信息。
bash
docker ps -f ancestor=ac232364af84 -q

上图仅输出了容器 ID 列表,这正是批量操作所需要的输入格式。
四、 容器的批量操作实战
在掌握了 -q 输出 ID 的技巧后,可以结合 Linux 的命令替换功能(Command Substitution,即反引号 ````` 或 $()),实现对容器的批量管理。
首先,确认当前环境中有多个容器存在:
bash
docker ps -a

1. 批量停止容器
假设需要维护宿主机,停止所有正在运行的容器。
首先获取运行中容器的 ID:
bash
docker ps -q

将上述命令作为 docker stop 的参数:
bash
docker stop `docker ps -q`

上图中,Shell 先执行了反引号内的命令,获取 ID 列表,然后传递给 stop 命令。输出的一系列 ID 表明这些容器已被成功接收停止指令。
2. 批量启动容器
同理,可以一键拉起所有处于停止状态的容器。
这里使用 docker ps -a -q 获取所有容器 ID(包括已停止的):
bash
docker ps -a -q

执行批量启动:
bash
docker start `docker ps -a -q`

上图显示所有容器 ID 被再次打印,意味着它们均已收到启动信号。
五、 容器的交互模式详解
Docker 容器的运行模式主要分为 Attached(前台/附属)和 Detached(后台/分离),以及特定的 Interactive(交互式)模式。
1. Attached 模式(前台阻塞)
默认情况下,如果不加 -d 参数,docker run 会在前台运行。
bash
docker run --name mynginx -p 8106:80 ac232364af84
注意:此处使用的是镜像 ID 启动。

上图可见,终端被容器的日志输出占据,光标不再返回命令行提示符。此时容器的标准输出直接绑定到了当前终端。
在另一个终端查看,容器确实在运行:

回到运行容器的终端,按下 Ctrl + C:

Ctrl + C 发送了中断信号,容器随之停止并退出。
检查状态:
bash
docker ps -a

容器状态变为 Exited。这证明 Attached 模式不适合生产环境,因为它极易受终端连接断开或误操作的影响。它主要用于调试或查看启动阶段的即时报错。
2. Detached 模式(后台守护)
这是生产环境的标准用法,通过 -d 实现。
bash
docker run -d --name mynginx2 -p 9107:80 nginx:1.23.3

容器启动后立即返回 ID,Shell 恢复控制权。此时容器在后台运行,不受终端关闭影响。
若需查看日志,需显式调用 logs 命令:
bash
docker logs -f mynginx2

3. Interactive 模式(交互式 Shell)
当需要进入容器内部进行调试、文件查看或执行临时任务时,需要创建一个交互式容器或进入现有容器。
创建时直接进入:
bash
docker run -it --name mynginx001 -p 8105:80 nginx:1.23.3 bash
- -i (Interactive): 保持 STDIN 打开,允许用户输入。
- -t (TTY): 分配一个伪终端。
- bash: 指定容器启动后执行的命令为 shell,而非默认的 nginx 启动脚本。

上图显示提示符变成了 root@8e...:/#,说明已成功登录容器内部系统。
退出容器:

在 shell 中输入 exit 或 Ctrl+D,容器的主进程(bash)结束,容器随之停止。
在运行中容器执行命令 (Exec):
对于已经在后台运行的容器(如 mynginx2),使用 exec 命令"钻"进去,而不影响原有服务的运行。
bash
docker exec -it mynginx2 bash

这会启动一个新的 Bash 进程连接到该容器。这是排查线上问题的最常用手段。
六、 容器与宿主机的数据交互(CP 命令)
在容器化环境中,有时需要修改容器内的配置文件,但容器镜像通常是精简的(基于 Debian-slim 或 Alpine),可能没有安装 vim 或 nano 等编辑器。此时,docker cp 就成了救命稻草。
1. 准备环境
启动一个后台 Nginx 容器:
bash
docker run -d --name mynginx -p 8080:80 nginx:1.23.3

2. 定位目标文件
进入容器确认文件路径:
bash
docker exec -it mynginx bash
cd /usr/share/nginx/html/

查看默认的 index.html 内容:

确认无 vim 编辑器:

上图显示 bash: vim: command not found。
3. 复制文件到宿主机
退出容器,在宿主机执行复制命令。格式为 docker cp <container_id>:<path> <local_path>。
bash
docker cp mynginx:/usr/share/nginx/html/index.html .

文件被成功复制到当前目录。
4. 修改并覆盖回容器
在宿主机上使用熟悉的编辑器修改文件:

上图中,我们将标题修改为了 "hello nanjing"。
将修改后的文件复制回容器,覆盖原文件:
bash
docker cp ./index.html mynginx:/usr/share/nginx/html/index.html

命令执行无报错,即为成功。
5. 验证修改
再次进入容器查看:
bash
docker exec -it mynginx bash
cat /usr/share/nginx/html/index.html

或者直接通过浏览器/curl 访问映射端口:

页面成功展示了 "hello nanjing"。
七、 容器的高级生命周期策略
Docker 提供了自动化机制来管理容器的生存期和自愈能力。
1. 自动删除 (--rm)
对于临时任务(如运行一次脚本、测试某个命令),容器退出后留下的尸体(Exited 状态)需要手动清理,非常麻烦。使用 --rm 参数,容器在退出时会自动销毁。
bash
docker run -it --rm --name mynginx01 -p 8081:80 nginx:1.23.3 bash
容器运行中:

当在容器内输入 exit 退出后,再执行 docker ps -a 将找不到该容器。这保持了环境的整洁。
2. 自动重启策略 (--restart)
生产环境要求服务具备自愈能力。--restart 参数控制容器退出后的行为。
no: 默认值,不重启。on-failure: 非 0 状态码退出时重启(可指定次数)。always: 无论如何都重启(手动 stop 除外)。unless-stopped: 类似 always,但若容器在 Docker 守护进程启动前就是停止的,则不启动它。
演示 always 策略:
bash
docker run -d --name mynginx001 -p 8125:80 --restart=always nginx:1.23.3
检查运行状态,查看 restart 策略详情:
bash
docker container inspect mynginx001

inspect 结果确认 RestartPolicy 的 Name 为 always。
模拟故障:
进入容器,手动停止 Nginx 进程,模拟应用崩溃。
bash
docker exec -it mynginx001 bash
nginx -s quit

观察宿主机的 docker ps:

注意 STATUS 栏,显示 Up Less than a second,这说明容器检测到主进程退出,立即被 Docker 守护进程重启了。
手动停止的例外:
如果运维人员显式执行 docker stop,Docker 会认为这是预期行为,不会触发 always 策略。
bash
docker stop mynginx001

容器保持 Exited 状态,不再自动重启。
八、 环境变量配置管理
环境变量是云原生应用配置解耦的核心。
1. 命令行直接注入 (-e)
使用 -e KEY=VALUE 格式。
bash
docker run -it --rm -e MYTEST=1 --name mynginx001 -p 8081:80 nginx:1.23.3 bash
进入容器后查看:

env 命令显示 MYTEST=1 已生效。
2. 文件批量注入 (--env-file)
当变量较多或涉及敏感信息时,写入文件更安全、易管理。
创建 myenv 文件:

内容包含 mytest=100 等。
加载文件启动:
bash
docker run -it --rm --env-file=./myenv nginx:1.23.3 bash
验证变量:

grep 结果显示变量已成功读入。
九、 容器信息深入查阅
除了前文提到的 inspect,了解如何验证自定义配置也很重要。
启动一个包含复杂参数(端口、环境变量、主机名 -h)的容器:
bash
docker run -d --name 001 -p 8021:80 -e MYTEST=1 -h kk nginx:1.23.3
再次使用 inspect 查看配置落地情况:
bash
docker container inspect 001

上图中 JSON 数据的 Env 数组和 Hostname 字段准确反映了启动时的参数。
十、 特殊任务执行(Busybox)
有时不需要运行完整的服务,只需一个微型 Linux 环境执行特定命令。Busybox 镜像是首选,它集成了常用 Unix 工具但体积极小。
bash
docker run --rm busybox:1.36.0 ifconfig

该命令启动容器,执行 ifconfig 打印网络信息,然后容器立即销毁(配合 --rm)。这是查看 Docker 默认网桥网段的快捷方式。
十一、 容器迁移技术(导入与导出)
这是 Docker 镜像迁移的一种特殊方式,不同于 save/load,export/import 针对的是容器的文件系统快照。
1. 准备工作
启动一个 Nginx 容器,并修改其首页内容,确保它与原始镜像不同。
bash
docker run -d --name haha -p 8085:80 nginx:1.23.3
docker exec -it haha bash
# 在内部进行修改...


2. 导出容器 (Export)
将容器 haha 的当前文件系统状态打包为 tar 文件。
bash
docker export -o mynginx.tar mynginx
# 注意:截图命令使用的是 mynginx 容器名,实际上应对应操作的容器名

此时得到了一个包含容器内所有文件(含被修改的 html)的压缩包。
3. 跨服务器传输
使用 scp 将 tar 包发送到另一台机器。
bash
scp mynginx.tar root@123.60.26.220:/root/mydir

4. 导入为镜像 (Import)
在目标机器上,将 tar 包恢复为镜像。
bash
docker import mynginx.tar mynginx:v0.30

5. 核心陷阱与解决
尝试使用新镜像启动容器:
bash
docker run -d --name 001 -p 80:80 mynginx:v0.30

容器会立即报错停止。
原因分析:
使用 inspect 查看镜像详情:
bash
docker image inspect mynginx:v0.30

docker export 导出的仅是文件系统,丢失了原始镜像的元数据(Metadata) ,包括 CMD 和 ENTRYPOINT。Docker 不知道启动这个镜像时该运行什么进程。
解决方案:
在 docker run 时显式指定启动命令。对于 Nginx,通常是 nginx -g "daemon off;" 以保持前台运行。
bash
docker run -d --name 001 -p 80:80 mynginx:v0.30 nginx -g "daemon off;"

此时容器成功启动,且包含了之前修改过的文件内容。
十二、 高级日志与资源监控
1. 日志高级控制
启动容器 mynginx011。
bash
docker run -d --name mynginx011 -p 8093:80 nginx:1.23.3

全量查看:
bash
docker logs mynginx

实时滚动 (Follow):
bash
docker logs -f mynginx

查看尾部指定行数 (Tail):
这在日志文件巨大时非常有用,避免刷屏。
bash
docker logs -f -n 5 mynginx

上图仅显示了最后 5 条日志记录。
2. 资源监控 (Stats & Top)
运维人员需要掌握容器消耗了多少物理资源。
实时资源流 (Stats):
bash
docker stats mtnginx

上图展示了一个实时的监控面板,包括 CPU 使用率、内存占用(Usage/Limit)、网络 I/O 和 磁盘 I/O。这是排查性能瓶颈的第一手资料。
进程查看 (Top):
查看容器内部运行了哪些进程。
bash
docker top mynginx aux

上图列出了容器内的进程列表。注意这里显示的 PID 是宿主机视角的 PID,或者是经过命名空间映射后的视图,可以用来追踪僵尸进程或异常高负载进程。
通过以上十二个章节的详细拆解,我们完成了从容器创建、管理、交互、配置到监控的完整闭环。熟练掌握这些命令及其背后的原理,是成为 Docker 容器专家的必经之路。