| name | implementing-container-image-minimal-base-with-distroless |
| description | 通过在 Google distroless 基础镜像上构建应用镜像来减少容器攻击面,这些镜像仅包含应用运行时,没有 shell、包管理器或不必要的 OS 工具。 |
| domain | cybersecurity |
| subdomain | container-security |
| tags | ["distroless","container-images","minimal-base","attack-surface","docker","security-hardening","supply-chain","kubernetes"] |
| version | 1.0 |
| author | mahipal |
| license | Apache-2.0 |
使用 Distroless 实施容器镜像最小基础
概述
Google distroless 镜像仅包含应用程序及其运行时依赖项,不包含包管理器、shell 或标准 Linux 发行版中的其他程序。通过消除不必要的 OS 组件,distroless 镜像与 ubuntu 或 debian 等传统基础镜像相比,攻击面减少高达 95%。Kubernetes 本身、Knative 和 Tekton 等主要项目在生产中使用 distroless 镜像。截至 2025 年,Docker 也提供了 Hardened Images (DHI) 作为最小容器基础的开源替代方案。
前提条件
- Docker 20.10+ 或兼容的容器构建工具(Buildah、Kaniko)
- 多阶段 Dockerfile 知识
- 应用程序编译为静态二进制文件或已捆绑运行时
- 用于镜像存储的容器仓库
可用的 Distroless 镜像
| 镜像 | 使用场景 | 大小 |
|---|
gcr.io/distroless/static-debian12 | 静态编译的二进制文件(Go、Rust) | ~2MB |
gcr.io/distroless/base-debian12 | 需要 glibc 的动态链接二进制文件 | ~20MB |
gcr.io/distroless/cc-debian12 | 需要 libstdc++ 的 C/C++ 应用 | ~25MB |
gcr.io/distroless/java21-debian12 | Java 21 应用 | ~220MB |
gcr.io/distroless/python3-debian12 | Python 3 应用 | ~50MB |
gcr.io/distroless/nodejs22-debian12 | Node.js 22 应用 | ~130MB |
多阶段构建模式
Go 应用
# 构建阶段
FROM golang:1.22-bookworm AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /server ./cmd/server
# 运行阶段 - 静态 distroless
FROM gcr.io/distroless/static-debian12:nonroot
COPY --from=builder /server /server
USER nonroot:nonroot
ENTRYPOINT ["/server"]
Java 应用
# 构建阶段
FROM maven:3.9-eclipse-temurin-21 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests
# 运行阶段 - Java distroless
FROM gcr.io/distroless/java21-debian12:nonroot
COPY --from=builder /app/target/app.jar /app.jar
USER nonroot:nonroot
ENTRYPOINT ["java", "-jar", "/app.jar"]
Python 应用
# 构建阶段
FROM python:3.12-bookworm AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --target=/deps -r requirements.txt
COPY . .
# 运行阶段 - Python distroless
FROM gcr.io/distroless/python3-debian12:nonroot
WORKDIR /app
COPY --from=builder /deps /deps
COPY --from=builder /app /app
ENV PYTHONPATH=/deps
USER nonroot:nonroot
ENTRYPOINT ["python3", "/app/main.py"]
Node.js 应用
# 构建阶段
FROM node:22-bookworm AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
# 运行阶段 - Node distroless
FROM gcr.io/distroless/nodejs22-debian12:nonroot
WORKDIR /app
COPY --from=builder /app .
USER nonroot:nonroot
CMD ["server.js"]
安全优势
攻击面对比
| 组件 | Ubuntu | Alpine | Distroless |
|---|
| Shell(bash/sh) | 有 | 有 | 无 |
| 包管理器 | apt | apk | 无 |
| coreutils | 完整 | BusyBox | 无 |
| curl/wget | 有 | 有 | 无 |
| 用户管理 | 有 | 有 | 无 |
| 已知 CVE(典型) | 50-200+ | 5-20 | 0-5 |
| 镜像大小(基础) | ~77MB | ~7MB | ~2-20MB |
安全影响
- 无 shell:攻击者无法进入容器执行命令
- 无包管理器:无法安装额外工具或恶意软件
- 无 coreutils:无
cat、ls、find、curl 可用于侦察
- 最少 CVE:包越少,需要修补的漏洞越少
- 默认非 root:
:nonroot 标签以 UID 65534 运行
调试 Distroless 容器
由于 distroless 没有 shell,使用以下技术进行调试:
Debug 镜像变体
# 仅在非生产环境中使用 debug 变体
FROM gcr.io/distroless/base-debian12:debug
# 包含位于 /busybox/sh 的 busybox shell
kubectl exec -it pod-name -- /busybox/sh
临时调试容器(Kubernetes 1.25+)
kubectl debug -it pod-name --image=busybox:1.36 --target=app-container
使用 Crane/Dive 进行镜像检查
crane export gcr.io/distroless/static-debian12 - | tar -tf - | head -50
dive gcr.io/distroless/static-debian12
镜像扫描结果
使用 Trivy 的典型漏洞对比:
trivy image myapp:ubuntu
trivy image myapp:distroless
参考资料