Docker底层-OverlayFS

Docker 三大核心技术对比

1. 作用对比

复制代码
┌─────────────────────────────────────────────────────────┐
│  Docker 三大核心技术的作用                              │
│                                                          │
│  ┌──────────────────────────────────────────────────┐  │
│  │ 1. Namespace(隔离)                             │  │
│  │                                                  │  │
│  │  作用:隔离进程的视图                             │  │
│  │  • PID Namespace - 隔离进程 ID                    │  │
│  │  • Network Namespace - 隔离网络                  │  │
│  │  • Mount Namespace - 隔离文件系统挂载点           │  │
│  │  • IPC Namespace - 隔离进程间通信                 │  │
│  │  • UTS Namespace - 隔离主机名                     │  │
│  │  • User Namespace - 隔离用户 ID                  │  │
│  │  • Cgroup Namespace - 隔离 Cgroup 视图           │  │
│  │                                                  │  │
│  │  类比:给每个容器一个"独立的世界"                 │  │
│  └──────────────────────────────────────────────────┘  │
│                                                          │
│  ┌──────────────────────────────────────────────────┐  │
│  │ 2. Cgroup(资源限制)                            │  │
│  │                                                  │  │
│  │  作用:限制资源使用                               │  │
│  │  • CPU 限制 - 限制 CPU 使用率                    │  │
│  │  • 内存限制 - 限制内存使用                        │  │
│  │  • IO 限制 - 限制磁盘 IO                         │  │
│  │  • 进程数限制 - 限制进程数量                      │  │
│  │                                                  │  │
│  │  类比:给每个容器分配"资源配额"                   │  │
│  └──────────────────────────────────────────────────┘  │
│                                                          │
│  ┌──────────────────────────────────────────────────┐  │
│  │ 3. OverlayFS(文件系统)                          │  │
│  │                                                  │  │
│  │  作用:实现镜像层和容器层的联合挂载                │  │
│  │  • 镜像层 - 只读层(共享)                         │  │
│  │  • 容器层 - 可写层(每个容器独立)                 │  │
│  │  • 联合挂载 - 合并多个层为一个视图                  │  │
│  │  • Copy-on-Write - 修改时才复制                  │  │
│  │                                                  │  │
│  │  类比:给每个容器一个"独立的文件系统视图"           │  │
│  └──────────────────────────────────────────────────┘  │
│                                                          │
│  关键区别:                                               │
│  • Namespace = 隔离(让容器看不到其他容器)             │
│  • Cgroup = 限制(让容器不能无限使用资源)               │
│  • OverlayFS = 存储(让容器有独立的文件系统)            │
└─────────────────────────────────────────────────────────┘

2. OverlayFS 的具体作用

问题:为什么需要 OverlayFS?
复制代码
┌─────────────────────────────────────────────────────────┐
│  没有 OverlayFS 的问题                                  │
│                                                          │
│  场景:100 个容器都使用 ubuntu:20.04 镜像               │
│                                                          │
│  方案 1:每个容器完整复制镜像                            │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐            │
│  │ Container│  │ Container│  │ Container│            │
│  │    1     │  │    2     │  │   ...    │            │
│  │          │  │          │  │          │            │
│  │ 完整镜像  │  │ 完整镜像  │  │ 完整镜像  │            │
│  │ 500MB    │  │ 500MB    │  │ 500MB    │            │
│  └──────────┘  └──────────┘  └──────────┘            │
│                                                          │
│  总存储:100 × 500MB = 50GB ❌ 浪费空间!               │
└─────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────┐
│  使用 OverlayFS 的解决方案                               │
│                                                          │
│  场景:100 个容器都使用 ubuntu:20.04 镜像               │
│                                                          │
│  ┌──────────────────────────────────────────────────┐  │
│  │ 镜像层(只读,共享)                               │  │
│  │  ubuntu:20.04 (500MB)                            │  │
│  │  └── /bin, /lib, /usr, ...                       │  │
│  └──────────────────────────────────────────────────┘  │
│                      ↑                                   │
│                      │ 共享                               │
│          ┌───────────┼───────────┐                      │
│          │           │           │                      │
│  ┌───────▼───┐ ┌─────▼─────┐ ┌──▼──────┐              │
│  │ Container │ │ Container │ │Container│              │
│  │    1      │ │    2      │ │  100    │              │
│  │           │ │           │ │         │              │
│  │ 容器层    │ │ 容器层    │ │ 容器层   │              │
│  │ 10MB     │ │ 10MB     │ │ 10MB    │              │
│  └──────────┘ └──────────┘ └─────────┘              │
│                                                          │
│  总存储:500MB + (100 × 10MB) = 1.5GB ✅ 节省空间!      │
└─────────────────────────────────────────────────────────┘

3. 三者如何协同工作

复制代码
┌─────────────────────────────────────────────────────────┐
│  Docker 容器启动时的完整流程                             │
│                                                          │
│  ┌──────────────────────────────────────────────────┐  │
│  │ 1. OverlayFS(文件系统)                           │  │
│  │                                                  │  │
│  │  • 创建容器层(可写层)                            │  │
│  │  • 挂载镜像层(只读层)                            │  │
│  │  • 联合挂载到 merged 目录                         │  │
│  │                                                  │  │
│  │  结果:容器有独立的文件系统视图                     │  │
│  └──────────────────────────────────────────────────┘  │
│                      │                                  │
│                      ↓                                  │
│  ┌──────────────────────────────────────────────────┐  │
│  │ 2. Namespace(隔离)                              │  │
│  │                                                  │  │
│  │  • 创建 PID Namespace                             │  │
│  │  • 创建 Network Namespace                         │  │
│  │  • 创建 Mount Namespace                           │  │
│  │  • 创建 IPC Namespace                             │  │
│  │  • 创建 UTS Namespace                             │  │
│  │  • 创建 User Namespace                            │  │
│  │                                                  │  │
│  │  结果:容器有独立的进程、网络、文件系统视图          │  │
│  └──────────────────────────────────────────────────┘  │
│                      │                                  │
│                      ↓                                  │
│  ┌──────────────────────────────────────────────────┐  │
│  │ 3. Cgroup(资源限制)                             │  │
│  │                                                  │  │
│  │  • 创建 Cgroup 组                                 │  │
│  │  • 设置 CPU 限制                                 │  │
│  │  • 设置内存限制                                  │  │
│  │  • 设置 IO 限制                                  │  │
│  │                                                  │  │
│  │  结果:容器资源使用受限                            │  │
│  └──────────────────────────────────────────────────┘  │
│                      │                                  │
│                      ↓                                  │
│  ┌──────────────────────────────────────────────────┐  │
│  │ 4. 启动容器进程                                   │  │
│  │                                                  │  │
│  │  • 在 Namespace 中运行                            │  │
│  │  • 使用 OverlayFS 文件系统                        │  │
│  │  • 受 Cgroup 限制                                │  │
│  └──────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────┘

4. 实际例子对比

例子:运行一个 Redis 容器

docker run -d --name redis redis:latest

OverlayFS 做了什么:

复制代码
┌─────────────────────────────────────────────────────────┐
│  OverlayFS 的工作                                       │
│                                                          │
│  1. 挂载镜像层(只读)                                   │
│     /var/lib/docker/overlay2/<image-id>/diff            │
│     ├── /usr/local/bin/redis-server                    │
│     ├── /etc/redis.conf                                 │
│     └── ...                                             │
│                                                          │
│  2. 创建容器层(可写)                                   │
│     /var/lib/docker/overlay2/<container-id>/diff        │
│     └── (空,等待写入)                                  │
│                                                          │
│  3. 联合挂载                                            │
│     /var/lib/docker/overlay2/<container-id>/merged      │
│     ├── /usr/local/bin/redis-server  ← 来自镜像层      │
│     ├── /etc/redis.conf               ← 来自镜像层      │
│     └── /data/redis.rdb               ← 写入容器层      │
│                                                          │
│  结果:容器看到完整的文件系统,但只存储修改的部分!       │
└─────────────────────────────────────────────────────────┘

5. OverlayFS 工作原理

目录结构
复制代码
/var/lib/docker/overlay2/
├── <layer-id>/              # 镜像层(只读)
│   └── diff/               # 镜像文件
│
├── <container-id>/          # 容器层(可写)
│   ├── diff/               # 容器修改的文件(upperdir)
│   ├── work/               # 工作目录(workdir)
│   ├── merged/             # 合并视图(挂载点)
│   ├── lower               # 镜像层列表文件
│   └── link                # 符号链接 ID
│
└── l/                      # 符号链接目录
    └── <link-id> -> ../<container-id>/diff
三层结构
复制代码
┌─────────────────────────────────────────┐
│ merged/ (容器看到的完整文件系统)         │
│  ├── /usr/local/bin/redis-server       │
│  ├── /etc/redis.conf                    │
│  └── /data/redis.rdb                    │
└─────────────────────────────────────────┘
              ↑
              │ OverlayFS 合并
              │
┌─────────────────────────────────────────┐
│ upperdir (容器层 - 可写)                 │
│  └── /data/redis.rdb  ← 容器修改的文件  │
└─────────────────────────────────────────┘
              ↑
              │ 叠加在
              │
┌─────────────────────────────────────────┐
│ lowerdir (镜像层 - 只读,多个层)          │
│  ├── layer-9: /usr/local/bin/redis-server│
│  ├── layer-8: /etc/redis.conf           │
│  └── ...                                 │
└─────────────────────────────────────────┘
相关推荐
眠りたいです2 小时前
Docker:Docker Network容器之间及容器与外部世界的通信桥梁
运维·docker·容器·docker网络
goodlook01232 小时前
监控平台搭建-监控指标展示-Grafana篇(五)
java·算法·docker·grafana·prometheus
java_logo2 小时前
Apache Flink Docker 容器化部署指南
docker·flink·apache·apache flink·apache flink部署·flink部署文档·flink部署教程
深耕AI2 小时前
【Docker Desktop for Windows】 两个 volumes 目录的区别
windows·docker·容器
深耕AI2 小时前
【手搓 Docker 卷 volumes】从 `docker volume create` 到落盘位置的最后1公里
运维·docker·容器
鸠摩智首席音效师2 小时前
如何在 Linux 中使用 fallocate 命令 ?
linux·运维·服务器
雨大王5122 小时前
如何选择汽车制造数字化服务商?关键指标与实战案例解析
大数据·运维·人工智能
QT 小鲜肉2 小时前
【Linux命令大全】001.文件管理之split命令(实操篇)
linux·运维·服务器·网络·笔记
是垚不是土2 小时前
TDengine脚本备份方案:全库/单库备份与飞书通知
大数据·运维·数据库·飞书·时序数据库·tdengine