问题: Docker的镜像和容器的概念和联系

👇 点击展开/折叠 面试背诵模板(建议先背这个) Docker镜像是只读的静态模板,包含运行应用程序所需的文件系统、代码、依赖、库和配置,不包含运行状态。Docker容器是镜像的可运行实例,在镜像之上增加了一层可写层,包含进程、网络、文件系统状态等运行时环境。二者的关系类似“类与对象”或“程序与进程”:镜像是构建容器的蓝图,容器是镜像的动态执行实体。同一镜像可创建多个相互隔离的容器实例。容器停止后,其可写层数据默认保留,可重新启动或commit为新镜像。
---

一、镜像(Image)的详细概念

定义:Docker镜像是轻量级的、只读的、分层存储的模板,包含了运行应用程序所需的一切——代码、运行时、系统工具、库和设置。它本质上是一个只读文件系统,以分层结构(UnionFS)存储,每一层代表Dockerfile中的一条指令。镜像不包含任何运行状态(如进程、内存数据),因此是静态的、不可变的。

特点:

  • 只读:镜像内容不可修改,任何修改都会在容器层进行
  • 分层:采用联合文件系统(UnionFS),每层叠加形成完整文件系统
  • 可复用:多个容器可共享同一镜像层,节省存储空间

二、容器(Container)的详细概念

定义:容器是镜像的可运行实例,在镜像只读层之上增加了一个可写层(容器层)。它包含了运行中的进程、网络配置、挂载卷、环境变量等动态状态。容器是一个隔离的进程环境,拥有自己的文件系统、网络栈和资源限制。

特点:

  • 可写:容器层是可读写的,所有运行时修改(日志、文件变更)都写在这一层
  • 有状态:包含运行时的进程状态、内存数据、网络连接等
  • 隔离:每个容器拥有独立的命名空间(进程、网络、文件系统)
  • 生命周期:容器可被启动、停止、删除、重启,状态变化不影响镜像

三、核心联系

① 类是模板,对象是实例
镜像相当于“类”(蓝图/模板),容器相当于“对象”(实例)。一个镜像可以创建多个容器实例,每个容器相互隔离,拥有独立的可写层和运行状态。

② 构建与运行的关系
镜像通过Dockerfile构建(docker build),容器通过镜像运行(docker run)。构建生成镜像,运行产生容器。本质上,镜像用于分发和存储,容器用于执行和运行。

③ 容器状态可持久化
容器停止后,其可写层数据默认保留,不会被清除。可以重新启动已停止的容器,恢复之前的运行状态。如果需要保留容器修改后的状态,可以用docker commit将容器状态保存为新镜像。

四、工作流程示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 1. 拉取镜像(从仓库下载到本地)
docker pull nginx:latest

# 2. 查看本地镜像列表
docker images

# 3. 基于镜像创建并运行容器
docker run -d --name my-nginx nginx:latest

# 4. 查看运行中的容器
docker ps

# 5. 停止容器
docker stop my-nginx

# 6. 删除容器
docker rm my-nginx

# 7. 删除镜像
docker rmi nginx:latest

五、镜像与容器的核心对比

维度 Docker镜像 Docker容器
本质 只读模板 可运行实例
状态 静态(不包含运行时状态) 动态(包含进程、内存、网络)
存储位置 镜像仓库 + 本地缓存 运行时的可写层 + 本地存储
生命周期 长期保存,可版本管理 临时或持久化,可启停删除
分层结构 多层只读层(UnionFS) 镜像层 + 一层可写容器层
修改 不可修改(需重新构建) 可修改(写入容器层)
删除影响 依赖该镜像的容器无法启动 删除容器不影响镜像本身