Docker 中卷、容器、镜像的区别
🎯 核心概念比喻
想象一个面向对象编程的类比:
- 镜像 = 类(模板、蓝图)
- 容器 = 对象(类的实例)
- 卷 = 外部存储(数据库、文件系统)
📝 详细对比
概念 | 说明 | 生命周期 | 读写特性 | 类比 |
---|---|---|---|---|
镜像 | 只读模板,包含应用和运行环境 | 持久化存储 | 只读 | 软件安装包(.exe文件) |
容器 | 镜像的运行实例 | 临时性,可随时创建/删除 | 读写层(基于镜像) | 正在运行的进程 |
卷 | 持久化数据存储 | 独立于容器生命周期 | 读写 | 外接硬盘/U盘 |
🔍 深入详解
1. 镜像 - 只读的模板
# Dockerfile - 构建镜像的配方
FROM ubuntu:20.04
COPY app.py /app/
RUN pip install -r requirements.txt
CMD ["python", "/app/app.py"]
特性:
- ✅ 只读,不可修改
- ✅ 分层存储,每层都有唯一哈希
- ✅ 可共享(通过 Docker Hub)
- ✅ 可版本控制(标签)
# 相关命令
docker images # 查看镜像
docker pull nginx:latest # 下载镜像
docker build -t myapp . # 构建镜像
docker rmi <image_id> # 删除镜像
2. 容器 - 运行中的实例
# 基于镜像创建容器
docker run -d --name my-container nginx:latest
特性:
- ✅ 可写(在镜像基础上添加读写层)
- ✅ 临时性(删除后数据丢失)
- ✅ 隔离性(有自己的文件系统、网络、进程空间)
- ✅ 轻量级(共享主机内核)
# 容器生命周期
docker run # 创建并启动
docker start/stop # 启动/停止
docker exec -it bash # 进入运行中的容器
docker rm # 删除容器
3. 卷 - 持久化数据
# 创建和使用卷
docker volume create my-volume
docker run -v my-volume:/data nginx
特性:
- ✅ 持久化(独立于容器)
- ✅ 可共享(多个容器可挂载同一卷)
- ✅ 高性能(不经过存储驱动)
- ✅ 可备份迁移
# 卷管理
docker volume create # 创建卷
docker volume ls # 列出卷
docker volume inspect # 查看卷详情
docker volume rm # 删除卷
🎯 实际工作流示例
场景:部署一个 Web 应用
# 1. 获取镜像(从Docker Hub)
docker pull nginx:1.21# 2. 创建数据卷(持久化存储)
docker volume create app-data# 3. 运行容器(基于镜像创建实例)
docker run -d \--name web-server \-v app-data:/usr/share/nginx/html \-p 80:80 \nginx:1.21# 此时:
# - nginx:1.21 是镜像(只读模板)
# - web-server 是容器(运行实例)
# - app-data 是卷(持久化存储网站文件)
📊 数据流向图
镜像 (只读)↓
容器 (读写层) ←→ 卷 (持久化数据)↓
应用运行状态
🔄 生命周期关系
💡 关键区别总结
-
持久性:
- 镜像:永久存在(除非删除)
- 容器:临时存在
- 卷:永久存在(用于数据持久化)
-
可写性:
- 镜像:只读
- 容器:可写(但数据随容器删除而丢失)
- 卷:可写(数据持久化)
-
用途:
- 镜像:打包应用和环境
- 容器:运行应用
- 卷:存储数据
🛠 最佳实践
- 镜像应该尽量小而精简
- 容器应该是无状态的
- 卷用于存储需要持久化的数据
- 重要数据永远不要只存在容器层
理解这三者的关系是掌握 Docker 的关键!