Docker 完全指南 / 01 - 容器技术简介
01 - 容器技术简介
理解容器的本质、与虚拟机的区别,以及 Docker 的发展历程与行业标准。
1.1 什么是容器
容器(Container)是一种轻量级的操作系统级虚拟化技术,它将应用程序及其所有依赖项(库、配置文件、运行时环境)打包成一个标准化的单元,实现"一次构建,到处运行"。
┌─────────────────────────────────────────────────┐
│ 容器 (Container) │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ App A │ │ App B │ │ App C │ │
│ │ + 依赖 │ │ + 依赖 │ │ + 依赖 │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ ──────────── 容器运行时 (containerd/runc) ───── │
│ ──────────── 共享宿主机内核 (Linux Kernel) ───── │
└─────────────────────────────────────────────────┘
核心特征
| 特征 | 说明 |
|---|---|
| 轻量级 | 共享宿主机内核,启动时间毫秒级 |
| 隔离性 | 通过 namespace 和 cgroup 实现进程、网络、文件系统隔离 |
| 可移植性 | 镜像包含所有依赖,跨环境一致运行 |
| 不可变性 | 容器实例不可修改,变更通过重建镜像实现 |
| 分层存储 | 镜像采用分层文件系统,层与层之间可共享 |
1.2 容器 vs 虚拟机
这是理解容器技术的核心对比:
┌──────────────────────────────┬──────────────────────────────┐
│ 虚拟机 (VM) │ 容器 (Container) │
├──────────────────────────────┼──────────────────────────────┤
│ ┌──────┐ ┌──────┐ ┌──────┐ │ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │App A │ │App B │ │App C │ │ │App A │ │App B │ │App C │ │
│ ├──────┤ ├──────┤ ├──────┤ │ ├──────┤ ├──────┤ ├──────┤ │
│ │Guest │ │Guest │ │Guest │ │ │Libs │ │Libs │ │Libs │ │
│ │ OS │ │ OS │ │ OS │ │ │Bins │ │Bins │ │Bins │ │
│ └──────┘ └──────┘ └──────┘ │ └──────┘ └──────┘ └──────┘ │
│ ──────── Hypervisor ─────── │ ──────── 容器引擎 ───────── │
│ ──────── 宿主机 OS ──────── │ ──────── 宿主机内核 ─────── │
│ ──────── 硬件 ───────────── │ ──────── 硬件 ───────────── │
└──────────────────────────────┴──────────────────────────────┘
详细对比表
| 对比维度 | 虚拟机 (VM) | 容器 (Container) |
|---|---|---|
| 虚拟化级别 | 硬件级(Hardware-level) | 操作系统级(OS-level) |
| 内核 | 每个 VM 独立内核 | 共享宿主机内核 |
| 启动时间 | 分钟级 | 毫秒/秒级 |
| 资源占用 | GB 级(完整 OS) | MB 级(仅应用+依赖) |
| 隔离性 | 强(硬件隔离) | 较强(进程级隔离) |
| 性能损耗 | 5%-15% | 接近零 |
| 密度 | 单机运行十几个 | 单机运行数百个 |
| 镜像大小 | 几 GB 到几十 GB | 几 MB 到几百 MB |
| 适用场景 | 需要不同内核的场景 | 微服务、CI/CD、开发环境 |
| 典型技术 | VMware, KVM, VirtualBox | Docker, Podman, containerd |
何时选择容器 vs 虚拟机
选择容器:
✅ 微服务架构
✅ CI/CD 流水线
✅ 开发/测试环境标准化
✅ 需要快速扩缩容
✅ 应用依赖 Linux 内核功能
选择虚拟机:
✅ 需要运行不同操作系统 (Windows/Linux 混合)
✅ 强隔离安全要求 (多租户)
✅ 运行不兼容容器的遗留应用
✅ 需要自定义内核参数
混合方案:
✅ Kata Containers / gVisor (容器体验 + VM 级隔离)
1.3 容器技术的发展历程
Linux 容器技术演进
| 年份 | 里程碑 | 说明 |
|---|---|---|
| 2000 | FreeBSD Jails | 最早的容器化概念之一 |
| 2001 | Linux VServer | Linux 上的早期虚拟化方案 |
| 2006 | Google cgroups | 进程资源限制,后合入 Linux 内核 |
| 2008 | LXC (Linux Containers) | 第一个完整的 Linux 容器方案 |
| 2013 | Docker 发布 | 彻底改变了容器生态 |
| 2014 | Kubernetes | Google 开源容器编排系统 |
| 2015 | OCI 成立 | 开放容器标准组织成立 |
| 2016 | containerd | Docker 捐赠容器运行时给 CNCF |
| 2020 | Rootless Docker | 非 root 用户运行 Docker |
| 2023+ | Docker Engine 24/25 | BuildKit 默认启用,镜像加密等 |
Docker 创始人
Docker 由 Solomon Hykes 于 2013 年在 PyCon 大会上首次展示。最初是 dotCloud(PaaS 公司)的内部项目,基于 LXC 构建。后来发展出自己的容器运行时 libcontainer,最终演进为 runc。
Docker 版本演进:
0.1 (2013.3) - 基于 LXC 的第一个版本
0.9 (2014.3) - 引入 libcontainer,替代 LXC
1.0 (2014.6) - 首个正式稳定版
1.10 (2016.2) - 引入内容信任 (Content Trust)
17.03 (2017.3)- 版本号改为 YY.MM 格式
18.09 (2018.11)- BuildKit 实验性支持
19.03 (2019.7)- Rootless 模式实验性支持
20.10 (2020.12)- 默认使用 cgroup v2
23.0 (2023.2) - BuildKit 默认启用
24.0 (2023.5) - containerd 集成改进
25.0 (2024.1) - BuildKit 0.12, 镜像加密
27.0 (2024.6) - containerd 作为默认运行时
1.4 OCI 标准
OCI (Open Container Initiative) 是由 Docker、Google、CoreOS 等公司于 2015 年联合成立的开放标准组织,旨在定义容器行业的开放标准。
OCI 三大规范
| 规范 | 全称 | 说明 |
|---|---|---|
| Runtime Spec | Runtime Specification | 定义如何运行一个容器(运行时规范) |
| Image Spec | Image Specification | 定义容器镜像的格式(镜像规范) |
| Distribution Spec | Distribution Specification | 定义如何分发镜像(分发规范) |
Runtime Spec
定义容器的生命周期和配置:
容器状态流转:
creating → created → running → stopped
↓
paused → running
{
"ociVersion": "1.0.2",
"process": {
"terminal": false,
"user": { "uid": 1000, "gid": 1000 },
"args": ["nginx", "-g", "daemon off;"],
"env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin"]
},
"root": {
"path": "rootfs",
"readonly": true
},
"linux": {
"namespaces": [
{ "type": "pid" },
{ "type": "network" },
{ "type": "ipc" },
{ "type": "uts" },
{ "type": "mount" }
]
}
}
Image Spec
定义镜像的格式和层次结构:
镜像结构:
┌──────────────────────┐
│ Manifest │ ← 描述镜像的配置和层
│ (JSON 文件) │
├──────────────────────┤
│ Config │ ← 镜像配置(环境变量、CMD 等)
│ (JSON 文件) │
├──────────────────────┤
│ Layer 3 (top) │ ← 应用代码
│ Layer 2 │ ← 依赖安装
│ Layer 1 (base) │ ← 基础系统
└──────────────────────┘
Distribution Spec
定义镜像仓库的 API 标准:
镜像拉取流程:
Client Registry
│ │
│ 1. GET /v2/ │
│ ──────────────────────> │
│ │
│ 2. GET /v2/<name>/ │
│ manifest/<ref> │
│ ──────────────────────> │
│ │
│ 3. GET /v2/<name>/ │
│ blobs/<digest> │
│ ──────────────────────> │
│ │
OCI 标准的意义
OCI 标准化之前:
Docker 镜像 ←→ Docker 运行时 ←→ Docker 仓库
(供应商锁定)
OCI 标准化之后:
任意 OCI 镜像 ←→ 任意 OCI 运行时 ←→ 任意 OCI 仓库
(开放生态)
| 受益方 | 具体收益 |
|---|---|
| 用户 | 不被特定供应商锁定 |
| 运行时 | runc, crun, kata 等可互换 |
| 镜像 | Docker 镜像可在 Podman, CRI-O 等运行 |
| 仓库 | Harbor, GHCR 等可互操作 |
1.5 Docker 生态系统
核心组件
Docker 生态全景:
┌─────────────────────────────────────────────────────┐
│ 用户层 (User) │
│ Docker CLI │ Docker Desktop │ SDK/API │
├─────────────────────────────────────────────────────┤
│ Docker Engine (daemon) │
│ 镜像构建 │ 网络管理 │ 存储管理 │
├─────────────────────────────────────────────────────┤
│ containerd │
│ (高级容器运行时) │
├─────────────────────────────────────────────────────┤
│ runc │
│ (OCI 标准运行时) │
├─────────────────────────────────────────────────────┤
│ Linux Kernel │
│ namespaces │ cgroups │ seccomp │
└─────────────────────────────────────────────────────┘
Docker 产品线
| 产品 | 定位 | 说明 |
|---|---|---|
| Docker Engine | 容器运行时 | 开源,服务器端部署 |
| Docker Desktop | 桌面开发工具 | macOS/Windows/Linux GUI |
| Docker Hub | 公有镜像仓库 | 官方 + 社区镜像 |
| Docker Compose | 多容器编排 | 本地开发/测试环境 |
| Docker Scout | 镜像安全扫描 | 漏洞分析与修复建议 |
| Docker Build Cloud | 云端构建 | 远程构建加速 |
1.6 容器编排概述
当容器数量增多,需要自动化管理时,就需要容器编排(Container Orchestration):
| 编排工具 | 特点 | 适用场景 |
|---|---|---|
| Docker Compose | 单机多容器编排 | 开发、测试环境 |
| Docker Swarm | Docker 原生集群编排 | 中小规模生产环境 |
| Kubernetes (K8s) | 行业标准编排系统 | 大规模生产环境 |
| Nomad (HashiCorp) | 轻量级编排 | 混合工作负载 |
容器编排解决的问题
手动管理容器的痛点:
❌ 手动启动/停止容器
❌ 手动处理容器故障重启
❌ 手动扩缩容
❌ 手动管理网络和存储
❌ 手动滚动更新
容器编排的价值:
✅ 声明式配置 (Declarative Configuration)
✅ 自动故障恢复 (Self-healing)
✅ 自动扩缩容 (Auto-scaling)
✅ 服务发现与负载均衡 (Service Discovery & LB)
✅ 滚动更新与回滚 (Rolling Update & Rollback)
1.7 本章实操:第一个容器
运行 hello-world
# 拉取并运行 hello-world 镜像
docker run hello-world
预期输出:
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
3. The Docker daemon created a new container from that image.
...
运行交互式 Ubuntu
# 启动一个 Ubuntu 容器并进入交互式 shell
docker run -it --name my-ubuntu ubuntu:22.04 bash
# 在容器内执行命令
cat /etc/os-release
uname -a
exit
运行 Nginx Web 服务器
# 后台运行 Nginx,映射 80 端口
docker run -d --name my-nginx -p 8080:80 nginx:alpine
# 验证运行状态
docker ps
# 访问测试
curl http://localhost:8080
# 停止并删除
docker stop my-nginx
docker rm my-nginx
查看容器信息
# 查看运行中的容器
docker ps
# 查看所有容器(包括已停止的)
docker ps -a
# 查看本地镜像
docker images
要点回顾
| 要点 | 核心内容 |
|---|---|
| 容器本质 | 操作系统级虚拟化,共享宿主机内核 |
| 容器 vs VM | 容器更轻量、启动更快、资源占用更少 |
| OCI 标准 | Runtime Spec + Image Spec + Distribution Spec |
| Docker 核心 | daemon + containerd + runc |
| 编排工具 | Compose(单机)→ Swarm / K8s(集群) |
注意事项
容器不是虚拟机: 容器共享宿主机内核,安全性弱于虚拟机。在多租户环境中需要额外的安全措施。
镜像版本: 始终使用具体的镜像标签(如
ubuntu:22.04),避免使用latest,确保环境可重现。
资源限制: 容器默认不限制资源使用,生产环境中务必设置 CPU、内存限制。
下一步
→ 02 - 安装与配置:学习如何在不同操作系统上安装 Docker 并配置镜像源。