1.docker与容器介绍
Docker 学习笔记 (一):容器化革命与架构原理
1. 为什么要使用容器?(Why Containers?)
1.1 传统应用部署的痛点
在容器技术普及之前,部署一个应用程序(比如 Node.js 应用)往往是一场“噩梦”。我们需要在服务器上:
- 安装 Node.js 及其特定的依赖版本。
- 安装应用程序本身的依赖库。
- 配置运行环境,最后启动应用。
但这带来了巨大的复杂性:
- 环境地狱:如果服务器上还要运行 Python、Java、Go 等其他语言的应用怎么办?
- 版本冲突:如果应用 A 需要 Node.js v14,而应用 B 需要 Node.js v18,如何让它们在同一台机器上和谐共存?
- “Devs vs Ops” 的经典推诿:
- 开发人员 (Devs) 写好了代码和部署脚本。
- 运维人员 (Ops) 在服务器上运行脚本 —— 报错了!
- Devs:“但在我的机器上是好的啊!”
- Ops:“那是你的机器,服务器环境不一样。”
- …经历无数次调整脚本、安装依赖、调试后,应用终于上线了。
1.2 容器带来的救赎
Docker 容器的出现改变了这一切。
核心理念:容器将应用程序及其所有的依赖项和配置打包在一起。从外部看,所有的容器看起来都一样,运行方式也几乎相同。
由此带来的好处:
- 简化设置:不再需要繁琐的手动环境配置。
- 可移植性 (Portability):在开发笔记本上能跑,就能在测试服、生产环境云服务器上跑,“一次构建,到处运行”。
- 环境一致性:消除了“在我的机器上没问题”这类借口。
- 隔离性:不同应用之间互不干扰。
- 更高效的资源利用:相比虚拟机更轻量。
新的协作模式:
- Devs 编写
Dockerfile,定义环境和依赖。 - Devs 构建并推送镜像 (Image)。
- Ops 只需要拿到镜像并部署,无需关心内部细节。
2. 容器与虚拟机 (Containers vs Virtual Machines)
这是面试和理解容器技术时最常见的问题:Docker 容器和 VMware/VirtualBox 这种虚拟机有什么区别?
2.1 架构对比
虚拟化 (Virtualization) - “独栋别墅”
- 结构:硬件基础设施 -> 宿主机系统 (Host OS) -> Hypervisor -> 客户机系统 (Guest OS) -> 依赖/代码。
- 特点:每个虚拟机 (VM) 都有自己完整的操作系统(Guest OS)。
- 比喻:就像一排独栋别墅,每一栋都有自己的地基、墙壁、水电设施,相互完全独立,但占地面积大,建设成本高。
容器化 (Containerization) - “现代化公寓”
- 结构:硬件基础设施 -> 宿主机系统 (Host OS) -> 容器引擎 (Container Engine) -> 容器 (代码/依赖)。
- 特点:所有容器共享宿主机的操作系统内核 (Kernel),没有 Guest OS 这一层。
- 比喻:就像一栋公寓大楼,大家共享地基和基础设施(内核),但每个房间(容器)内部是独立的。这使得它非常轻量和高效。

2.2 核心特性 PK
| 特性 | 虚拟机 (VMs) | Docker 容器 |
|---|---|---|
| 隔离性 | 强隔离:每个 VM 有独立的 OS,隔离彻底,安全性极高。 | 进程级隔离:共享宿主机内核,通过 Namespace/Cgroup 实现隔离。 |
| 大小/开销 | 庞大:包含完整 OS,镜像通常是 GB 级别。启动慢。 | 轻量:仅包含应用和必要库,镜像通常是 MB 级别。秒级启动。 |
| 可移植性 | 较弱:往往绑定特定的 Hypervisor 或 OS 配置。 | 极佳:平台无关,只要有 Docker 引擎就能跑。 |
2.3 该怎么选?
- 选择虚拟机 (VM) 当:
- 你需要极强的环境隔离(例如运行不同租户的敏感工作负载)。
- 你需要运行完全不同的操作系统(如在 Linux 上跑 Windows)。
- 你需要处理难以容器化的传统遗留应用。
- 选择容器 (Docker) 当:
- 你正在构建现代的、云原生的微服务架构。
- 你需要快速扩缩容,追求极致的启动速度。
- 你需要跨环境(开发、测试、生产)的高度一致性。
3. Docker 架构组件 (Docker Components)
Docker 采用的是客户端-服务器 (C/S) 架构。理解这部分有助于排查连接问题。
3.1 三大核心组件
Docker Client (客户端)
- 这是用户与 Docker 交互的入口,也就是我们常用的 CLI (命令行界面),例如执行
docker build,docker run。 - 客户端通过 API 与 Docker Host 通信。
- 这是用户与 Docker 交互的入口,也就是我们常用的 CLI (命令行界面),例如执行
Docker Host (主机)
- 这是 Docker 实际干活的地方。
- Docker Daemon:后台守护进程,负责监听 API 请求,管理 Docker 对象(镜像、容器、网络、卷)。
- REST API:客户端和守护进程之间的通信桥梁。
- Images Cache:本地的镜像仓库。
- Containers:正在运行的容器实例。
Image Registry (镜像仓库)
- 存储镜像的地方。
- Docker Hub 是默认的公共仓库,也有企业私有的 Registry。

4. 深入理解 Docker 工作流 (Lifecycle)
让我们通过两个最常用的命令,看看 Docker 内部发生了什么。
场景一:运行一个容器 (docker run)
当你输入 docker run <image> 时:
- 指令发出:你在 CLI 输入命令。
- 发送请求:CLI 将指令转换为 API 请求,发送给 Docker Host 的 REST API。
- 检查本地缓存:Docker Host 首先检查本地 (Local Cache) 是否已经有这个镜像?
- 拉取镜像 (Pull):
- 如果有:直接使用。
- 如果没有:Host 会连接 Image Registry,下载(Pull)该镜像到本地。
- 实例化:Docker Host 根据镜像创建一个新的容器实例并启动它。
场景二:构建并发布镜像 (docker build & docker push)
当你开发完代码,需要打包发布时:
- 构建指令:你输入
docker build命令。 - 发送上下文:CLI 将请求发送给 Host,同时会把当前的“构建上下文” (Context,通常是当前目录下的文件) 和
Dockerfile发送给 Docker Daemon。 - 执行构建:Docker Host 按照
Dockerfile的指令,一步步构建出镜像。 - 保存镜像:构建好的镜像会被打上标签 (Tag) 并存储在本地缓存中。
- 推送指令:你输入
docker push。 - 上传:Docker Host 将本地的镜像上传到远端的 Image Registry,供其他人下载使用。