Files
docker_practice/01_introduction/why.md

209 lines
8.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 为什么要使用 Docker
在回答"为什么用 Docker"之前笔者想先问一个问题**你有没有经历过这些场景**
## 没有 Docker 的世界
### 场景一"在我电脑上明明能跑"
```
周五下午 5:00
├── 开发者:代码写完了,本地测试通过,提交!🎉
├── 周一早上 9:00
│ └── 测试:"这个功能在测试环境跑不起来"
└── 开发者:" 不可能,在我电脑上明明能跑啊……"
```
笔者统计过这个问题通常由以下原因导致
- Python/Node/Java 版本不一致
- 依赖库版本不一致
- 操作系统配置不一致
- 某些环境变量没有设置
- "哦,忘了说我本地装了个 XXX"
### 场景二环境配置的噩梦
```
新同事入职
├── Day 1领电脑配环境
├── Day 2继续配环境遇到问题
├── Day 3换种方法配环境
├── Day 4问老同事怎么配的他也忘了
└── Day 5终于能跑起来了但不知道为什么……
```
### 场景三服务器迁移的恐惧
```
运维:"我们需要把服务迁移到新服务器"
开发:"旧服务器上的配置文档在哪?"
运维:"当时是一个已经离职的同事配的……"
所有人:😱
```
## Docker 如何解决这些问题
### 核心理念一次构建到处运行
```
开发环境 测试环境 生产环境
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Docker │ = │ Docker │ = │ Docker │
│ 镜像 │ │ 镜像 │ │ 镜像 │
└─────────┘ └─────────┘ └─────────┘
↓ ↓ ↓
完全一致 完全一致 完全一致
```
## Docker 的核心优势
### 1. 环境一致性
Docker 镜像包含了应用运行所需的**一切**代码运行时系统工具配置这意味着
- 开发环境和生产环境完全一致
- 不会再有"在我机器上能跑"的问题
- 新人入职一条命令就能启动开发环境
```bash
# 新同事入职第一天
$ git clone https://github.com/company/project.git
$ docker compose up
# 完整的开发环境就准备好了
```
### 2. 秒级启动
传统虚拟机启动需要几分钟引导操作系统 Docker 容器启动通常只需要**几秒甚至几百毫秒**
笔者实测数据
| 启动内容 | 虚拟机 | Docker 容器 |
|---------|--------|-------------|
| 空系统 | ~60 | ~0.5 |
| MySQL | ~90 | ~3 |
| 完整 Web 应用 | ~120 | ~5 |
这个差异对以下场景尤为重要
- **CI/CD 流水线**每次构建节省几分钟一天累积下来就是几小时
- **弹性扩容**流量高峰时能快速启动更多实例
- **开发体验**快速重启服务进行调试
### 3. 资源效率
Docker 容器共享宿主机内核无需为每个应用运行完整的操作系统
```
传统虚拟机方案:
┌────────────────────────────────────────────────┐
│ 物理服务器 (64GB 内存) │
├──────────────┬───────────────┬─────────────────┤
│ VM1 │ VM2 │ VM3 │
│ 8GB 内存 │ 8GB 内存 │ 8GB 内存 │
│ (含 OS 2GB) │ (含 OS 2GB) │ (含 OS 2GB) │
│ 应用 1 │ 应用 2 │ 应用 3 │
└──────────────┴───────────────┴─────────────────┘
实际可用于应用3 × 6GB = 18GB ❌
Docker 方案:
┌────────────────────────────────────────────────┐
│ 物理服务器 (64GB 内存) │
│ 宿主机 OS + Docker (约 4GB) │
├──────────────┬───────────────┬─────────────────┤
│ 容器 1 │ 容器 2 │ 容器 3 │
│ 应用 1 │ 应用 2 │ 应用 3 │
│ (按需分配) │ (按需分配) │ (按需分配) │
└──────────────┴───────────────┴─────────────────┘
实际可用于应用:约 60GB ✅
```
### 4. 持续交付和部署
Docker 完美契合 DevOps 的工作流程
```
代码提交 ──→ 自动构建镜像 ──→ 自动测试 ──→ 自动部署
│ │ │ │
▼ ▼ ▼ ▼
Git docker 容器内 容器滚动
push build 运行测试 更新
```
使用 [Dockerfile](../04_image/build.md) 定义镜像构建过程使得
- 构建过程**可重复可追溯**
- 任何人都能从代码重建完全相同的镜像
- 配合 [GitHub Actions](../14_cases/ci/actions/README.md) CI 系统实现自动化
### 5. 轻松迁移
Docker 可以在几乎任何平台上运行
- 本地开发机macOSWindowsLinux
- 公有云AWSAzureGCP阿里云腾讯云
- 私有云和自建数据中心
- 边缘设备和 IoT
**同一个镜像在任何地方运行结果都一致** 这让应用迁移变得前所未有的简单
### 6. 微服务架构的基石
现代微服务架构几乎都依赖容器技术Docker 让你可以
- **隔离服务**每个服务运行在独立容器中互不干扰
- **独立扩展**哪个服务负载高就单独扩展哪个
- **独立部署**更新一个服务不影响其他服务
- **技术多样**不同服务可以用不同语言和框架
```
┌───────────────────────────────────────────────────┐
│ 微服务架构示例 │
├─────────────┬─────────────┬───────────────────────┤
│ 前端容器 │ API 容器 │ Worker 容器 │
│ (Node.js) │ (Python) │ (Go) │
├─────────────┴─────────────┴───────────────────────┤
│ Redis 容器 │
├───────────────────────────────────────────────────┤
│ PostgreSQL 容器 │
└───────────────────────────────────────────────────┘
```
## Docker 不适合的场景
笔者认为技术选型要客观Docker 并非银弹以下场景可能不太适合
### 1. 需要完全隔离的场景
容器共享宿主机内核隔离性不如虚拟机如果你需要运行不受信任的代码虚拟机可能更安全
### 2. 需要特殊内核的场景
容器使用宿主机内核如果应用需要特定版本的内核或内核模块可能需要虚拟机
### 3. Windows 原生应用
虽然 Docker 支持 Windows 容器但生态不如 Linux 容器成熟传统 Windows 应用的容器化仍有挑战
### 4. 桌面应用
Docker 主要面向服务端应用桌面 GUI 应用的容器化虽然可行但通常得不偿失
## 与传统虚拟机的对比总结
| 特性 | Docker 容器 | 传统虚拟机 |
|:------|:-----------|:-----------|
| 启动速度 | 秒级 | 分钟级 |
| 磁盘占用 | MB 级别 | GB 级别 |
| 性能 | 接近原生 | 5-20% 损耗 |
| 单机支持量 | 上千个容器 | 几十个虚拟机 |
| 隔离性 | 进程级别 | 完全隔离 |
| 最佳场景 | 微服务CI/CD开发环境 | 多租户高安全需求 |
## 本章小结
Docker 的核心价值可以用一句话概括**让应用的开发测试部署保持一致同时极大提高资源利用效率**
笔者认为对于现代软件开发者来说Docker 已经不是"要不要学"的问题而是**必备技能**无论你是前端后端运维还是全栈开发者掌握 Docker 都能让你的工作更高效
接下来让我们学习 Docker [基本概念](../02_basic_concept/README.md)