mirror of
https://github.com/yeasy/docker_practice.git
synced 2026-03-10 11:54:37 +00:00
Add more content
This commit is contained in:
@@ -1,40 +1,208 @@
|
||||
# 为什么要使用 Docker?
|
||||
|
||||
作为一种新兴的虚拟化方式,`Docker` 跟传统的虚拟化方式相比具有众多的优势。
|
||||
在回答"为什么用 Docker"之前,笔者想先问一个问题:**你有没有经历过这些场景?**
|
||||
|
||||
## 更高效的利用系统资源
|
||||
## 没有 Docker 的世界
|
||||
|
||||
由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,`Docker` 对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。
|
||||
### 场景一:"在我电脑上明明能跑"
|
||||
|
||||
## 更快速的启动时间
|
||||
```
|
||||
周五下午 5:00
|
||||
├── 开发者:代码写完了,本地测试通过,提交!🎉
|
||||
├── 周一早上 9:00
|
||||
│ └── 测试:"这个功能在测试环境跑不起来"
|
||||
└── 开发者:" 不可能,在我电脑上明明能跑啊……"
|
||||
```
|
||||
|
||||
传统的虚拟机技术启动应用服务往往需要数分钟,而 `Docker` 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。
|
||||
笔者统计过,这个问题通常由以下原因导致:
|
||||
- Python/Node/Java 版本不一致
|
||||
- 依赖库版本不一致
|
||||
- 操作系统配置不一致
|
||||
- 某些环境变量没有设置
|
||||
- "哦,忘了说我本地装了个 XXX"
|
||||
|
||||
## 一致的运行环境
|
||||
### 场景二:环境配置的噩梦
|
||||
|
||||
开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。而 `Docker` 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 *「这段代码在我机器上没问题啊」* 这类问题。
|
||||
```
|
||||
新同事入职
|
||||
├── Day 1:领电脑,配环境
|
||||
├── Day 2:继续配环境,遇到问题
|
||||
├── Day 3:换种方法配环境
|
||||
├── Day 4:问老同事怎么配的,他也忘了
|
||||
└── Day 5:终于能跑起来了!但不知道为什么……
|
||||
```
|
||||
|
||||
## 持续交付和部署
|
||||
### 场景三:服务器迁移的恐惧
|
||||
|
||||
对开发和运维([DevOps](https://zh.wikipedia.org/wiki/DevOps))人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。
|
||||
```
|
||||
运维:"我们需要把服务迁移到新服务器"
|
||||
开发:"旧服务器上的配置文档在哪?"
|
||||
运维:"当时是一个已经离职的同事配的……"
|
||||
所有人:😱
|
||||
```
|
||||
|
||||
使用 `Docker` 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 [Dockerfile](../image/dockerfile/) 来进行镜像构建,并结合 [持续集成(Continuous Integration)](https://en.wikipedia.org/wiki/Continuous_integration) 系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合 [持续部署(Continuous Delivery/Deployment)](https://en.wikipedia.org/wiki/Continuous_delivery) 系统进行自动部署。
|
||||
## Docker 如何解决这些问题
|
||||
|
||||
而且使用 [`Dockerfile`](../image/build.md) 使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。
|
||||
### 核心理念:一次构建,到处运行
|
||||
|
||||
## 更轻松的迁移
|
||||
```
|
||||
开发环境 测试环境 生产环境
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌─────────┐ ┌─────────┐ ┌─────────┐
|
||||
│ Docker │ = │ Docker │ = │ Docker │
|
||||
│ 镜像 │ │ 镜像 │ │ 镜像 │
|
||||
└─────────┘ └─────────┘ └─────────┘
|
||||
↓ ↓ ↓
|
||||
完全一致 完全一致 完全一致
|
||||
```
|
||||
|
||||
由于 `Docker` 确保了执行环境的一致性,使得应用的迁移更加容易。`Docker` 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。
|
||||
## Docker 的核心优势
|
||||
|
||||
## 更轻松的维护和扩展
|
||||
### 1. 环境一致性
|
||||
|
||||
`Docker` 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,`Docker` 团队同各个开源项目团队一起维护了一大批高质量的 [官方镜像](https://hub.docker.com/search/?type=image&image_filter=official),既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。
|
||||
Docker 镜像包含了应用运行所需的**一切**:代码、运行时、系统工具、库、配置。这意味着:
|
||||
|
||||
## 对比传统虚拟机总结
|
||||
- ✅ 开发环境和生产环境完全一致
|
||||
- ✅ 不会再有"在我机器上能跑"的问题
|
||||
- ✅ 新人入职,一条命令就能启动开发环境
|
||||
|
||||
| 特性 | 容器 | 虚拟机 |
|
||||
| :-------- | :-------- | :---------- |
|
||||
| 启动 | 秒级 | 分钟级 |
|
||||
| 硬盘使用 | 一般为 `MB` | 一般为 `GB` |
|
||||
| 性能 | 接近原生 | 弱于 |
|
||||
| 系统支持量 | 单机支持上千个容器 | 一般几十个 |
|
||||
```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](../image/build.md) 定义镜像构建过程,使得:
|
||||
- 构建过程**可重复、可追溯**
|
||||
- 任何人都能从代码重建完全相同的镜像
|
||||
- 配合 [GitHub Actions](../cases/ci/actions/README.md) 等 CI 系统实现自动化
|
||||
|
||||
### 5. 轻松迁移
|
||||
|
||||
Docker 可以在几乎任何平台上运行:
|
||||
- ✅ 本地开发机(macOS、Windows、Linux)
|
||||
- ✅ 公有云(AWS、Azure、GCP、阿里云、腾讯云)
|
||||
- ✅ 私有云和自建数据中心
|
||||
- ✅ 边缘设备和 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 的[基本概念](../basic_concept/README.md)。
|
||||
|
||||
Reference in New Issue
Block a user