trivy扫描镜像前须确认运行时权限与缓存路径:默认读Docker socket需root权限,$HOME/.cache/trivy写入失败会导致静默漏报;非root下应加--timeout --no-progress --skip-update并手动更新DB;CI/CD推荐TRIVY_CACHE_DIR显式指定;Podman需--dockerfile或trivy fs;Go调用优先用trivy-go SDK;注意FixedVersion字段而非仅Severity;library漏洞需显式启用--security-checks;多阶段构建需过滤Layers;K8s准入应异步预检;--light提速;--offline-scan仍需本地DB且须统一管理。

用 trivy 扫描镜像前,必须确认运行时权限和缓存路径
直接跑 trivy image nginx:1.25 很可能失败——不是因为镜像问题,而是 trivy 默认尝试读取本地 Docker daemon socket(/var/run/docker.sock),而普通用户没权限;更隐蔽的是,它还会在 $HOME/.cache/trivy 写扫描缓存,若磁盘满或目录不可写,会静默跳过数据库更新,导致漏报高危 CVE。
- 非 root 场景下,加
--timeout 300s --no-progress --skip-update避免卡住,但要手动定期执行trivy image --download-db-only - CI/CD 中推荐显式指定缓存目录:
TRIVY_CACHE_DIR=/tmp/trivy-cache trivy image --format json nginx:1.25 - 若用
podman替代 Docker,需加--dockerfile或改用trivy fs模式,否则报错failed to get docker client
Go 程序里调用 trivy 不要用 os/exec.Command 直接拼字符串
硬编码命令行容易被镜像名里的特殊字符(如冒号、斜杠、@sha256)破坏,且无法可靠捕获结构化结果。Go 生态已有轻量封装,比自己 parse JSON 输出更稳。
- 优先用
github.com/aquasecurity/trivy-go官方 SDK,它屏蔽了 CLI 的临时文件、信号处理、版本兼容等细节 - 关键配置别漏掉:
ScanOptions{SkipFiles: []string{".git", "vendor/"}},否则扫描超大构建产物会 OOM - 注意
trivy-gov0.5+ 默认启用远程 DB 模式,若离线环境需提前下载trivy.db并设DBRepository: "file:///path/to/trivy.db"
trivy 扫描结果里 Severity 字段不能直接当处置依据
同一个 CVE 在不同镜像层可能显示不同严重等级,比如 CVE-2023-45853 在基础镜像中标为 MEDIUM,但在你应用层引入的 libssl 补丁包里实际已修复——但 trivy 仍按原始 NVD 数据标级,不结合上下文 patch 状态。
- 务必检查结果中的
FixedVersion字段,为空表示暂无修复,而非“低风险” - 对
library类型漏洞(如 Go module 中的golang.org/x/crypto),trivy默认不扫,得加--security-checks vuln,config,secret并配合--scanners vuln - 误报常见于多阶段构建:builder 镜像里的漏洞出现在 final 镜像中根本不存在,需用
--ignore-unfixed+ 对比Layers字段过滤
在 Kubernetes 集群里做准入扫描,别让 trivy 成为 Pod 启动瓶颈
同步调用 trivy 扫描镜像会把 admission webhook 延迟拉到秒级,尤其首次拉取镜像时还要解压 layer,极易触发 kube-apiserver 超时(默认 30s)。
立即学习“go语言免费学习笔记(深入)”;
- 不要在
MutatingWebhookConfiguration里实时扫描,改用ValidatingWebhookConfiguration+ 异步 job 预检,用ImagePolicyWebhook或 OPA/Gatekeeper 做策略兜底 - 扫描本身建议用
trivy image --light模式,跳过 OS 包指纹比对,只查已知漏洞 ID,速度提升 3–5 倍 - 注意
trivy的--offline-scan不等于离线可用,它仍依赖本地 DB,DB 更新必须由 operator 统一管理,不能每个 webhook pod 自行下载
真正卡住落地的,从来不是“能不能扫”,而是缓存路径权限、FixedVersion 判定逻辑、以及 webhook 超时和 DB 更新节奏这三件事的耦合。扫出来一堆 HIGH 不难,难的是知道哪条该立刻阻断,哪条其实已在 runtime 层被绕过。










