Trivy 容器镜像安全扫描实战:CI/CD 漏洞检测与修复指南

适用场景

Trivy 容器镜像安全扫描适用于以下场景:在 CI/CD 流水线中构建镜像后自动扫描漏洞、上线前对生产镜像做安全准入检查、定期对私有仓库中的存量镜像做巡检,以及 Kubernetes 集群部署前校验镜像安全性。对于已经使用 Docker 与 Kubernetes 的团队,Trivy 是最低门槛的镜像漏洞治理工具。

前置条件

  • Linux 服务器或本地开发机,已安装 Docker(用于扫描镜像)
  • 具备 root 或 sudo 权限
  • 可访问外网,用于首次下载漏洞数据库(约 80MB)
  • CI/CD 场景需要 GitHub Actions / GitLab CI 等流水线环境

原理说明

Trivy(Treasure Vulnerability)是 Aqua Security 开源的漏洞扫描器,核心原理是比对镜像文件系统与 CVE 漏洞数据库:它解析镜像每一层的包管理器元数据(如 APK、RPM、DEB),提取软件包名称与版本,再与 NVD、Red Hat、Debian、Alpine、Ubuntu 等漏洞源的数据比对,输出受影响漏洞及其严重级别。Trivy 还支持生成 SBOM(软件物料清单)并识别密钥等敏感信息,扫描速度通常在数秒内完成。

操作步骤

1. 安装 Trivy

# Debian/Ubuntu
sudo apt-get install wget apt-transport-https gnupg lsb-release
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
echo deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main | sudo tee -a /etc/apt/sources.list.d/trivy.list
sudo apt-get update && sudo apt-get install trivy

# 二进制直接安装(任意发行版)
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin

验证安装:trivy --version

2. 扫描镜像基础用法

# 先拉取待扫描镜像
docker pull nginx:1.27

# 扫描镜像(首次运行会自动下载漏洞数据库)
trivy image nginx:1.27

# 只看高危急漏洞
trivy image --severity HIGH,CRITICAL nginx:1.27

# 忽略未修复的漏洞(很多漏洞上游尚无补丁)
trivy image --ignore-unfixed nginx:1.27

输出会按 CRITICAL / HIGH / MEDIUM / LOW 四级列出漏洞,包含 CVE 编号、受影响组件、修复版本。

3. 输出格式与结果导出

# JSON 格式,便于接入平台
trivy image --format json --output result.json nginx:1.27

# SARIF 格式,接入 GitHub Code Scanning
trivy image --format sarif --output trivy.sarif nginx:1.27

# 表格模式按严重级别过滤
trivy image --format table --severity CRITICAL nginx:1.27

4. 忽略误报与基线豁免

# 项目根目录创建 .trivyignore
# 每条一行,写 CVE 编号加注释
# CVE-2026-0000
# 此漏洞仅影响非默认配置,暂不修复

# 扫描时自动读取 .trivyignore
trivy image --ignorefile .trivyignore nginx:1.27

5. CI/CD 流水线集成(GitHub Actions)

name: image-scan
on:
  push:
    branches: [ main ]
jobs:
  trivy-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build image
        run: docker build -t myapp:latest .
      - name: Run Trivy scan
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: 'myapp:latest'
          format: 'table'
          exit-code: '1'
          severity: 'CRITICAL,HIGH'
          ignore-unfixed: true

关键点:exit-code: ‘1’ 表示扫描到 HIGH/CRITICAL 漏洞时流水线直接失败,形成发布门禁;ignore-unfixed: true 可避免因无修复版本而阻塞发布。

6. 文件系统与 Git 仓库扫描

# 扫描本地代码目录依赖(无需镜像)
trivy fs ./myapp

# 扫描远程仓库
trivy repo https://github.com/aquasecurity/trivy

# 扫描 IaC 配置错误(Dockerfile/K8s yaml)
trivy config ./deploy

配置验证

# 验证 1:确认扫描结果可解析
trivy image --format json --severity CRITICAL nginx:1.27 | python3 -m json.tool | head -50

# 验证 2:确认门禁生效(扫描到高危时返回非 0)
trivy image --exit-code 1 --severity CRITICAL nginx:1.27; echo "exit=$?"

若返回 exit=1 说明镜像存在 CRITICAL 漏洞,门禁正确拦截;修复后再次扫描应返回 exit=0

常见问题

FAQ 1:Trivy 扫描结果与 Docker Hub 官方扫描不一致怎么办?

不同工具使用的漏洞数据源和匹配算法不同,结果存在差异属正常。建议以 Trivy 为准并固定数据库版本:trivy image --download-db-only --db-repository ghcr.io/aquasecurity/trivy-db 离线同步,保证 CI 环境数据一致。

FAQ 2:扫描到的漏洞没有修复版本,如何处理?

.trivyignore 中豁免并记录原因与复核时间,同时通过风险缓解(如限制网络出口、加固运行参数)降低被利用概率,定期复查上游补丁状态。生产环境严禁直接忽略 CRITICAL 漏洞而不评估。

FAQ 3:Trivy 能扫描私有仓库镜像吗?

可以。先执行 docker login 登录私有仓库,或用 TRIVY_USERNAME / TRIVY_PASSWORD 环境变量提供凭证;离线环境需提前导出漏洞数据库并配置 --offline-scan

总结

Trivy 以零配置、多数据源、支持 CI 门禁的特点,成为容器镜像安全扫描的事实标准工具。建议团队将其接入构建流水线:镜像构建后立即扫描,高危漏洞阻断发布,配合 .trivyignore 管理例外项,并每月对存量镜像做一次全量巡检,形成「构建即扫描、漏洞不进生产」的闭环。