返回首页返回书籍《Docker 从入门到实践》
目录

目录 · CONTENTS

  1. 01前言
  2. 02修订记录
  3. 03如何贡献
  4. 04第一章 Docker 简介
  5. 051.1 快速上手
  6. 061.2 什么是 Docker
  7. 071.3 为什么要用 Docker
  8. 08本章小结
  9. 09第二章 基本概念
  10. 102.1 镜像
  11. 112.2 容器
  12. 122.3 仓库
  13. 13本章小结
  14. 14第三章 安装 Docker
  15. 153.1 Ubuntu
  16. 163.2 Debian
  17. 173.3 Fedora
  18. 183.4 CentOS
  19. 193.5 Raspberry Pi
  20. 203.6 Linux 离线安装
  21. 213.7 macOS
  22. 223.8 Windows 10/11
  23. 233.9 镜像加速器
  24. 243.10 开启实验特性
  25. 25本章小结
  26. 26第四章 使用镜像
  27. 274.1 获取镜像
  28. 284.2 列出镜像
  29. 294.3 删除本地镜像
  30. 304.4 利用 commit 理解镜像构成
  31. 314.5 使用 Dockerfile 定制镜像
  32. 324.6 其他制作镜像的方式
  33. 334.7 实现原理
  34. 34本章小结
  35. 35第五章 操作容器
  36. 365.1 启动
  37. 375.2 守护态运行
  38. 385.3 终止
  39. 395.4 进入容器
  40. 405.5 导出和导入
  41. 415.6 删除
  42. 42本章小结
  43. 43第六章 访问仓库
  44. 446.1 Docker Hub
  45. 456.2 私有仓库
  46. 466.3 私有仓库高级配置
  47. 476.4 Nexus 3
  48. 48本章小结
  49. 49第七章 Dockerfile 指令详解
  50. 507.1 RUN 执行命令
  51. 517.2 COPY 复制文件
  52. 527.3 ADD 更高级的复制文件
  53. 537.4 CMD 容器启动命令
  54. 547.5 ENTRYPOINT 入口点
  55. 557.6 ENV 设置环境变量
  56. 567.7 ARG 构建参数
  57. 577.8 VOLUME 定义匿名卷
  58. 587.9 EXPOSE 暴露端口
  59. 597.10 WORKDIR 指定工作目录
  60. 607.11 USER 指定当前用户
  61. 617.12 HEALTHCHECK 健康检查
  62. 627.13 ONBUILD 为他人作嫁衣裳
  63. 637.14 LABEL 为镜像添加元数据
  64. 647.15 SHELL 指令
  65. 657.16 参考文档
  66. 667.17 多阶段构建
  67. 677.18 实战多阶段构建 Laravel 镜像
  68. 68本章小结
  69. 69第八章 数据管理
  70. 708.1 数据卷
  71. 718.2 挂载主机目录
  72. 728.3 tmpfs 挂载
  73. 73本章小结
  74. 74第九章 网络配置
  75. 759.1 配置 DNS
  76. 769.2 网络类型
  77. 779.3 自定义网络
  78. 789.4 容器互联
  79. 799.5 外部访问容器
  80. 809.6 网络隔离
  81. 819.7 容器网络高级特性
  82. 82本章小结
  83. 83第十章 Docker Buildx
  84. 8410.1 BuildKit
  85. 8510.2 使用 buildx 构建镜像
  86. 8610.3 使用 buildx 构建多种系统架构支持的 Docker 镜像
  87. 87本章小结
  88. 88第十一章 Docker Compose
  89. 8911.1 简介
  90. 9011.2 安装与卸载
  91. 9111.3 使用
  92. 9211.4 命令说明
  93. 9311.5 Compose 模板文件
  94. 9411.6 实战 Django
  95. 9511.7 实战 Rails
  96. 9611.8 实战 WordPress
  97. 9711.9 实战 LNMP
  98. 98本章小结
  99. 99第十二章 底层实现
  100. 10012.1 基本架构
  101. 10112.2 命名空间
  102. 10212.3 控制组
  103. 10312.4 联合文件系统
  104. 10412.5 容器格式
  105. 10512.6 网络
  106. 106本章小结
  107. 107第十三章 容器编排基础
  108. 10813.1 简介
  109. 10913.2 基本概念
  110. 11013.3 架构设计
  111. 11113.4 高级特性
  112. 11213.5 实战练习
  113. 113本章小结
  114. 114第十四章 部署 Kubernetes
  115. 11514.1 使用 kubeadm 部署 Kubernetes
  116. 11614.2 使用 kubeadm 部署 Kubernetes:使用 Docker
  117. 11714.3 在 Docker Desktop 使用
  118. 11814.4 Kind - Kubernetes IN Docker
  119. 11914.5 K3s - 轻量级 Kubernetes
  120. 12014.6 一步步部署 Kubernetes 集群
  121. 12114.7 可视化管理界面
  122. 12214.8 Kubernetes 命令行 kubectl
  123. 123本章小结
  124. 124第十五章 Etcd 项目
  125. 12515.1 简介
  126. 12615.2 安装
  127. 12715.3 集群
  128. 12815.4 使用 etcdctl
  129. 129本章小结
  130. 130第十六章 容器与云计算
  131. 13116.1 简介
  132. 13216.2 腾讯云
  133. 13316.3 阿里云
  134. 13416.4 亚马逊云
  135. 13516.5 多云部署策略
  136. 136本章小结
  137. 137第十七章 容器其他生态
  138. 13817.1 Fedora CoreOS 简介
  139. 13917.2 Fedora CoreOS 安装
  140. 14017.3 Podman - 下一代 Linux 容器工具
  141. 14117.4 Buildah - 容器镜像构建工具
  142. 14217.5 Skopeo - 容器镜像管理工具
  143. 14317.6 containerd - 核心容器运行时
  144. 14417.7 安全容器运行时
  145. 14517.8 WebAssembly 与容器
  146. 146本章小结
  147. 147第十八章 安全
  148. 14818.1 内核命名空间
  149. 14918.2 控制组
  150. 15018.3 服务端防护
  151. 15118.4 内核能力机制
  152. 15218.5 其他安全特性
  153. 15318.6 容器镜像安全扫描与供应链安全
  154. 154本章小结
  155. 155第十九章 容器监控与日志
  156. 15619.1 Prometheus
  157. 15719.2 ELK 套件
  158. 15819.3 容器性能优化与故障诊断
  159. 159本章小结
  160. 160第二十章 实战案例 - 操作系统
  161. 16120.1 Busybox
  162. 16220.2 Alpine
  163. 16320.3 Debian Ubuntu
  164. 16420.4 CentOS Fedora
  165. 165本章小结
  166. 166第二十一章 实战案例 - DevOps
  167. 16721.1 DevOps 完整工作流
  168. 16821.2 GitHub Actions
  169. 16921.3 Drone
  170. 17021.4 Drone Demo
  171. 17121.5 在 IDE 中使用 Docker
  172. 17221.6 VS Code
  173. 17321.7 实战案例:Go/Rust/数据库/微服务
  174. 174本章小结
  175. 175附录
  176. 176附录一:常见问题与错误速查
  177. 177常见错误处理
  178. 178附录二:热门镜像介绍
  179. 179Ubuntu
  180. 180CentOS
  181. 181Nginx
  182. 182PHP
  183. 183Node.js
  184. 184MySQL
  185. 185WordPress
  186. 186MongoDB
  187. 187Redis
  188. 188Minio
  189. 189附录三:Docker 命令查询
  190. 190客户端命令 - docker
  191. 191服务端命令 - dockerd
  192. 192附录四:Dockerfile 最佳实践
  193. 193附录五:如何调试 Docker
  194. 194附录六:资源链接
  195. 195附录七:术语表
  196. 196附录八:Docker 学习路线图与知识体系
第 7 / 196 节

第 7 节 · SECTION 07

1.3 为什么要用 Docker

1.3 为什么要用 Docker

在回答 “为什么用 Docker” 之前,笔者想先问一个问题:你有没有经历过这些场景?

1.3.1 没有 Docker 的世界

在 Docker 出现之前,软件开发和运维面临着诸多棘手的问题。我们先来看看以下三个典型的痛点场景。

场景一:“在我电脑上明明能跑”

周五下午 5:00
├── 开发者:代码写完了,本地测试通过,提交!🎉
├── 周一早上 9:00
│   └── 测试:"这个功能在测试环境跑不起来"
└── 开发者:"不可能,在我电脑上明明能跑啊……"

笔者统计过,这个问题通常由以下原因导致:

  • Python/Node/Java 版本不一致
  • 依赖库版本不一致
  • 操作系统配置不一致
  • 某些环境变量没有设置
  • “哦,忘了说我本地装了个 XXX”

场景二:环境配置的噩梦

新同事入职
├── Day 1:领电脑,配环境
├── Day 2:继续配环境,遇到问题
├── Day 3:换种方法配环境
├── Day 4:问老同事怎么配的,他也忘了
└── Day 5:终于能跑起来了!但不知道为什么……

场景三:服务器迁移的恐惧

运维:"我们需要把服务迁移到新服务器"
开发:"旧服务器上的配置文档在哪?"
运维:"当时是一个已经离职的同事配的……"
所有人:😱

1.3.2 Docker 如何解决这些问题

Docker 的出现为上述问题提供了完美的解决方案。它通过 “一次构建,到处运行” 的核心理念,从根本上改变了软件交付的方式。

核心理念:一次构建,到处运行

flowchart LR
    dev["开发团队"] -->|创建| img["Docker 镜像"]
    img -->|测试团队验证| test["测试团队"]
    test -- "有问题<br/>反馈修改和更新" --> dev
    test -- "没问题<br/>发布" --> prod["生产环境"]

1.3.3 Docker 的核心优势

除了解决上述痛点,Docker 还拥有诸多显著的技术优势,包括环境一致性、秒级启动、高效的资源利用等。

1. 环境一致性

Docker 镜像包含了应用运行所需的大部分用户态依赖:代码、运行时、系统工具、库和默认配置。它不包含宿主机内核,也不能消除 CPU 架构、内核能力、外部服务、网络、卷和运行时配置差异。这意味着:

  • ✅ 开发环境和生产环境可以显著减少差异
  • ✅ 大幅降低 “在我机器上能跑” 的问题
  • ✅ 新人入职,一条命令就能启动开发环境
## 新同事入职第一天

$ 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 内存的物理服务器为例:

  • 传统虚拟机方案:每个虚拟机都需要运行完整的操作系统(每个额外占用如 2GB 内存),产生大量资源开销,实际可用于应用的内存可能只有约 18GB。
  • Docker 方案:容器直接共享宿主机系统,只需付出很少的基础开销(OS 及引擎约 4GB),即可将约 60GB 的内存全部用于实际应用。
flowchart TD
    subgraph VM ["传统虚拟机方案 ❌"]
        direction TB
        Server1["物理服务器 (64GB 内存)"]
        subgraph VMs ["可用应用内存: 约 18GB"]
            direction LR
            VM1["VM 1: 应用 1<br/>(含 2GB OS)"]
            VM2["VM 2: 应用 2<br/>(含 2GB OS)"]
            VM3["VM 3: 应用 3<br/>(含 2GB OS)"]
        end
        Server1 --- VMs
    end

    subgraph Docker ["Docker 方案 ✅"]
        direction TB
        Server2["物理服务器 (64GB 内存)<br/>含约 4GB OS及引擎配置"]
        subgraph Containers ["可用应用内存: 约 60GB"]
            direction LR
            C1["容器 1: 应用 1<br/>(按需分配)"]
            C2["容器 2: 应用 2<br/>(按需分配)"]
            C3["容器 3: 应用 3<br/>(按需分配)"]
        end
        Server2 --- Containers
    end

4. 持续交付和部署

Docker 完美契合 DevOps 的工作流程:

flowchart LR
    A["代码提交<br/>(Git push)"] --> B["自动构建镜像<br/>(docker build)"]
    B --> C["自动测试<br/>(容器内运行测试)"]
    C --> D["自动部署<br/>(容器滚动更新)"]

使用 Dockerfile 定义镜像构建过程,使得:

  • 构建过程 可重复、可追溯
  • 任何人都能从代码重建完全相同的镜像
  • 配合 GitHub Actions 等 CI 系统实现自动化

5. 轻松迁移

Docker 可以在几乎任何平台上运行:

  • ✅ 本地开发机 (macOS、Windows、Linux)
  • ✅ 公有云(AWS、Azure、GCP、阿里云、腾讯云)
  • ✅ 私有云和自建数据中心
  • ✅ 边缘设备和 IoT

同一个镜像,在任何地方运行结果都一致。 这让应用迁移变得前所未有的简单。

6. 微服务架构的基石

现代微服务架构几乎都依赖容器技术。Docker 让你可以:

  • 隔离服务:每个服务运行在独立容器中,互不干扰
  • 独立扩展:哪个服务负载高,就单独扩展哪个
  • 独立部署:更新一个服务不影响其他服务
  • 技术多样:不同服务可以用不同语言和框架
flowchart TD
    subgraph Microservices ["微服务架构示例"]
        direction TB
        subgraph AppLayer ["应用层"]
            direction LR
            Frontend["前端容器<br/>(Node.js)"]
            API["API 容器<br/>(Python)"]
            Worker["Worker 容器<br/>(Go)"]
        end
        Redis["Redis 容器"]
        DB["PostgreSQL 容器"]

        Frontend --> API
        API --> Redis
        API --> DB
        Worker --> Redis
        Worker --> DB
    end

1.3.4 Docker 不适合的场景

笔者认为,技术选型要客观。Docker 并非银弹,以下场景可能不太适合:

  • 需要完全隔离的场景:容器共享宿主机内核,隔离性不如虚拟机。如果需要运行不受信任的代码,虚拟机可能更安全。
  • 需要特殊内核的场景:容器使用宿主机内核。如果应用需要特定版本的内核或内核模块,可能需要虚拟机。
  • Windows 原生应用:虽然 Docker 支持 Windows 容器,但生态不如 Linux 容器成熟。传统 Windows 应用的容器化仍有挑战。
  • 桌面应用:Docker 主要面向服务端应用。桌面 GUI 应用的容器化虽然可行,但通常得不偿失。

1.3.5 与传统虚拟机的对比总结

关于容器与虚拟机的详细特性对比,请参阅 1.2.3 Docker vs 虚拟机 中的对比表。总结来说:

  • 性能差异:虚拟机通常有 5-20% 的性能损耗,而容器接近原生性能。
  • 最佳场景:Docker 容器适合微服务、CI/CD、开发环境;虚拟机适合多租户、高安全需求场景。