你的容器,真的安全吗?
假设你刚写好一个 Dockerfile:
FROM node:18-alpineWORKDIR /appCOPY package*.json ./RUN npm installCOPY . .EXPOSE 3000CMD ["node", "server.js"]看起来很干净对不对?但你可能不知道——node:18-alpine 基础镜像里有 47 个已知漏洞,其中 3 个是 Critical 级别的。npm install 拉下来的依赖里还有 12 个漏洞。
这不是危言耸听。根据 Aqua Security 的年度报告,超过 80% 的生产容器镜像包含至少一个高危漏洞。
而 Trivy 就是那个能在你 docker push 之前就把这些问题揪出来的工具。
Trivy 是什么?
Trivy(aquasecurity/trivy)是 Aqua Security 开源的一款全能安全扫描器。说它「全能」不是因为营销话术,而是它真的能扫描:
- 容器镜像漏洞(CVE)
- IaC 配置错误(Terraform、CloudFormation、K8s manifests)
- Kubernetes 集群风险
- 文件系统中的密钥和硬编码密码
- Git 仓库的 Secrets 泄露
- SBOM 生成和比对
而且——一条命令搞定。
# 安装 Trivy(macOS)brew install trivy
# Linuxcurl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh实战场景一:一键扫描容器镜像
这是 Trivy 最核心的场景。对比一下 docker scan 和 Trivy 的速度:
# 扫描本地镜像trivy image node:18-alpine
# 输出超快,几秒钟就出结果...输出会清晰列出每个漏洞的 CVE 编号、严重等级、受影响的包版本、以及修复版本:
node:18-alpine (alpine 3.16.3)=================================Total: 47 (CRITICAL: 3, HIGH: 12, MEDIUM: 25, LOW: 7)
┌──────────────┬────────────────┬──────────┬───────────────────┬───────────────┐│ Library │ Vulnerability │ Severity │ Installed │ Fixed Version ││ │ │ │ Version │ │├──────────────┼────────────────┼──────────┼───────────────────┼───────────────┤│ openssl │ CVE-2024-5535 │ CRITICAL │ 3.0.8-r4 │ 3.0.9-r0 ││ zlib │ CVE-2024-3648 │ HIGH │ 1.2.13-r0 │ 1.2.13-r1 ││ libcrypto3 │ CVE-2024-4603 │ CRITICAL │ 3.0.8-r4 │ 3.0.9-r0 ││ ... │ ... │ ... │ ... │ ... │└──────────────┴────────────────┴──────────┴───────────────────┴───────────────┘看到 openssl 那个 Critical 漏洞了吗?基础镜像的问题,不扫不知道。
集成到 CI/CD 流水线
更实用的做法是把 Trivy 集成到 GitHub Actions 或 GitLab CI 中,在每次 PR 时自动扫描:
name: Container Security Scan
on: pull_request: paths: - 'Dockerfile' - 'docker-compose*.yml'
jobs: trivy-scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Build Docker image run: docker build -t my-app:${{ github.sha }} .
- name: Run Trivy scan uses: aquasecurity/trivy-action@master with: image-ref: 'my-app:${{ github.sha }}' format: 'sarif' output: 'trivy-results.sarif' severity: 'CRITICAL,HIGH' exit-code: '1' # 有高危漏洞就阻止合并
- name: Upload scan results uses: github/codeql-action/upload-sarif@v3 with: sarif_file: 'trivy-results.sarif'重点:设置 exit-code: '1' 和 severity: 'CRITICAL,HIGH',一旦发现严重漏洞,PR 直接无法合并。这才是真正的「安全左移」。
实战场景二:扫描 IaC 配置错误
Terraform 配错了安全组?K8s 的 Pod 用了 privileged 模式?Trivy 也能管:
# 扫描 Terraform 配置trivy config ./terraform/
# 扫描 Kubernetes 部署文件trivy config ./k8s/# main.tf - 看看 Trivy 会发现什么问题resource "aws_s3_bucket" "data" { bucket = "my-app-data" # ❌ 没有设置 block_public_access!}
resource "aws_security_group" "web" { # ❌ 0.0.0.0/0 对所有 IP 开放 ingress { from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] }}Trivy 会直接报出:
aws_s3_bucket[data].block_public_access: 缺少 block_public_access 配置 (AVD-AWS-0139)aws_security_group[web].ingress: SSH (22) 对所有 IP 开放 (AVD-AWS-0021)在代码层面就发现问题,比等到部署到 AWS 才发现——或者更糟,等到被攻击才发现——要好得多。
实战场景三:密钥泄露检测
Git 仓库里不小心提交了 .env 文件?Trivy 能帮你抓出来:
# 扫描 Git 仓库中可能泄露的密钥trivy fs --scanners secret ./# config.py - 这种代码绝对不能提交!DB_PASSWORD = "SuperSecret123!"AWS_ACCESS_KEY = "AKIAIOSFODNN7EXAMPLE"AWS_SECRET_KEY = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"GITHUB_TOKEN = "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"2026-06-05T10:23:45.123Z CRITICAL GitHub Personal Access Token found2026-06-05T10:23:45.124Z CRITICAL AWS Access Key ID found2026-06-05T10:23:45.125Z CRITICAL AWS Secret Access Key found在 pre-commit hook 中使用
#!/bin/bashtrivy fs --scanners secret --exit-code 1 --severity CRITICAL,HIGH .if [ $? -ne 0 ]; then echo "❌ 检测到密钥泄露!请移除后再提交。" exit 1fiTrivy vs 其他安全工具
| 特性 | Trivy | Snyk | Clair | Grype |
|---|---|---|---|---|
| 镜像扫描 | ✅ | ✅ | ✅ | ✅ |
| IaC 扫描 | ✅ | ✅ | ❌ | ❌ |
| K8s 审计 | ✅ | ✅ | ❌ | ❌ |
| 密钥检测 | ✅ | ✅ | ❌ | ❌ |
| SBOM 生成 | ✅ | ✅ | ✅ | ✅ |
| 完全离线 | ✅ | ❌ | ✅ | ✅ |
| 开源免费 | ✅ | 部分付费 | ✅ | ✅ |
| 扫描速度 | 🚀 极快 | ⚡ 快 | 🐢 慢 | ⚡ 快 |
最佳实践总结
我把 Trivy 的最佳实践总结为三个阶段的「安全左移」流程:
开发阶段:零容忍策略
在开发者本地和 PR 阶段就把问题消灭掉:
开发阶段 ├── pre-commit hook: trivy fs --scanners secret ├── docker build: 使用多阶段构建 + 最小基础镜像 └── PR 审核: CI 中 trivy image + trivy config具体来说,pre-commit hook 应该检测密钥泄露和硬编码密码——这往往是数据泄露的第一大原因。CI 中的镜像扫描应该设置 --exit-code 1,一旦发现 Critical 或 High 漏洞就阻止 PR 合并。
Dockerfile 的最佳实践也是安全的关键一环:
# ❌ 不安全的做法FROM node:18 # 包含大量开发工具和已知漏洞
# ✅ 推荐做法FROM node:18-alpine AS builderWORKDIR /appCOPY package*.json ./RUN npm ci --only=production # 只安装生产依赖COPY . .RUN npm run build
FROM alpine:3.19 # 最小基础镜像RUN apk add --no-cache nodejs=18.19.0-r0WORKDIR /appCOPY --from=builder /app/dist ./distCOPY --from=builder /app/node_modules ./node_modulesEXPOSE 3000USER node # 不要用 root 运行CMD ["node", "dist/server.js"]多阶段构建 + 最小基础镜像 + 非 root 用户——这三个原则加在一起,能让镜像的漏洞数量从几十个降到个位数。
测试阶段:全面审计
在测试环境中做更彻底的检查:
测试阶段 ├── 定期全量扫描: trivy image --severity HIGH,CRITICAL ├── SBOM 生成: trivy image --format cyclonedx > sbom.json └── 策略检查: 基于扫描结果决定是否部署SBOM(软件物料清单)是 2026 年安全合规的重要趋势。生成 SBOM 后,你可以追踪每个镜像中使用的开源组件及其版本,在新 CVE 发布时快速定位受影响的服务。
# 生成 SPDX 格式的 SBOMtrivy image --format spdx-json --output sbom.spdx.json my-app:latest
# 基于之前生成的 SBOM 进行差异扫描trivy sbom sbom.spdx.json生产阶段:持续监控
到了生产环境,安全的重点从「预防」转向了「检测和响应」:
生产阶段 ├── 运行时扫描: K8s 准入控制器集成 ├── 持续监控: trivy k8s --report summary └── 事件响应: 新 CVE 发布时重新扫描K8s 集群的动态准入控制(Admission Controller)是一个非常强大的安全手段——当有人试图部署一个包含高危漏洞的镜像时,K8s 可以直接拒绝创建 Pod:
# Trivy Admission Controller 配置apiVersion: trivy-operator.aquasecurity.com/v1alpha1kind: ConfigAuditReportmetadata: name: trivy-admission-configspec: vulnerability: # 阻止任何包含 Critical 漏洞的镜像 block: critical: true high: true medium: false low: false # 例外:在 allowlist 中的镜像不拦截 allowlist: - "gcr.io/google-containers/*" - "registry.k8s.io/*"配置完成后,任何试图部署包含高危漏洞镜像的 Deployment 都会被自动拒绝,同时生成告警通知安全团队。
写在最后
安全左移不是一句口号,它需要工具链的支撑。Trivy 的价值在于:它不是又一个需要专门学习的安全平台,而是你 CI/CD 流水线里的一个命令。
在 2026 年这个「AI 写代码、CI 自动部署」的时代,安全不能再是上线的最后一关检查。因为代码的生成速度已经远超过了人工审查的速度——AI 可以在几分钟内生成几百行代码,但你不可能让安全团队逐行 review。唯一的出路就是自动化、工具化、左移化。
Trivy 恰好提供了这套能力。它不需要专门的运维人员来部署和维护,不需要昂贵的商业许可证,不需要改变现有的开发流程。装一个二进制文件,加一行 CI 配置,就能让你的整个安全水位提升一个档次。
对于个人开发者来说,用 Trivy 扫描自己的个人项目可能有点「大炮打蚊子」。但对于团队协作的项目——特别是那些有外部贡献者的开源项目——Trivy 几乎是必需品。一个关键的 CVE 如果没有被及时发现,可能会导致整个系统的数据泄露。我见过不止一个案例:一个开源项目因为依赖了一个有已知漏洞的库,被攻击者利用后导致用户数据泄露,项目声誉一落千丈。这种事如果在 CI 阶段就配置了 Trivy 扫描,完全可以避免——它会在你合并 PR 之前就发出警告,告诉你这个依赖有已知漏洞,请升级到修复版本。
另外一点值得强调的是:Trivy 不是那种「装了就不管」的工具。安全是一个持续的过程,不是一劳永逸的工作。今天没有漏洞的镜像,明天可能就爆出一个新的 CVE。所以最佳实践是把 Trivy 配置成定时任务——每周扫描一次所有生产镜像,一旦发现新的漏洞就自动创建工单通知团队处理。这种持续的安全运营,才是真正有效的安全策略。
一键扫描、即时反馈、自动阻断——这才是开发者喜欢的安全工具该有的样子。
安全最好的实践,不是让安全团队帮你看代码,而是让每个开发者都能自己发现和修复问题。Trivy 做到了这一点。
安全,不应该成为开发的绊脚石,而应该是开发的助推器。一个好的安全工具,应该让开发者感觉「在帮我」,而不是「在管我」。Trivy 就是这样一个工具。