bigywater.tech
Docker · 17

基础镜像对比:alpine、debian-slim 与 distroless 的真实体积

“用 alpine 镜像小”到底小多少?这篇把 busybox、alpine、debian-slim、ubuntu 拉下来,数文件、看 libc 和包管理器,再用同一个 Go 程序实际装进去,看镜像最后多大,以及最小的 scratch 要付出什么代价。

138.15 MB vs 2.22 MB
同一个 1.57 MB 的静态 Go 程序,FROM debian:12-slim 与 FROM scratch 的镜像大小
89 vs 3266 个文件
alpine:3.20 与 debian:12-slim 里的文件数
退出码 127
scratch 镜像里 docker run --entrypoint sh 的结果:找不到 sh

四个基础镜像多大

实测 · 本机执行输出
  busybox:1.36     DISK USAGE   6.14MB   CONTENT SIZE    1.9MB
  alpine:3.20      DISK USAGE   13.6MB   CONTENT SIZE   4.09MB
  debian:12-slim   DISK USAGE    136MB   CONTENT SIZE   28.1MB
  ubuntu:24.04     DISK USAGE    139MB   CONTENT SIZE   28.9MB

busybox:1.36 是 6.14MB,alpine:3.20 是 13.6MB,debian:12-slim 是 136MB,ubuntu:24.04 是 139MB(docker images 的 DISK USAGE)。压缩后的内容分别是 1.9、4.09、28.1、28.9 MB。这是 arm64 版本,amd64 版本大小可能不同(本文没有测)。

差在哪

实测 · 本机执行输出
  [busybox:1.36] 文件数 424 | libc: | shell: /bin/sh | 包管理器: dpkg
  [alpine:3.20] 文件数 89 | libc: /lib/ld-musl-aarch64.so.1 | shell: /bin/sh | 包管理器: apk | 系统: Alpine Linux v3.20
  [debian:12-slim] 文件数 3266 | libc: /lib/aarch64-linux-gnu/libc.so.6 | shell: /bin/sh /bin/bash | 包管理器: apt-get dpkg | 系统: Debian GNU/Linux 12 (bookworm)
  [ubuntu:24.04] 文件数 2589 | libc: /lib/aarch64-linux-gnu/libc.so.6 | shell: /bin/sh /bin/bash | 包管理器: apt-get dpkg | 系统: Ubuntu 24.04.5 LTS

alpine 里只有 89 个文件,用 musl 和 apk;debian-slim 有 3266 个文件,用 glibc,带 bash、apt-get、dpkg;ubuntu 是 2589 个文件。选 alpine 还是 debian 不只是大小的问题:libc 不同,依赖 glibc 的预编译二进制在 alpine 里可能跑不起来(本文没有测这一点)。busybox 里 command -v dpkg 能找到,为什么我没有查。

装进同一个程序

实测 · 本机执行输出
  Go 静态二进制(-ldflags="-s -w"):1.57 MB
  FROM scratch         → 镜像 Size   2.22 MB;运行输出:hello from static go
  FROM busybox:1.36    → 镜像 Size   8.36 MB;运行输出:hello from static go
  FROM alpine:3.20     → 镜像 Size  15.80 MB;运行输出:hello from static go
  FROM debian:12-slim  → 镜像 Size 138.15 MB;运行输出:hello from static go
  FROM ubuntu:24.04    → 镜像 Size 141.60 MB;运行输出:hello from static go

把 CGO_ENABLED=0 编译的 1.57 MB 静态 Go 程序分别 COPY 进五个 FROM,镜像大小是 2.22(scratch)、8.36(busybox)、15.80(alpine)、138.15(debian-slim)、141.60(ubuntu)MB。程序本身没变,基础镜像占了镜像体积的绝大部分。scratch 比二进制本身多出的 0.65 MB 我推测是压缩内容与解包层都被计入(docker image inspect 的 Size),没有单独验证。

scratch 的代价

实测 · 本机执行输出
  scratch:退出码 127;输出:docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: exec: "sh": executable file not found in $PATH
  alpine:3.20:退出码 0;输出:shell 可用

scratch 里没有 shell:docker run --entrypoint sh 报 exec: "sh": executable file not found in $PATH,退出码 127;alpine 里同样的命令成功。需要进容器排查的服务,体积和可排查性要自己权衡。

分步演示

基础镜像体积
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Docker Desktop(Engine 29.8.2,容器跑在 Docker Desktop 自带的 Linux 虚拟机里,内核与宿主机的 macOS 不同);镜像为 linux/arm64;需要看虚拟机内部时用特权容器 + nsenter;计时用 time / date +%s%N,数字每次运行会有小幅抖动。四个基础镜像用 dpull.py 在宿主机经代理下载后 docker load;Go 程序用宿主机 go 交叉编译(CGO_ENABLED=0 GOOS=linux GOARCH=arm64,-ldflags="-s -w");镜像体积取 docker images 与 docker image inspect .Size;文件数用 find / -xdev -type f;实验后已删除这些镜像
    • 没有验证:amd64 版本的体积、distroless 镜像(没有拉取)、动态链接程序在 alpine 上的兼容问题、安装软件后的体积增长、镜像里的 CVE 数量、busybox 里 dpkg 的来源
    京ICP备2026067502号-1京公网安备11010502063487号