Docker 的 scratch 镜像及其使用

528 阅读3分钟

1. 什么是 ****scratch ****镜像?

scratch 是 Docker 提供的一个特殊“空镜像”,其核心特点如下:

  • 空文件系统scratch 是一个完全空白的镜像,不包含任何操作系统、软件包或文件系统。
  • 无基础依赖:没有 Shell(如 /bin/sh)、包管理器(如 apt/apk)或动态链接库(如 glibc)。
  • 最小体积:基于 scratch 的镜像仅包含用户显式添加的文件,是构建极简镜像的理想选择。
  • 内置虚拟镜像scratch 是 Docker 内置的,无需从仓库拉取。

2. ****scratch ****镜像的典型用途

  • 静态编译的二进制程序:如 Go、Rust 等语言编译的静态可执行文件,无需依赖系统库。
  • 极致轻量化:适合需要最小化镜像体积的场景(如微服务、嵌入式设备)。
  • 安全敏感环境:减少攻击面,避免因系统组件漏洞导致的风险。

3. 如何使用 ****scratch ****镜像?

3.1 准备工作:静态编译程序

scratch 镜像无法直接运行动态链接的程序,因此需确保程序是静态编译的(不依赖外部库)。

示例:Go 程序静态编译


// main.go
package main
 
import "fmt"
 
func main() {
    fmt.Println("Hello from scratch!")
}

编译命令


# 静态编译(生成独立二进制文件)
GOOS=linux GOARCH=amd64 go build -o hello -ldflags="-s -w" main.go
  • -ldflags="-s -w":移除调试信息,进一步减小体积。
  • 输出文件 hello 是一个独立的二进制文件,可直接运行。
3.2 编写 Dockerfile

基于 scratch 的 Dockerfile 非常简单,仅需将二进制文件复制到镜像中。

示例 Dockerfile

FROM scratch
COPY hello /hello
CMD ["/hello"]
  • FROM scratch:从空白镜像开始。
  • COPY hello /hello:将本地编译的 hello 文件复制到镜像的根目录。
  • CMD ["/hello"]:指定默认运行 /hello
3.3 构建和运行镜像

构建镜像

docker build -t hello-scratch .
  • -t hello-scratch:为镜像命名。

运行容器

docker run --rm hello-scratch
  • --rm:容器退出后自动删除。
  • 输出:Hello from scratch!

验证镜像大小

docker images hello-scratch
  • 输出示例:
REPOSITORY    TAG       IMAGE ID       CREATED          SIZE
hello-scratch latest    1a2b3c4d5e6f   10 seconds ago   1.2MB
  • 镜像大小仅为 1.2MB(仅包含 hello 二进制文件)。

4. 注意事项

  1. 必须静态编译
    • 动态链接的程序(如 Python、Java)无法直接在 scratch 中运行,需手动添加依赖库或选择其他基础镜像(如 alpine)。
  1. 调试困难
    • scratch 镜像没有 Shell 或调试工具,建议先在本地开发环境测试程序,再迁移到 scratch
  1. 与 Alpine 的区别
    • FROM scratch 是完全空白的,而 FROM alpine 基于 Alpine Linux,已包含基本的 Shell 和包管理器(apk)。

5. 适用场景对比

场景推荐基础镜像原因
静态编译的 Go 程序FROM scratch极简体积,无依赖,适合微服务或嵌入式设备。
需要 Shell 的程序FROM alpineAlpine 提供 shapk,便于调试和安装依赖。
动态链接的程序FROM ubuntu/FROM debian需操作系统支持动态库,体积较大。

6. 总结

  • 核心优势scratch 镜像通过完全空白的环境,实现了镜像的极致轻量化和安全性。

  • 关键步骤

    1. 静态编译程序(如 Go)。
    2. 编写 Dockerfile 复制二进制文件。
    3. 构建并运行镜像。
  • 适用语言:Go、Rust 等支持静态编译的语言。

通过合理使用 scratch 镜像,可以显著优化 Docker 镜像的体积和安全性,尤其适合云原生和微服务架构。