饮墨

子安饮墨馀三斗,留与卿儿作赋来

Chainguard Images + Wolfi OS:构建零 CVE 容器镜像实战

痛点:你的容器镜像到底有多少漏洞?

用 Trivy 扫一下你生产环境的基础镜像,结果往往触目惊心:

$ trivy image python:3.12-slim
Total: 287 (UNKNOWN: 0, LOW: 112, MEDIUM: 98, HIGH: 62, CRITICAL: 15)

即使是 -slim 变体,Debian/Ubuntu 基础镜像也天然携带大量系统级包,其中不乏已知 CVE。这些漏洞绝大多数与你的应用毫无关系,但安全审计不管——扫出来就要修,修不动就要写豁免申请。

核心矛盾:传统发行版为通用性设计,塞了太多你用不到的东西;而 scratch/distroless 又缺少必要的工具链,调试排障极其困难。

方案:Wolfi OS + Chainguard Images

Wolfi OS 是 Chainguard 开源的面向容器的 Linux 发行版(非通用 OS),专为生成最小化、可签名、可溯源的容器镜像而设计。核心特性:

  • 使用 apk(Alpine 的包管理器)但基于 glibc(非 musl),兼容性远超 Alpine
  • 所有包每日从源码构建,CVE 修复平均响应时间 < 24 小时
  • 原生支持 SBOM(Software Bill of Materials)生成
  • 包粒度极细,可精确控制镜像内容

Chainguard Images 是基于 Wolfi 构建的预置镜像集合,涵盖 Python、Node.js、Go、Java、Nginx 等常用运行时,开箱即实现零或近零已知 CVE。

实操步骤

第 1 步:替换基础镜像对比效果

以 Python 应用为例,原始 Dockerfile:

# 旧方案:基于 Debian slim
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "main.py"]

替换为 Chainguard 镜像:

# 新方案:基于 Chainguard Python
FROM cgr.dev/chainguard/python:latest-dev AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt

FROM cgr.dev/chainguard/python:latest
WORKDIR /app
COPY --from=builder /install /usr/
COPY . .
CMD ["python", "main.py"]

关键区别: - latest-dev 标签含 pip、shell 等构建工具,用于编译阶段 - latest 标签是最终运行时,仅包含 Python 解释器和必要库 - 多阶段构建确保最终镜像干净

扫描对比:

$ trivy image my-app:chainguard
Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)

第 2 步:用 apko 自定义 Wolfi 镜像

当 Chainguard 预置镜像不满足需求时(如需要额外系统工具),用 apko 从 Wolfi 包仓库自行组装:

# apko.yaml
contents:
  repositories:
    - https://packages.wolfi.dev/os
  keyring:
    - https://packages.wolfi.dev/os/wolfi-signing.rsa.pub
  packages:
    - wolfi-baselayout
    - python-3.12
    - py3-pip
    - ca-certificates-bundle
    - curl        # 仅在确实需要时加入

accounts:
  groups:
    - groupname: app
      gid: 1000
  users:
    - username: app
      uid: 1000
      gid: 1000
  run-as: 1000

entrypoint:
  command: /usr/bin/python3

archs:
  - x86_64
  - aarch64

构建镜像:

# 安装 apko
go install chainguard.dev/apko@latest

# 构建并加载到 Docker
apko build apko.yaml my-wolfi-python:latest my-wolfi-python.tar
docker load < my-wolfi-python.tar

第 3 步:集成到 CI/CD 流水线

在 GitHub Actions 中自动构建 + 签名 + 扫描:

name: Build Wolfi Image
on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
      id-token: write  # cosign keyless 签名需要

    steps:
      - uses: actions/checkout@v4

      - name: Build with apko
        uses: chainguard-images/actions/apko-build@main
        with:
          config: apko.yaml
          tag: ghcr.io/${{ github.repository }}:${{ github.sha }}

      - name: Sign with Cosign
        uses: sigstore/cosign-installer@v3
      - run: cosign sign --yes ghcr.io/${{ github.repository }}:${{ github.sha }}

      - name: Scan with Trivy
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: ghcr.io/${{ github.repository }}:${{ github.sha }}
          exit-code: 1        # CVE 非零即失败
          severity: HIGH,CRITICAL

第 4 步:验证 SBOM 和来源证明

Chainguard Images 自带 SBOM 和构建证明(attestation),可直接验证:

# 查看镜像 SBOM
cosign download attestation cgr.dev/chainguard/python:latest \
  | jq -r '.payload' | base64 -d | jq '.predicate.packages[]' | head -20

# 验证签名
cosign verify cgr.dev/chainguard/python:latest \
  --certificate-oidc-issuer=https://token.actions.githubusercontent.com \
  --certificate-identity-regexp='.*chainguard.*'

避坑指南

1. musl vs glibc 兼容性问题

从 Alpine 迁移到 Wolfi 时注意:Wolfi 用 glibc,Alpine 用 musl。如果你的应用依赖预编译的 musl 二进制,需要重新编译。反过来,从 Debian/Ubuntu 迁移则基本无缝。

2. -dev 标签不要用于生产

cgr.dev/chainguard/python:latest-dev 包含 shell 和包管理器,仅用于多阶段构建的编译阶段。最终镜像必须用 latest(不含 shell),否则攻击面并未缩小。

3. 免费版 vs 付费版的差异

Chainguard 的免费 Developer 镜像仅提供 :latest 标签且无 SLA。生产环境需要固定版本标签(如 python:3.12.4)需订阅 Production 版。替代方案:直接用 apko + Wolfi 公开包仓库自行构建,完全免费且可固定版本。

总结

维度 Debian slim Alpine Chainguard/Wolfi
典型 CVE 数 50-300 10-50 0-5
C 库 glibc musl glibc
镜像大小 80-150 MB 30-50 MB 20-40 MB
调试便利性 低(无 shell)
供应链安全 无 SBOM 无 SBOM 原生 SBOM + 签名

核心结论:对安全审计有硬性要求的团队,Chainguard Images 是性价比最高的「零 CVE」路径——替换一行 FROM 即可。需要更多自定义控制时,apko + Wolfi 包是 DIY 的正确姿势。两者都应搭配 Cosign 签名 + Trivy 扫描形成完整的容器供应链安全闭环。

您还没有登录,请登录后发表评论。