You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在GitLab CI中用Kaniko推送镜像前执行容器扫描且不使用制品?

解决方案

问题1:推送前漏洞扫描的替代方案(无制品存储)

存在成熟的最佳实践,核心是让Kaniko构建镜像后先导出为本地镜像文件,直接在CI流水线内完成扫描,确认无高危漏洞后再推送。具体流程:

  1. Kaniko构建并导出镜像为tar包:使用Kaniko的--tarPath参数,将构建好的镜像导出为tar文件到CI节点的共享存储路径(不存入GitLab制品库),同时加上--no-push参数避免提前推送。
  2. 加载tar包为本地镜像:扫描任务中用docker load命令将tar包加载为本地可识别的镜像。
  3. GitLab容器扫描本地镜像:配置GitLab容器扫描作业,通过环境变量指定本地镜像的标签,直接扫描本地镜像而非远程仓库镜像。
  4. 条件触发推送:只有扫描结果无高危漏洞时,再调用Kaniko将镜像推送到目标仓库。

问题2:构建与扫描任务共用存储的配置

完全可以实现,无需依赖制品存储,主要有两种可行方式:

方式1:绑定同一Runner的本地共享目录

  • 给构建、扫描、推送三个Job指定相同的tags,确保它们运行在同一个GitLab Runner节点上。
  • 在该Runner的配置文件中,挂载一个本地目录(如/tmp/ci-shared)到Job容器内的固定路径(如/shared)。
  • 构建Job将镜像tar包导出到/shared/${CI_COMMIT_SHA}.tar,扫描Job直接从该路径加载镜像,推送Job则基于源代码重新构建(或复用tar包推送,需额外配置)。

示例CI配置片段:

stages:
  - build
  - scan
  - push

build-image:
  stage: build
  tags:
    - shared-storage-runner
  script:
    - |
      /kaniko/executor \
        --context "${CI_PROJECT_DIR}" \
        --dockerfile "${CI_PROJECT_DIR}/Dockerfile" \
        --tarPath "/shared/${CI_COMMIT_SHA}.tar" \
        --no-push

scan-image:
  stage: scan
  tags:
    - shared-storage-runner
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker load -i "/shared/${CI_COMMIT_SHA}.tar"
    - docker tag $(docker images -q | head -1) ${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHA}
    # 配置扫描环境变量,指向本地镜像
    - export CI_APPLICATION_REPOSITORY=${CI_REGISTRY_IMAGE}
    - export CI_APPLICATION_TAG=${CI_COMMIT_SHA}
    - run-container-scanning
  rules:
    - if: $CI_COMMIT_BRANCH
      when: on_success

push-image:
  stage: push
  tags:
    - shared-storage-runner
  script:
    - |
      /kaniko/executor \
        --context "${CI_PROJECT_DIR}" \
        --dockerfile "${CI_PROJECT_DIR}/Dockerfile" \
        --destination "${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHA}" \
        --destination "${CI_REGISTRY_IMAGE}:latest"
  rules:
    - if: $CI_COMMIT_BRANCH
      when: on_success

方式2:利用GitLab CI临时缓存(适合小型镜像)

  • 构建Job将镜像tar包存入GitLab CI的cache(缓存仅用于流水线内临时共享,不进入制品库),设置policy: push。
  • 扫描Job通过policy: pull从缓存中提取tar包,完成扫描。
  • 此方式无需绑定特定Runner,但缓存有大小限制,仅适合体积较小的镜像。

示例缓存配置片段:

build-image:
  stage: build
  script:
    - |
      /kaniko/executor \
        --context "${CI_PROJECT_DIR}" \
        --dockerfile "${CI_PROJECT_DIR}/Dockerfile" \
        --tarPath "${CI_PROJECT_DIR}/image.tar" \
        --no-push
  cache:
    key: "${CI_COMMIT_SHA}"
    paths:
      - image.tar
    policy: push

scan-image:
  stage: scan
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker load -i image.tar
    # 扫描步骤同方式1
  cache:
    key: "${CI_COMMIT_SHA}"
    paths:
      - image.tar
    policy: pull

关键注意事项

  • Runner权限:使用Docker-in-Docker时,需确保Runner配置了足够的权限访问Docker daemon。
  • 扫描环境变量:必须正确设置CI_APPLICATION_REPOSITORY和CI_APPLICATION_TAG,让GitLab扫描工具识别本地镜像。
  • 清理机制:流水线结束后,需通过脚本清理共享目录或缓存中的tar包,避免占用节点存储空间。

内容的提问来源于stack exchange,提问作者Eladik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 09:53:25