Docker 核心概念
Docker = 利用 Linux 内核能力(Namespace + cgroups + UnionFS), 把应用进程“隔离、限制、打包、分发、运行”的一整套工程体系。
⚠️ Docker 不是虚拟机
⚠️ 容器不是 OS
⚠️ Docker 本质是 进程管理 + 文件系统抽象
- 开发 / 测试 / 生产环境不一致
- “在我机器上是好的”
Docker 用 镜像 固化环境。
- 手动装环境
- 配置不可追溯
Docker 用 Dockerfile -> Image -> Container 标准化流程。
- 虚拟机浪费资源
- 启动慢
Docker 直接跑在宿主机内核上,进程级虚拟化。
Namespace 解决的是:“容器里的进程,为什么以为自己是独占系统?”
Linux Namespace 让一个进程看到的是“假的世界”。
| Namespace | 作用 |
|---|---|
| PID | 进程号隔离 |
| NET | 网络隔离 |
| MNT | 挂载点隔离 |
| IPC | 进程通信隔离 |
| UTS | 主机名隔离 |
| USER | 用户隔离 |
📌 结果:
-
容器里 ps 看不到宿主机进程
-
容器有自己的 IP
-
容器有自己的 hostname
-
👉 隔离 ≠ 虚拟化
-
👉 仍然是宿主机内核
cgroups 解决的是:“容器不能把宿主机拖死”
限制内容:
- CPU(配额 / 权重)
- 内存(最大值)
- IO
- PID 数量
例:
docker run --memory=512m --cpus=1 nginx
📌 没有 cgroups,容器只是“裸进程”。
解决:“镜像如何复用?为什么那么小?”
镜像是多层叠加的只读层:
Layer 1: ubuntu
Layer 2: apt install python
Layer 3: copy app
容器启动后:
RW Layer (container)
RO Layers (image)
📌 写时复制(Copy-On-Write)
定义:
- 只读
- 不可变
- 分层
📌 镜像 = rootfs + metadata
定义:
- 镜像的运行实例
- 本质是一个 Linux 进程
- 有自己的 Namespace + cgroups + FS
⚠️ 容器应当是:
- 短生命周期
- 可随时销毁
- 无状态
作用:
- 描述“如何构建镜像”
- 每条指令 -> 一个镜像层
📌 Dockerfile 是 声明式构建描述,不是脚本。
作用:
- 镜像的分发系统
- 支持 tag / digest / manifest
Docker 运行流程
docker run nginx
↓
Docker CLI
↓
dockerd
↓
containerd
↓
runc
↓
Linux Kernel
📌 Docker 不是直接启动容器。
| 组件 | 职责 |
|---|---|
| docker CLI | 用户接口 |
| dockerd | 容器生命周期管理 |
| containerd | 容器运行管理 |
| runc | 真正调用内核创建容器 |
| OCI | 标准 |
默认 bridge 网络
container
↓
docker0 bridge
↓
iptables NAT
↓
宿主机网卡
- 📌 NAT 转发
- 📌 容器 IP 私有
host 网络
- 无 Namespace
- 与宿主机共用网络栈
- 性能最好
overlay 网络(集群)
- VXLAN
- 跨宿主机容器通信
为什么容器不能存数据?
- 容器可随时销毁
- 写入 overlayfs 性能差
- 容器迁移困难
Volume 原理
container
↓
volume mount
↓
host FS
- 📌 volume 绕过 overlayfs
- 📌 高性能、持久化
| 维度 | Docker | VM |
|---|---|---|
| 内核 | 共享 | 独立 |
| 虚拟层级 | 进程级 | 硬件级 |
| 启动 | 秒级 | 分钟 |
| 资源 | 少 | 多 |
| 密度 | 高 | 低 |
- 不修改容器
- 通过构建新镜像发布
- 简化生命周期
- 易扩缩容
- 状态外置(DB / volume)
❌ 不是
✅ 进程隔离
✅ 安全依赖:
- 内核版本
- seccomp / apparmor
- 是否 root
- 镜像来源
- Docker:单机容器技术
- Kubernetes:容器编排系统
Docker 是进程,不是虚拟机
容器隔离来自内核,不是 Hypervisor
镜像是不可变的分层文件系统