Docker镜像和容器有什么区别
Docker镜像和容器是Docker技术的两个核心概念,它们的关系类似于**“类与实例”或“模板与运行对象”**。以下是它们的区别和联系:
1. 镜像(Image)
- 定义:镜像是一个静态的、只读的模板,包含运行应用程序所需的一切(代码、运行时环境、系统工具、配置等)。
- 特点:
- 不可修改:镜像一旦构建完成,内容无法直接更改(只能通过重新构建生成新镜像)。
- 分层存储:镜像由多个只读层(Layer)堆叠而成,不同镜像可以共享相同的层,节省存储空间。
- 可重复性:镜像是标准化的,确保在不同环境中运行一致。
- 创建方式:
- 通过编写
Dockerfile
并使用docker build
构建。 - 从远程仓库(如Docker Hub)拉取(
docker pull
)。 - 基于现有容器提交为镜像(
docker commit
,不推荐常规使用)。
- 通过编写
2. 容器(Container)
- 定义:容器是镜像的一个运行实例,类似于一个轻量级的虚拟机进程。
- 特点:
- 动态可写:容器启动后,会在镜像的只读层上添加一个可写层(容器层),所有修改(如文件写入、配置变更)都保存在此层。
- 生命周期:容器可以被启动、停止、删除,其状态是临时的(默认情况下,容器停止后数据会丢失)。
- 隔离性:容器通过Linux内核的命名空间(Namespaces)和控制组(Cgroups)实现资源隔离(如进程、网络、文件系统等)。
- 操作方式:
- 通过
docker run
从镜像启动容器。 - 通过
docker start/stop/restart
管理容器状态。 - 通过
docker rm
删除容器。
- 通过
关键区别总结
特性 | 镜像(Image) | 容器(Container) |
---|---|---|
状态 | 静态、只读 | 动态、可读写(通过容器层) |
存储 | 多层只读文件系统 | 镜像层(只读) + 容器层(可写) |
生命周期 | 持久化存储(除非主动删除) | 临时性(停止后容器层默认不保留,需通过卷持久化数据) |
创建方式 | Dockerfile 构建或从仓库拉取 | 通过 docker run 从镜像启动 |
数量关系 | 一个镜像可启动多个容器 | 每个容器基于一个镜像运行 |
类比理解
- 镜像:类似操作系统的安装光盘(
.iso
文件),是静态的模板。 - 容器:类似用光盘安装好的正在运行的电脑系统,可以操作、修改,但关闭后默认不保存状态(除非主动保存数据)。
示例流程
- 构建镜像:编写
Dockerfile
→docker build -t my-app .
。 - 启动容器:
docker run -d --name my-container my-app
。 - 修改容器:进入容器(
docker exec -it my-container bash
)并修改文件。 - 保存状态(可选):若需要保留修改,可提交容器为新镜像(
docker commit my-container my-app:v2
),但更推荐通过更新Dockerfile
重新构建。
核心总结
- 镜像是模板,容器是实例。
- 镜像不可变,容器可变。
- 镜像用于分发和标准化,容器用于运行和隔离环境。