我来详细介绍 Docker 的整体架构:
Docker 架构图
┌─────────────────────────────────────────────────────────┐
│ Docker Client │
│ (docker CLI / Docker Desktop) │
└────────────────────┬────────────────────────────────────┘
│ REST API
↓
┌─────────────────────────────────────────────────────────┐
│ Docker Daemon (dockerd) │
│ ┌──────────────────────────────────────────────────┐ │
│ │ API Server │ │
│ └──────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Images Containers Networks Volumes │ │
│ └──────────────────────────────────────────────────┘ │
└────────────────────┬────────────────────────────────────┘
│
↓
┌─────────────────────────────────────────────────────────┐
│ containerd │
│ (容器运行时 - 高级运行时) │
└────────────────────┬────────────────────────────────────┘
│
↓
┌─────────────────────────────────────────────────────────┐
│ runc │
│ (容器运行时 - 低级运行时) │
│ (OCI Runtime Specification) │
└────────────────────┬────────────────────────────────────┘
│
↓
┌─────────────────────────────────────────────────────────┐
│ Linux Kernel (Host OS) │
│ Namespaces | Cgroups | Union FS | Network │
└─────────────────────────────────────────────────────────┘
核心组件详解
1. Docker Client (客户端)
- 用户与 Docker 交互的界面
- 常见形式:
dockerCLI 命令行工具- Docker Desktop GUI
- Docker Compose
- 通过 REST API 与 Docker Daemon 通信
bash
# 客户端命令示例
docker run nginx
docker build -t myapp .
docker-compose up
2. Docker Daemon (dockerd)
- Docker 的核心后台服务进程
- 主要职责:
- 监听 Docker API 请求
- 管理 Docker 对象(镜像、容器、网络、卷)
- 与其他 Docker daemons 通信(Swarm 模式)
- 调用 containerd 来管理容器生命周期
3. containerd
- 工业标准的容器运行时
- 职责:
- 镜像管理(拉取、推送、存储)
- 容器生命周期管理
- 网络和存储管理
- 调用 runc 启动容器
- 独立于 Docker,也被 Kubernetes 使用
4. runc
- OCI (Open Container Initiative) 标准实现
- 真正创建和运行容器的工具
- 轻量级、低级别的容器运行时
- 与 Linux 内核直接交互
5. Linux 内核特性
Namespaces (命名空间) - 提供隔离
- PID: 进程隔离
- NET: 网络隔离
- IPC: 进程间通信隔离
- MNT: 文件系统挂载隔离
- UTS: 主机名隔离
- USER: 用户隔离
Cgroups (控制组) - 资源限制
- CPU 限制
- 内存限制
- 磁盘 I/O 限制
- 网络带宽限制
Union FS (联合文件系统)
- OverlayFS, AUFS, Btrfs 等
- 实现镜像分层存储
工作流程示例
用户执行: docker run -d nginx
1. Docker Client
↓ 发送 REST API 请求
2. Docker Daemon
↓ 检查本地是否有 nginx 镜像
↓ 如果没有,从 Registry 拉取
↓ 调用 containerd
3. containerd
↓ 准备容器运行环境
↓ 准备镜像层
↓ 调用 runc
4. runc
↓ 创建 namespaces
↓ 设置 cgroups
↓ 启动容器进程
5. Container 运行中
↓ 进程在隔离环境中执行
镜像存储架构
┌─────────────────────────────────┐
│ Docker Image │
│ ┌───────────────────────────┐ │
│ │ Layer 4: App files │ │ ← 可写层 (容器层)
│ ├───────────────────────────┤ │
│ │ Layer 3: Dependencies │ │
│ ├───────────────────────────┤ │ ← 只读层 (镜像层)
│ │ Layer 2: Runtime │ │
│ ├───────────────────────────┤ │
│ │ Layer 1: Base OS │ │
│ └───────────────────────────┘ │
└─────────────────────────────────┘
网络架构
┌──────────────────────────────────────┐
│ Docker Network Types │
├──────────────────────────────────────┤
│ • bridge (默认) │
│ • host (共享主机网络) │
│ • none (无网络) │
│ • overlay (跨主机通信) │
│ • macvlan (分配 MAC 地址) │
└──────────────────────────────────────┘
数据存储架构
容器数据持久化方式:
1. Volumes (推荐)
├─ Docker 管理
└─ 存储位置: /var/lib/docker/volumes/
2. Bind Mounts
├─ 挂载主机目录
└─ 完全控制路径
3. tmpfs Mounts
└─ 内存存储,临时数据
关键设计原则
- 客户端-服务器架构: Client 和 Daemon 可以在不同机器上
- 分层架构: 每层职责明确,可独立替换
- 标准化: 遵循 OCI 标准,保证兼容性
- 插件化: 网络、存储驱动可插拔
- 安全隔离: 基于 Linux 内核特性实现容器隔离
这种架构设计使 Docker 既强大又灵活,能够高效地管理和运行容器化应用。
我来解释一下 Docker 中这三个核心概念的关系:
基本定义
Images (镜像)
- 只读的模板,包含运行应用所需的代码、运行时、库、环境变量和配置文件
- 类似于"类"或"安装包"的概念
- 通过 Dockerfile 构建或从 Docker Hub 拉取
Container (容器)
- 镜像的运行实例
- 类似于"对象"或"运行中的进程"
- 是镜像的可写层,容器删除后数据也会丢失
Volumes (卷)
- Docker 管理的持久化存储机制
- 独立于容器生命周期,容器删除后数据仍然保留
- 用于数据持久化和容器间数据共享
三者关系
Images (镜像) --实例化--> Container (容器) --挂载--> Volumes (卷)
↓ ↓ ↓
只读模板 运行实例 持久化存储
可复用 临时的 永久的
实际例子
bash
# 1. 拉取镜像
docker pull nginx:latest
# 2. 创建卷
docker volume create my-data
# 3. 从镜像创建容器并挂载卷
docker run -d \
--name my-nginx \
-v my-data:/usr/share/nginx/html \
nginx:latest
在这个例子中:
nginx:latest是 Imagemy-nginx是运行的 Containermy-data是 Volume,用于持久化网站数据
关键区别
- Image → Container: 一对多关系,一个镜像可以创建多个容器
- Volume → Container: 多对多关系,一个卷可以被多个容器共享
- 数据持久性: Image(不变) > Volume(持久) > Container(临时)
这种设计让 Docker 既灵活又高效:镜像保证环境一致性,容器提供隔离运行环境,卷确保数据不丢失。