GitLab运行中CI流水线查询容器扫描结果返回空的解决方案咨询
问题原因
GitLab的安全漏洞数据(包括容器扫描结果)并非扫描作业一结束就立刻写入可供API查询的数据库。扫描作业生成报告后,GitLab会启动异步的报告处理流程,这个流程通常要等整个流水线进入完成状态后才会完成数据同步,所以在流水线运行中直接调用API会返回空数组。
解决方案
方案1:直接读取扫描作业生成的本地报告文件(推荐)
容器扫描作业会生成标准格式的JSON报告文件gl-container-scanning-report.json,你可以将这个文件作为artifacts传递到query阶段,直接读取本地文件而无需调用API,这是最可靠高效的方式。
修改你的流水线配置:
include: - template: Security/Container-Scanning.gitlab-ci.yml stages: - build - scan - query build_job: stage: build ... container_scanning: stage: scan artifacts: paths: - gl-container-scanning-report.json # 传递报告文件到后续阶段 expire_in: 1 week # 可选,设置报告过期时间,避免存储冗余数据 ... query_job: stage: query ... script: # 直接读取本地报告文件,比如用jq解析漏洞信息 - cat gl-container-scanning-report.json - jq '.vulnerabilities[] | {name, severity, solution}' gl-container-scanning-report.json ...
方案2:轮询API直到数据可用(不推荐,仅当必须用API时使用)
如果必须通过API获取数据,可以在query_job中添加轮询逻辑,每隔几秒查询一次API,直到返回非空结果或超时。这种方法依赖GitLab的处理速度,可能会延长流水线执行时间。
示例脚本:
query_job: stage: query ... script: - | MAX_RETRIES=20 RETRY_INTERVAL=5 COUNT=0 while [ $COUNT -lt $MAX_RETRIES ]; do RESPONSE=$(curl -s --header "Authorization: Bearer ${CI_JOB_TOKEN}" "https://git.example.com/api/v4/projects/${CI_PROJECT_ID}/vulnerability_findings?report_type=container_scanning&pipeline_id=${CI_PIPELINE_ID}") if [ "$RESPONSE" != "[]" ]; then echo "获取到漏洞数据:" echo "$RESPONSE" exit 0 fi echo "暂未获取到数据,${RETRY_INTERVAL}秒后重试..." sleep $RETRY_INTERVAL COUNT=$((COUNT+1)) done echo "超时未获取到漏洞数据" exit 1 ...
注意:这里建议使用
${CI_JOB_TOKEN}代替手动输入的token,CI_JOB_TOKEN是流水线自动生成的,权限范围更安全且无需手动维护。
方案3:确认API权限
虽然你流水线结束后能查到数据,权限大概率没问题,但仍可确认:
- 如果使用个人访问令牌,需要确保令牌拥有
read_vulnerability权限; - 如果使用
CI_JOB_TOKEN,GitLab 13.10+版本默认赋予了项目内的read_vulnerability权限,若版本较低可能需要在项目设置中启用相关权限。
内容的提问来源于stack exchange,提问作者Cake
相关产品推荐
相关产品推荐

