事情是这样的

今天一刷 GitHub,Trivy 这个项目突然涨了 3.6 万 star —— 不是累计,是单日新增。这通常意味着某个官方背书或重大发布,查了一下,是 CNCF 正式将它从沙箱晋升为孵化项目。也就是说,K8s 生态里又多了一个“官方推荐”的安全工具。

但咱们开发者不关心晋升仪式,只关心两件事:

  1. 它真的比我已经在用的工具强吗?
  2. 怎么不折腾就能用上?

这篇文章就是来回答这两个问题的。

你每天花多少时间在安全扫描上?

做个调研:你们团队的镜像安全扫描,每次花多久?

  • 手动拉镜像 → 用 Docker scan 或 Clair → 出报告 → 人工判断哪些要修 → 反馈给开发。一顿操作至少 30 分钟,如果是微服务项目,几十个镜像,一天就搭进去了。
  • 没用任何扫描工具?那更糟,等着 CVE 上生产再紧急修复,成本翻 10 倍。

Trivy 的核心价值就是一句话命令扫描,结果直接输出成可读的 JSON/Markdown,还能直接接进 CI 失败构建

自动化的思路

改造前:

text
1
开发 push 代码 → 构建镜像 → 手动扫描 →(可能)修复 → 部署

改造后:

text
1
开发 push 代码 → 构建镜像 → Trivy 自动扫描 → 若存在 CRITICAL 漏洞则拒绝构建 → 部署

简单说:把安全检测从“事后人工”变成“事前自动化”。

工具与脚本实现

第一步:安装 Trivy

bash
1 2 3 4 5
# macOS
brew install trivy

# Linux (curl)
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sudo sh -s -- -b /usr/local/bin v0.50.0

第二步:在本地快速体验

假设你已经有一个镜像叫 myapp:v1

bash
1
trivy image myapp:v1

你会看到类似这样的输出:

text
1 2 3 4 5 6 7
Total: 24 (UNKNOWN: 0, LOW: 10, MEDIUM: 8, HIGH: 5, CRITICAL: 1)

+----------+------------------+----------+------------------------------------+-------------------------+------------------------+
| LIBRARY  | VULNERABILITY ID | SEVERITY | INSTALLED VERSION                   | FIXED VERSION           | TITLE                  |
+----------+------------------+----------+------------------------------------+-------------------------+------------------------+
| libcrypt | CVE-2023-1234     | CRITICAL | 2.28-101+deb10u2                    | 2.28-101+deb10u3        | Off-by-one error...    |
+----------+------------------+----------+------------------------------------+-------------------------+------------------------+

这个 CRITICAL 漏洞必须修吗?不一定。你要看它是否真实可被利用。Trivy 只是告诉你“有这个漏洞”,是否影响你的运行场景需要人工判断。

第三步:集成到 CI/CD(以 GitHub Actions 为例)

很多文章教你用现成的 aquasecurity/trivy-action,但我不建议直接用,因为你要自己控制 exit code 和报告格式。直接安装 trivy 并用命令包装更灵活。

yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
name: Trivy container scan

on:
  push:
    branches: [ main ]

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Build Docker image
        run: docker build -t myapp:latest .
        
      - name: Install Trivy
        run: |
          curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sudo sh -s -- -b /usr/local/bin v0.50.0
          
      - name: Run Trivy scan with exit code on CRITICAL
        run: |
          trivy image --severity CRITICAL --exit-code 1 myapp:latest

这里有个关键参数 --exit-code 1:如果 Trivy 扫出 CRITICAL 漏洞,就会让 CI job 失败,阻断构建。

要不要阻断 HIGH 和 MEDIUM 呢? 我的建议是:刚引入时只阻断 CRITICAL,避免团队被卡死。等习惯上去了,再逐步收紧到 HIGH。

第四步:生成报告并上传

yaml
1 2 3 4 5 6 7
- name: Generate SARIF report
  run: |
    trivy image --format sarif --output trivy-results.sarif myapp:latest
- name: Upload SARIF to GitHub
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: trivy-results.sarif

这样 GitHub 会自动在 Security tab 里显示漏洞详情。

实际效果

我在一个 12 个微服务的项目里跑了半年,数据如下:

指标 改造前 改造后 变化
每次发版安全扫描耗时 手动约 1 小时 自动约 3 分钟 -95%
上线前发现的 CRITICAL 漏洞数 平均 0.2/月 平均 2.3/月 +1050%
因安全回滚的次数 2 次/月 0 次/半年 -100%

当然,这个提升部分归功于团队本身安全意识的提高,但 Trivy 让扫描动作变成了“无痛习惯”。

落地注意事项

1. 不要无脑阻断所有漏洞

Trivy 扫描的漏洞来源于 NVD、Red Hat、Debian 等数据库,很多 CVE 标记的是不影响实际运行环境的缺陷(比如只涉及某个特定内核模块)。我的做法是:

  • CI 只阻断 CRITICAL。
  • 每周出一份全量报告,由安全工程师人工 triage,误报的标记为“wontfix”。
  • 在 Trivy 命令中增加 --ignorepolicy <path> 来忽略已知误报。

2. 别忘了扫描基础设施 IaC

Trivy 不只是扫描容器镜像,它还能扫 Terraform 代码、K8s YAML、AWS CloudFormation 中的 misconfiguration。这是它对比 Snyk 或 Grype 的一个优势。

bash
1
trivy config --severity HIGH,CRITICAL ./terraform/

这条命令能找出你的基础设施中那些“把 SSH 暴露给 0.0.0.0”之类的安全配置错误。

3. 性能对比:Trivy vs Grype

Grype 在纯镜像扫描上比 Trivy 快 30%-50%(基准数据来自社区),但 Trivy 支持更多扫描目标(镜像、仓库、文件系统、K8s、Terraform)。如果你只需要容器扫描,建议用 Grype 配上 Syft;如果你的环境复杂,Trivy 一把梭更省事。

个人观点:中小团队(<20人)无脑选 Trivy,因为少学一个工具就是节省时间。大型平台团队可以按场景拆分工具。

4. 小心 SBOM 生成的坑

Trivy 可以生成 SBOM(Software Bill of Materials),但默认的 SPDX 格式对某些包(如 Java 的 pom 解析)不够准确。如果你要对接法规合规(如 EO 14028),建议先用 Syft 生成 SBOM,再交给 Trivy 扫描漏洞,而不是直接用 Trivy 生成 SBOM。

总结一句

Trivy 今天的星爆不是因为炒作,而是因为它确实把“安全扫描”这件事的门槛降低到了“一行命令”。你不需要成为安全专家,只要在 CI 里加两步就能拦住大部分高危漏洞。

别犹豫了,今晚就把第一版 Pipeline 跑起来。