插件窝 干货文章 docker image是怎么存储的

docker image是怎么存储的

镜像 Docker 存储 文件 165    来源:    2025-04-06

Docker 镜像的存储是一个分层、高效的机制,其核心设计基于联合文件系统(UnionFS)。以下是详细解析:


1. 分层存储结构

Docker 镜像由多个只读层(Layer)叠加组成,每个层代表镜像构建过程中的一条指令(如 RUNCOPY 等)。例如:

FROM ubuntu:20.04         # 基础层
RUN apt-get update        # 新增层
COPY app /opt/app         # 新增层
  • 特点
    • 每层仅存储与上一层的差异部分,节省空间。
    • 层是共享的,多个镜像可复用相同层(如相同的 ubuntu:20.04 基础层)。

2. 存储驱动与文件系统

Docker 使用存储驱动(Storage Driver)管理层的堆叠和访问,常见驱动包括: - Overlay2(推荐):基于 OverlayFS,性能优,支持页缓存共享。 - AUFS:早期默认驱动,适合旧系统。 - Devicemapper:适用于 CentOS/RHEL(需 direct-lvm 优化)。 - Btrfs/ZFS:适用于特定文件系统需求。

数据存储路径: - Linux 默认位置:/var/lib/docker/<storage-driver>/ - 例如:/var/lib/docker/overlay2/


3. 镜像组成要素

  • Manifest:描述镜像的配置和层信息(JSON 文件)。
  • Config:包含镜像元数据(如环境变量、入口点)。
  • Layer Diff:每层的文件系统变更(压缩为 tar 归档)。
  • Image ID:基于内容哈希(SHA256)的唯一标识。

4. 镜像与容器的关系

  • 镜像:静态的只读层。
  • 容器:在镜像顶部添加一个可写层(Container Layer),所有修改(如日志、临时文件)均在此层,容器删除后该层丢失。

5. 存储优化实践

  • 清理无用镜像bash docker image prune -a # 删除悬空镜像 docker system df # 查看存储占用
  • 选择合适驱动:生产环境推荐 overlay2
  • 多阶段构建:减少最终镜像层数和大小。

    FROM golang AS builder     # 构建阶段
    COPY . /src
    RUN go build -o /app
    
    FROM alpine               # 最终阶段
    COPY --from=builder /app /
    

6. 底层文件系统示例(Overlay2)

/var/lib/docker/overlay2/
├── l/                      # 硬链接目录(缩短层ID路径)
├── <layer-id>/
│   ├── diff/               # 该层文件变更(如新增的 `/opt/app`)
│   ├── link                # 短名称引用
│   └── lower               # 指向父层标识
└── merged/                 # 联合挂载点(容器运行时视图)

常见问题

  • Q:镜像占用的磁盘空间比实际文件大?

    • A:因分层存储和日志等元数据占用,可用 docker system prune 清理。
  • Q:如何导出/导入镜像?

    • A:使用 docker savedocker load
    docker save my-image > my-image.tar
    docker load < my-image.tar
    

通过理解分层设计和存储驱动,可以更高效地管理 Docker 镜像的生命周期和资源占用。