第1章:容器和Docker简介(Introduction to Containers and Docker)
一、导读
1.1 本章学习目标
本章是容器技术的入门导论。从虚拟化技术的演进讲起,你将理解容器为何成为现代软件交付的标准方式。本章介绍容器的核心优势、Docker 的历史贡献、以及容器的 Linux 内核基础。
本章的核心学习目标包括:
- 理解虚拟化技术的演进:从物理机到虚拟机再到容器的演进路径。
- 掌握容器 vs 虚拟机的本质区别:共享内核 vs 独立内核。
- 了解 Docker 的历史和贡献:Docker 如何民主化了容器技术。
- 理解容器的 Linux 内核基础:Namespace、Cgroups、UnionFS。
- 掌握 Docker 的基本操作:安装、运行、管理容器。
- 了解容器生态系统:Docker、containerd、CRI-O、OCI。
1.2 为什么本章如此重要
容器是 Kubernetes、微服务、云原生等现代技术的基石。不理解容器,就无法理解这些上层技术。本章建立的容器基础认知,将贯穿整本书的学习。
更重要的是,容器不仅仅是一项技术,更是一种软件交付的范式转变。它改变了我们构建、分发、运行软件的方式。理解这种范式转变,才能充分利用容器的价值。
1.3 核心问题引导
容器和虚拟机的根本区别是什么?为什么容器比虚拟机更轻量?
Docker 之前就有容器技术(LXC),为什么 Docker 能改变世界?
什么是 Namespace?它如何隔离进程、网络、文件系统?
什么是 Cgroups?它如何限制容器的 CPU 和内存?
什么是 UnionFS?它如何让镜像分层存储?
二、核心概念详解
2.1 虚拟化技术的演进
2.1.1 物理机时代
一台物理服务器运行一个应用。问题:
- 资源利用率低(通常 10-15%)
- 部署慢(数天到数周)
- 运维成本高
2.1.2 虚拟机时代
Hypervisor(VMware、KVM、Xen)在一台物理机上运行多个虚拟机。每个 VM 有独立的操作系统。
优势:
- 资源利用率提升(60-80%)
- 隔离性好(独立内核)
- 快速部署(分钟级)
问题:
- 每个 VM 需要完整的 OS,资源浪费
- 启动慢(数十秒到分钟)
- 密度有限(单机数十个 VM)
2.1.3 容器时代
容器共享宿主机内核,只隔离应用运行环境。
优势:
- 秒级启动
- MB 级镜像
- 单机数百个容器
- 接近原生的性能
2.2 容器 vs 虚拟机
| 特性 | 容器 | 虚拟机 |
|---|---|---|
| 抽象级别 | OS 级别(共享内核) | 硬件级别(独立内核) |
| 启动速度 | < 1秒 | 数十秒到分钟 |
| 镜像大小 | 几十 MB | 几 GB |
| 性能损耗 | 接近原生 | 5-20% |
| 密度 | 单机数百个 | 单机数十个 |
| 隔离性 | 进程级(较弱) | 硬件级(较强) |
# 容器架构
┌─────────┐ ┌─────────┐ ┌─────────┐
│ App A │ │ App B │ │ App C │
├─────────┤ ├─────────┤ ├─────────┤
│ Bins/ │ │ Bins/ │ │ Bins/ │
│ Libs │ │ Libs │ │ Libs │
├─────────┴─┴─────────┴─┴─────────┤
│ Docker Engine │
├─────────────────────────────────┤
│ Host OS │
├─────────────────────────────────┤
│ Hardware │
└─────────────────────────────────┘
# 虚拟机架构
┌─────────┐ ┌─────────┐ ┌─────────┐
│ App A │ │ App B │ │ App C │
├─────────┤ ├─────────┤ ├─────────┤
│ Bins/ │ │ Bins/ │ │ Bins/ │
│ Libs │ │ Libs │ │ Libs │
├─────────┤ ├─────────┤ ├─────────┤
│ Guest OS│ │ Guest OS│ │ Guest OS│
├─────────┴─┴─────────┴─┴─────────┤
│ Hypervisor │
├─────────────────────────────────┤
│ Hardware │
└─────────────────────────────────┘2.3 Docker 的历史
2013 年,PaaS 公司 dotCloud 内部开发了一个工具,用于简化应用的打包和部署。这个工具就是 Docker。Docker 的贡献在于:
- 简化了容器操作:提供友好的 CLI 和 API
- 引入了镜像构建:Dockerfile 让镜像构建可重复
- 建立了镜像生态:Docker Hub 让镜像分发变得简单
- 推动了标准化:推动了 OCI 标准的建立
2.4 容器的 Linux 内核基础
2.4.1 Namespace(隔离)
Namespace 让容器觉得自己独占系统:
| Namespace | 隔离内容 |
|---|---|
| PID | 进程 ID |
| Network | 网络栈 |
| Mount | 文件系统 |
| User | 用户 ID |
| IPC | 进程间通信 |
| UTS | 主机名 |
# 在新的 PID + Mount Namespace 中运行
unshare --pid --fork --mount-proc bash
echo $$ # 输出: 12.4.2 Cgroups(资源限制)
Cgroups 限制容器能使用的资源:
# 限制 CPU 和内存
docker run --cpus=1.5 --memory=512m myapp2.4.3 UnionFS(分层文件系统)
UnionFS 将多个目录联合挂载。Docker 使用 overlay2 驱动实现镜像分层。
2.5 Docker 架构
Docker CLI → Docker Daemon (dockerd) → containerd → runc → Linux Kernel- Docker CLI:用户接口
- Docker Daemon:管理 Docker 对象
- containerd:容器生命周期管理
- runc:创建和运行容器
- Linux Kernel:Namespace + Cgroups + UnionFS
三、实战案例
3.1 安装 Docker
# Ubuntu
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
# 验证
docker version
docker info3.2 运行第一个容器
# 运行 hello-world
docker run hello-world
# 运行 Nginx
docker run -d -p 8080:80 --name web nginx
curl http://localhost:8080
# 查看运行中的容器
docker ps
# 查看容器日志
docker logs web
# 进入容器
docker exec -it web /bin/bash
# 停止和删除
docker stop web
docker rm web3.3 容器资源观察
# 实时查看容器资源使用
docker stats
# 查看容器详细信息
docker inspect web
# 查看容器进程
docker top web四、本章小结
容器共享内核,比虚拟机更轻量、启动更快、密度更高。
Docker 民主化了容器技术,提供了友好的工具和镜像生态。
Namespace 提供隔离,Cgroups 提供资源限制,UnionFS 提供分层存储。
Docker 架构:CLI → Daemon → containerd → runc → Kernel。
五、思考与练习
思考题
为什么容器的隔离性不如虚拟机?在什么场景下这可能成为问题?
Docker 之前就有 LXC,为什么 Docker 更成功?
如果两个容器共享内核,一个容器的内核漏洞会影响其他容器吗?
为什么容器启动只需不到1秒,而虚拟机需要数十秒?
练习题
安装 Docker,运行 hello-world 和 nginx 容器。
使用 docker stats 观察容器的资源占用。
对比启动容器和启动虚拟机的时间差异。
使用 unshare 命令手动创建 Namespace,观察隔离效果。