Docker 镜像优化:从 1GB 到 50MB

镜像过大的危害 很多团队在容器化初期不太关注镜像体积,一个 Spring Boot 应用镜像动辄 800MB-1.2GB,一个 Go 应用也常有 700MB+。镜像过大带来的问题远不止"占点磁盘": 拉取慢,部署延迟高:在 CI/CD 流水线或弹性扩容场景下,节点需要先拉取镜像再启动容器。1GB 的镜像在百兆内网下载需要 80 秒以上,而 50MB 的镜像仅需 4 秒。对于 HPA 自动扩容场景,这意味着故障恢复窗口被拉长。 安全攻击面大:基础镜像里包含了大量你根本用不到的系统工具(curl、wget、gcc、bash 等)。攻击者一旦拿到容器 shell,这些工具就是横向移动的跳板。镜像越小,攻击面越窄。 存储成本累积:一个镜像 1GB,每天构建 5 次、保留 30 天就是 150GB。10 个微服务就是 1.5TB。 Harbor / Registry 的存储成本和备份成本随之飙升。 构建缓存效率低:大镜像的每一层都更大,构建缓存命中后的加载也更慢,拖慢整体 CI 流水线。 本文参考 Docker 官方多阶段构建文档 多阶段构建(Multi-stage Build) 为什么需要多阶段构建 传统 Dockerfile 的关键问题是:构建工具和运行时环境混在同一个镜像里。 以 Go 应用为例,编译需要 go 工具链和 gcc,但运行时只需要一个二进制文件。如果用 golang:1.22 做基础镜像,最终镜像里会带上整个 Go SDK(约 800MB+),而你的应用二进制可能只有 15MB。 多阶段构建允许在一个 Dockerfile 中定义多个 FROM,每个 FROM 开始一个新阶段,最终镜像只保留最后一个阶段的内容。 多阶段构建语法 # ===== 阶段1:构建阶段 ===== FROM golang:1....

March 14, 2024 · 4 分钟 · 766 字 · 徐保金