容器镜像安全扫描是DevOps实践中保障CI/CD流水线安全的关键环节。生产环境中容器镜像通常来自多种来源:官方基础镜像、第三方应用镜像和自构建镜像,每一层都可能引入已知漏洞。Trivy作为Aqua Security开源的轻量级漏洞扫描工具,支持镜像、文件系统和Git仓库扫描,结合Kubernetes准入控制可以实现镜像级别的安全门禁,阻止含有高危漏洞的镜像进入集群。
Trivy安装配置与镜像漏洞扫描
Trivy支持多种安装方式,二进制安装最简单也最常用。扫描结果按严重程度分级(UNKNOWN/LOW/MEDIUM/HIGH/CRITICAL),可以配置阈值决定是否阻断构建流程。
# 安装Trivy
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
# 基本镜像扫描
trivy image nginx:1.25
# 指定严重程度过滤
trivy image --severity HIGH,CRITICAL nginx:1.25
# JSON格式输出(便于CI/CD集成)
trivy image --format json --output scan-result.json nginx:1.25
# 扫描本地镜像(已加载到Docker daemon)
trivy image --input <(docker save myapp:latest)
# 扫描文件系统(用于构建前检查源码依赖)
trivy fs --severity HIGH,CRITICAL ./myproject
# 扫描配置文件(Kubernetes YAML, Dockerfile, Terraform)
trivy config ./k8s-manifests/
# 扫描远程Git仓库
trivy repo https://github.com/myorg/myrepo
Trivy的漏洞数据库来自多个上游数据源:OS包级别的漏洞来自各发行版安全公告(RHEL OVAL、Ubuntu CVE Tracker等),语言依赖库漏洞来自OSV、GHSA等数据库。数据库默认每12小时自动更新,离线环境可以手动下载数据库文件。
CVE漏洞数据库与扫描策略定制
生产环境中并非所有漏洞都需要立即修复。通过配置.trivyignore文件可以忽略已知可接受的漏洞,通过trivy.yaml配置文件可以定制扫描策略,包括数据库镜像源、扫描超时、缓存策略等。
# .trivy.yaml 配置文件
scan:
scanners:
- vuln # 漏洞扫描
- misconfig # 配置错误扫描
- secret # 密钥泄露扫描
- license # 许可证扫描
vulnerability:
type:
- os
- library
ignore-unfixed: true # 忽略尚未有修复方案的漏洞
ignore-file: ./.trivyignore
db:
repository: ghcr.io/aquasecurity/trivy-db
skip-update: false
secret:
config-path: ./trivy-secret.yaml
# .trivyignore 文件:忽略特定CVE
CVE-2023-1234 # 已评估,不影响生产
CVE-2023-5678 # 等待上游修复
# trivy-secret.yaml:密钥泄露检测规则
allow-rules:
- id: allow-test-secrets
regex: 'test_token_.*'
block-rules:
- id: block-aws-keys
regex: 'AKIA[0-9A-Z]{16}'
不同环境应采用不同的扫描策略:开发环境仅报告CRITICAL级别漏洞,预发布环境报告HIGH和CRITICAL,生产环境报告MEDIUM及以上。这种分级策略既保证安全性又避免告警疲劳。
Kubernetes准入控制器集成
Kubernetes准入控制器(Admission Controller)是集群安全的第一道防线。通过Kyverno或OPA Gatekeeper可以在镜像部署到集群前拦截不合规的镜像。以下方案以Kyverno为例,配置一条ClusterPolicy要求所有镜像必须使用具体版本标签且来自可信仓库。
# 安装Kyverno
kubectl create -f https://github.com/kyverno/kyverno/releases/download/v1.12.0/install.yaml
# ClusterPolicy:阻止含有CRITICAL漏洞的镜像
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-image-scan
spec:
validationFailureAction: Enforce
rules:
- name: check-image-vulnerabilities
match:
any:
- resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "*"
attestors:
- entries:
- keys:
publicKeys: |
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----
mutateDigest: true
required: true
---
# ClusterPolicy:要求镜像使用特定标签(禁止latest)
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-latest-tag
spec:
validationFailureAction: Enforce
rules:
- name: require-image-tag
match:
any:
- resources:
kinds:
- Pod
validate:
message: "镜像必须使用具体版本标签,禁止使用latest"
pattern:
spec:
containers:
- image: "!*:latest"
---
# ClusterPolicy:要求镜像来源可信仓库
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: trusted-registry-only
spec:
validationFailureAction: Enforce
rules:
- name: check-registry
match:
any:
- resources:
kinds:
- Pod
validate:
message: "镜像必须来自可信仓库 harbor.example.com"
pattern:
spec:
containers:
- image: "harbor.example.com/*"
CI/CD流水线安全门禁配置
将Trivy集成到CI/CD流水线中实现自动化安全门禁,是Docker自动化部署安全闭环的关键。以下示例展示在GitLab CI和GitHub Actions中配置Trivy扫描步骤。
# GitLab CI配置:.gitlab-ci.yml
stages:
- build
- scan
- deploy
build_image:
stage: build
script:
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
security_scan:
stage: scan
image: aquasec/trivy:latest
script:
- trivy image --exit-code 1 --severity CRITICAL --ignore-unfixed $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
- trivy image --format json --output trivy-report.json $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
artifacts:
reports:
container_scanning: trivy-report.json
allow_failure: false # CRITICAL漏洞阻断流水线
deploy_production:
stage: deploy
script:
- kubectl set image deployment/myapp myapp=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
only:
- main
when: manual # 需要人工确认部署
# GitHub Actions配置:.github/workflows/security.yml
name: Container Security Scan
on: [push, pull_request]
jobs:
trivy-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t myapp:${{ github.sha }} .
- name: Trivy vulnerability scan
uses: aquasecurity/trivy-action@master
with:
image-ref: 'myapp:${{ github.sha }}'
format: 'sarif'
output: 'trivy-results.sarif'
severity: 'CRITICAL,HIGH'
exit-code: '1'
ignore-unfixed: true
- name: Upload results to GitHub Security
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: trivy-results.sarif
监控告警体系中应包含镜像安全指标。通过Prometheus导出Trivy扫描结果,设置告警规则监控未修复的高危漏洞数量。当新CVE披露时自动触发全量镜像重新扫描,确保存量镜像不会因新漏洞披露而成为安全盲区。
# Trivy Server模式(集中扫描)
trivy server --listen 0.0.0.0:4954
# 客户端调用
trivy image --server http://trivy-server:4954 myapp:latest
# Prometheus指标导出
# 使用trivy-operator自动扫描集群内运行镜像
helm install trivy-operator aquasecurity/trivy-operator
# 查看漏洞指标
kubectl get vulnerabilities.aquasecurity.github.io -A
容器安全不是一次性扫描的工作,而是贯穿构建、部署、运行全生命周期的持续过程。Trivy配合准入控制器和CI/CD门禁构成三道防线:构建时扫描阻断有漏洞的镜像进入仓库,部署时准入控制阻止未扫描的镜像进入集群,运行时trivy-operator定期扫描已在运行的容器。三层防护确保监控告警体系覆盖镜像安全的各个环节。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/rong-qi-jing-xiang-an-quan-sao-miao-shi-zhan-trivy-lou-dong/