第01章:Docker 基础概念
第01章:Docker 基础概念
本章目标:理解容器技术的本质,明白 Docker 解决了什么问题,建立正确的技术认知。
1.1 从一个痛点说起
1.1.1 传统软件交付的噩梦
想象一个典型的场景:
开发人员:"在我电脑上跑得好好的啊!"
运维人员:"但在我服务器上就是跑不起来......"
这不是段子,而是无数团队每天都在经历的真实困境。导致这种"环境不一致"问题的根源在于:
| 问题 | 描述 | 后果 |
|---|---|---|
| 操作系统差异 | 开发用 macOS,测试用 CentOS,生产用 Ubuntu | 系统调用不兼容 |
| 依赖版本冲突 | 项目A需要 Python 3.8,项目B需要 Python 3.11 | 同一台机器无法共存 |
| 配置不一致 | 数据库连接串、环境变量各不相同 | 排查问题耗时耗力 |
| 部署过程不可重复 | 手动安装、手动配置,每次部署结果可能不同 | 故障率高、回滚困难 |
1.1.2 传统虚拟机能解决问题吗?
虚拟机(VM)确实提供了一种解决方案:
┌─────────────────────────────────────────┐
│ 物理服务器 │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ 虚拟机 A │ │ 虚拟机 B │ │
│ │ ┌──────────┐ │ │ ┌──────────┐ │ │
│ │ │ App A │ │ │ │ App B │ │ │
│ │ ├──────────┤ │ │ ├──────────┤ │ │
│ │ │ Libs/依赖 │ │ │ │ Libs/依赖 │ │ │
│ │ ├──────────┤ │ │ ├──────────┤ │ │
│ │ │ Guest OS │ │ │ │ Guest OS │ │ │
│ │ └──────────┘ │ │ └──────────┘ │ │
│ └──────────────┘ └──────────────┘ │
│ ┌──────────────────────────────────┐ │
│ │ Hypervisor │ │
│ └──────────────────────────────────┘ │
│ ┌──────────────────────────────────┐ │
│ │ Host OS │ │
│ └──────────────────────────────────┘ │
└─────────────────────────────────────────┘
但虚拟机有明显的缺点:
| 对比维度 | 虚拟机 | 容器 |
|---|---|---|
| 启动速度 | 分钟级(需要启动完整OS) | 秒级(共享宿主机内核) |
| 资源占用 | GB 级(每个VM都有完整OS) | MB 级(仅包含应用和依赖) |
| 运行密度 | 一台服务器跑十几个 | 一台服务器跑数百个 |
| 镜像大小 | 通常 1GB+ | 通常 10MB~200MB |
| 隔离级别 | 硬件级(Hypervisor) | 进程级(内核隔离) |
| 可移植性 | 需要适配虚拟化平台 | 标准化,跨平台运行 |
1.2 什么是容器(Container)
1.2.1 容器的本质
容器 = 被隔离的进程
容器不是虚拟机,它不像虚拟机那样拥有独立的操作系统内核。容器的本质是利用 Linux 内核的隔离机制,将一个进程及其依赖资源(文件系统、网络、进程空间等)打包在一起,使其看起来像在一台独立的机器上运行。
┌─────────────────────────────────────────────┐
│ 物理服务器 │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ 容器 A │ │ 容器 B │ │
│ │ ┌──────────┐ │ │ ┌──────────┐ │ │
│ │ │ App A │ │ │ │ App B │ │ │
│ │ ├──────────┤ │ │ ├──────────┤ │ │
│ │ │ Libs/依赖 │ │ │ │ Libs/依赖 │ │ │
│ │ └──────────┘ │ │ └──────────┘ │ │
│ └──────────────┘ └──────────────┘ │
│ ┌────────────────────────────────────────┐ │
│ │ 容器运行时 (Docker Engine) │ │
│ └────────────────────────────────────────┘ │
│ ┌────────────────────────────────────────┐ │
│ │ Host OS(共享内核) │ │
│ └────────────────────────────────────────┘ │
│ ┌────────────────────────────────────────┐ │
│ │ 硬件 │ │
│ └────────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
1.2.2 容器技术的核心支柱
容器技术建立在三大 Linux 内核特性之上:
① Namespace(命名空间)—— 资源隔离
Namespace 让每个容器拥有自己独立的"视界",看起来就像独占了一台机器:
| Namespace | 功能 | 解决的问题 |
|---|---|---|
| PID | 进程 ID 隔离 | 容器内 PID 从1开始,看不到宿主机进程 |
| NET | 网络隔离 | 每个容器有独立的网络栈(IP、端口、路由表) |
| MNT | 文件系统挂载隔离 | 每个容器有独立的文件系统视图 |
| UTS | 主机名隔离 | 每个容器可以有自己的主机名 |
| USER | 用户隔离 | 容器内可以有不同的用户映射 |
| IPC | 进程间通信隔离 | 容器之间的信号量、消息队列等隔离 |
② Cgroups(控制组)—— 资源限制
Cgroups 限制每个容器可以使用的资源量,防止某个容器"吃光"所有资源:
物理机:16核 CPU / 32GB 内存
Cgroups 分配:
├── 容器 A:最多 4核 CPU / 8GB 内存
├── 容器 B:最多 4核 CPU / 8GB 内存
└── 容器 C:最多 4核 CPU / 8GB 内存
(剩余资源留给宿主机和其他容器)
支持限制的资源类型:
- CPU:可以使用多少核、使用时间片比例
- 内存:最大使用量、OOM 阈值
- 磁盘 I/O:读写速率限制
- 网络带宽:上传下载速率限制
③ UnionFS(联合文件系统)—— 分层存储
UnionFS 是容器镜像的基石,它允许将多个目录"叠加"在一起,形成一个统一的视图:
最终文件系统视图(可读写层)
┌────────────────────────────┐
│ Container Layer (R/W) │ ← 运行时产生的变更
├────────────────────────────┤
│ App Layer (R/O) │ ← 应用代码和依赖
├────────────────────────────┤
│ Dependency Layer (R/O) │ ← 运行时库
├────────────────────────────┤
│ Base Image Layer (R/O) │ ← 基础镜像(如 Ubuntu)
└────────────────────────────┘
关键特性:
- 镜像的每一层都是只读的,被多个容器共享
- 容器运行时在最上面添加一个可写层
- 容器删除后,可写层也随之删除,镜像层不受影响
- 层与层之间通过内容哈希去重,节省存储空间
1.3 Docker 是什么
1.3.1 Docker 的定义
Docker 是一个开源的应用容器引擎,让开发者可以打包应用及其依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 或 Windows 操作系统上。
简单说,Docker 就是容器技术的产品化实现。它把底层复杂的 Linux 内核隔离技术封装成了简单易用的命令行工具和 API。
1.3.2 Docker 的三大核心概念
┌──────────────────────────────────────────────┐
│ Docker 核心概念 │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 镜像 │ │ 容器 │ │ 仓库 │ │
│ │ Image │ │ Container │ │ Registry │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ 只读模板 运行实例 存储分发 │
│ (类比:类) (类比:对象) (类比:包管理) │
└──────────────────────────────────────────────┘
镜像(Image)
- 一个只读的模板,包含了运行应用所需的一切:代码、运行时、库、环境变量、配置文件
- 类比理解:如果把镜像比作一个 Java 类,那么它就是一份静态的定义
容器(Container)
- 镜像的一个运行实例,拥有独立的文件系统、网络和进程空间
- 类比理解:容器就是类创建出来的 对象实例,可以被创建、启动、停止、删除
- 容器是可以被修改的(在可写层中)
仓库(Registry)
- 用于存储和分发镜像的服务(如 Docker Hub、Harbor)
- 类比理解:就像 Maven 中央仓库 或 npm registry,是镜像的"应用商店"
1.3.3 Docker 的发展历史
| 时间 | 里程碑 | 意义 |
|---|---|---|
| 2013 | dotCloud 开源 Docker | 容器技术进入大众视野 |
| 2014 | Docker 1.0 发布 | 生产环境可用 |
| 2015 | OCI(开放容器标准)成立 | 容器技术标准化 |
| 2016 | Docker Swarm 内置 | 容器编排能力 |
| 2017 | Kubernetes 成为主流 | 容器编排大战尘埃落定 |
| 2019 | Docker Enterprise 被 Mirantis 收购 | Docker 公司转型 |
| 2020+ | Docker Desktop 成为主要产品 | 聚焦开发者体验 |
| 2023+ | Docker Init、Docker Debug、Docker Scout | 开发者平台全面升级 |
1.4 Docker vs 虚拟机:深度对比
1.4.1 架构对比
虚拟机架构: 容器架构:
┌─────────────────┐ ┌─────────────────┐
│ App A App B │ │ App A App B │
├─────────────────┤ ├─────────────────┤
│ Bins/Libs A/B │ │ Bins/Libs A/B │
├─────────────────┤ ├─────────────────┤
│ Guest OS A B │ │ Docker Engine │
├─────────────────┤ ├─────────────────┤
│ Hypervisor │ │ Host OS │
├─────────────────┤ ├─────────────────┤
│ Host OS │ │ 硬件/硬件虚拟化 │
├─────────────────┤ └─────────────────┘
│ 硬件 │
└─────────────────┘
1.4.2 全维度对比
| 对比维度 | Docker 容器 | 虚拟机(VM) |
|---|---|---|
| 虚拟化级别 | 操作系统级(共享内核) | 硬件级(独立内核) |
| 操作系统 | 共享宿主机内核 | 每个 VM 独立 OS |
| 启动时间 | 毫秒~秒级 | 分钟级 |
| 资源占用 | 极低(MB 级) | 较高(GB 级) |
| 运行密度 | 单机可运行数百个 | 单机通常数十个 |
| 镜像大小 | 通常 10~200MB | 通常 1~10GB |
| 隔离性 | 进程级隔离 | 强隔离(硬件虚拟化) |
| 安全性 | 共享内核,攻击面较大 | 独立内核,隔离性更强 |
| 可移植性 | 极强(标准化) | 依赖虚拟化平台 |
| 性能损耗 | 接近原生(<2%) | 5%~20% 损耗 |
| 适用场景 | 微服务、CI/CD、开发测试 | 强隔离需求、运行不同OS |
1.4.3 什么时候选容器,什么时候选 VM?
需要运行不同内核的操作系统?
├── 是 → 选虚拟机(如需要运行 Windows + Linux)
└── 否 → 需要强隔离(多租户、不可信代码)?
├── 是 → 选虚拟机(如公有云租户隔离)
└── 否 → 需要快速启动和高密度部署?
├── 是 → 选容器 ✓
└── 否 → 都可以,看团队技术栈
实际生产中的最佳实践:虚拟机 + 容器混合使用
┌────────────────────────────────────┐
│ 物理服务器 │
│ ┌──────────────┬──────────────┐ │
│ │ 虚拟机 A │ 虚拟机 B │ │
│ │ ┌────────┐ │ ┌────────┐ │ │
│ │ │容器 1 2│ │ │容器 3 4│ │ │
│ │ └────────┘ │ └────────┘ │ │
│ └──────────────┴──────────────┘ │
│ ┌──────────────────────────────┐ │
│ │ Hypervisor │ │
│ └──────────────────────────────┘ │
│ ┌──────────────────────────────┐ │
│ │ Host OS │ │
│ └──────────────────────────────┘ │
└────────────────────────────────────┘
场景:公有云环境
- 虚拟机提供租户间的强隔离
- 每个虚拟机内部使用容器部署微服务
1.5 Docker 的核心价值
1.5.1 对开发团队的价值
| 价值 | 说明 |
|---|---|
| 环境一致性 | 开发、测试、生产环境完全一致,告别"在我电脑上能跑" |
| 快速上手 | 新成员 docker-compose up 一键拉起整个开发环境 |
| 多项目并行 | 不同项目的依赖互不干扰,轻松切换 |
| 可复现的 Bug | 容器可以精确复制问题环境 |
1.5.2 对运维团队的价值
| 价值 | 说明 |
|---|---|
| 标准化部署 | 所有应用使用相同的部署流程 |
| 秒级伸缩 | 容器的秒级启动让弹性伸缩成为可能 |
| 资源利用率 | 同一台服务器运行更多应用实例 |
| 灰度发布 | 轻松实现蓝绿部署、金丝雀发布 |
| 故障恢复 | 容器故障后秒级重启,无需重新配置环境 |
1.5.3 对企业架构的价值
| 价值 | 说明 |
|---|---|
| 微服务架构落地 | 每个微服务独立容器化部署 |
| DevOps 文化 | 统一构建和运行环境,打破开发运维壁垒 |
| 云原生基础 | 容器是 Kubernetes、Service Mesh 等云原生技术的基石 |
| 多云策略 | 容器可以在任意云平台运行,避免厂商锁定 |
1.6 动手实验:你的第一个容器
实验 1.1:运行 Hello World
# 运行 Docker 的 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 Docker Hub.
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
这段输出揭示了 Docker 的工作流程:
- 客户端(docker 命令)→ 2. 守护进程(dockerd)→ 3. 拉取镜像 → 4. 创建容器 → 5. 执行并返回结果
实验 1.2:运行一个 Ubuntu 容器
# 启动一个 Ubuntu 容器并进入交互式终端
docker run -it ubuntu:22.04 /bin/bash
进入容器后你可以:
# 查看容器内的系统信息
cat /etc/os-release
# 查看容器内的进程(只有你自己的进程!)
ps aux
# 查看容器内的磁盘
df -h
# 退出容器
exit
你会发现:虽然你的宿主机可能运行的是 Windows,但容器内却是一个完整的 Ubuntu 系统!
实验 1.3:运行一个 Nginx Web 服务器
# 后台运行 Nginx
docker run -d -p 8080:80 nginx:latest
# 查看运行中的容器
docker ps
# 打开浏览器访问 http://localhost:8080
# 你应该能看到 Nginx 的欢迎页面
# 停止容器
docker stop <容器ID>
# 清理已停止的容器
docker rm <容器ID>
1.7 本章小结
| 要点 | 内容 |
|---|---|
| 容器的本质 | 利用 Linux 内核特性实现的轻量级进程隔离 |
| Docker 的定位 | 容器技术的产品化实现,降低了使用门槛 |
| 三大核心概念 | 镜像(模板)、容器(实例)、仓库(分发) |
| 三大技术支柱 | Namespace(隔离)、Cgroups(限制)、UnionFS(分层存储) |
| 核心价值 | 环境一致性、快速部署、高效利用资源、标准化交付 |
1.8 课后练习
- 思考题:为什么容器比虚拟机启动更快?从架构角度分析原因。
- 实操题:分别用
docker run启动一个 Ubuntu 和 CentOS 容器,进入容器查看操作系统信息,体会容器的"隔离性"。 - 扩展阅读:了解 Linux Namespace 和 Cgroups 的系统调用接口。
📖 下一章:Docker 架构原理 —— 深入理解 Docker 的内部工作机制
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)