04 容器操作:得心应手掌握 Docker 容器基本操作¶
面试中经常会被问到“容器和镜像的区别是什么”。简单来说,镜像是一个包含完整根文件系统的静态只读模板;而容器则是基于镜像创建的、包含了可写层的动态运行实例。
本课时将深入讲解容器的本质概念、生命周期模型以及生产实践中的核心操作命令。
1. 容器(Container)是什么?¶
容器是基于镜像创建的可运行实例,独立且隔离。当运行容器化环境时,实际上是在镜像只读层(Read-Only Layer)之上添加了一个全新的可写层(Read-Write Container Layer),允许在容器内部修改整个文件系统的副本。
图 1:容器结构组成
2. 容器的生命周期¶
容器的生命周期包含以下 5 种状态:
- created:初建状态(容器已创建但未启动进程);
- running:运行状态(容器主进程在后台或前台正常运行);
- stopped:停止/终止状态(主进程已退出或被终止);
- paused:暂停状态(进程通过 Cgroups Freezer 被冻结挂起);
- deleted:删除状态(容器文件系统及元数据被彻底物理删除)。
容器生命周期转换关系如下图所示:
图 2:容器生命周期状态转换
状态转化关系:
docker create创建容器 -> created;docker start启动容器 -> running;docker stop停止容器 -> stopped;docker pause暂停容器 -> paused;docker unpause恢复容器 -> running;docker rm强制或正常清除容器 -> deleted。
3. 容器的核心操作¶
容器的操作包含五个核心步骤:创建与启动、终止与重启、进入容器、删除容器、导入与导出容器。
3.1 创建并启动容器¶
容器极其轻量,可以快速创建与销毁。
1. 创建容器 (docker create)¶
终端输出示例:
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
61c5ed1cbdf8: Pull complete
Digest: sha256:4f47c01fa91355af2865ac10fef5bf6ec9c7f42ad2321377c21e844427972977
Status: Downloaded newer image for busybox:latest
2c2e919c2d6dad1f1712c65b3b8425ea656050bd5a0b4722f8b01526d5959ec6
查看已创建的容器列表:
2. 启动已创建的容器 (docker start)¶
使用 docker ps 查看处于运行状态的容器:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d6f3d364fad3 busybox "sh" 16 seconds ago Up 8 seconds busybox
3. 新建并启动容器 (docker run)¶
docker run 相当于组合执行了 docker create 和 docker start:
docker run 后台执行流程:
- 检查本地是否存在指定镜像,若无则从 Docker Hub 自动拉取;
- 基于镜像创建并启动容器;
- 为容器分配独占的文件系统,在只读层之上挂载一个可写层;
- 从 Docker 虚拟网络 Bridge 中分配一个独立 IP;
- 执行用户的入口启动命令(如
/bin/sh)。
参数 -t 分配伪终端,-i 打开容器的 STDIN 输入流,组合 -it 可直接进入容器的交互模式:
容器内部的 1 号进程即为启动命令 sh。在 Docker 架构中,当容器内部的 1 号主进程退出时,容器也会随之终止。
3.2 终止与重启容器¶
1. 停止运行中的容器 (docker stop)¶
docker stop 首先向容器 1 号进程发送 SIGTERM 优雅终止信号。若在默认超时时间(10秒)内未响应,则发送 SIGKILL 强行终止。
查看已停止的容器状态:
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
28d477d3737a busybox "sh" 26 minutes ago Exited (137) About a minute ago busybox
2. 重启容器 (docker restart)¶
docker restart 会直接停止并重新启动容器:
3.3 进入容器¶
1. 使用 docker attach 附加进容器¶
注意:
docker attach直接挂载到容器的 1 号进程。当多个终端同时使用attach时,所有窗口会完全同步屏显;一旦阻塞其他终端也无法输入。若在终端使用exit退出,会导致容器 1 号进程终止而使容器关闭。因此生产中一般不推荐使用attach。
2. 使用 docker exec 启动新进程进入(推荐)¶
docker exec 可以在已运行的容器内派生启动一个全新的独立进程:
在容器内查看进程列表:
可以看到新启动了一个独立的 PID 为 7 的 sh 进程。退出该 sh 窗口不会影响容器 1 号主进程的运行。
3.4 删除容器¶
1. 删除已停止的容器¶
2. 强制删除正在运行的容器 (-f)¶
开启 -f 参数后,Docker 会首先向容器发送 SIGKILL 强行杀掉进程,随后清理其存储与元数据。
3.5 导出与导入容器¶
1. 导出容器 (docker export)¶
不管容器当前是否处于运行状态,均可将其文件系统整体导出为 Tar 压缩归档:
先在容器内创建一个测试文件:
执行导出命令:
2. 导入容器快照为镜像 (docker import)¶
使用 docker import 可以将导出的容器快照文件直接导入为本地镜像:
查看导入后镜像的内容:
$ docker run -it busybox:imported sh
/ # ls -l /tmp/
-rw-r--r-- 1 root root 0 Jul 30 14:30 test_file.txt
可以看到之前在容器内部新建的临时文件被完好无损地迁移到了新的镜像中,从而实现了容器数据与镜像的跨机器迁移。
结语¶
本课时讲解了容器的本质概念、生命周期的 5 种状态,以及 create、start、run、exec、stop、rm、export/import 等核心操作命令。
思考题: 为什么容器的文件系统要设计成 Copy-on-Write(写时复制)的分层架构(如图 1 所示),而不是为每个容器完整单独复制一份镜像文件? 欢迎在留言区讨论。

