34

I have a Dockerfile which I can build using kaniko in the GitLab CI/CD pipeline. Currently the build stage both builds the Container and pushes it to the remote Docker repository.

I would like to utilize the stages concept of the CI/CD pipeline to build the image, then perform automatic tests and run a container security analysis tool (Trivy) and then as the last step, if all before steps were successful, I want to have it pushed to the registry:

  1. Build Image
  2. Perform automatic tests (based on the created image)
  3. Analyse security of created image (using Trivy)
  4. Push the image to the registry only if previous steps were successful and don't rebuild image

The command to build and push the image is:

build:latest-master:
  stage: build
  image:
    name: gcr.io/kaniko-project/executor:debug
    entrypoint: [""]
  script:
    - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
    - /kaniko/executor --cache=true --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $CI_REGISTRY_IMAGE:latest
  only:
    - master

There is an option / command line flag to perform no push with --no-push and there is a flag --tar-path that only produces a tarball of the image.

How would I have to combine these flags and commands to create the image only without pushing it to the regsitry, as it should only be pushed there if the security check has been performed. And then how does the push stage (GitLab CI Job) look like, especially the exact kaniko command line.

It would be great if that last pushing stage/job could reuse the previously build image or cache and not rebuilt it again. I guess the tarball could be used somehow but what would be the flag for kaniko to use it? Or do I just use that tarball and use a docker command to push the tarball to the registy?

kmindi
  • 4,524
  • 4
  • 31
  • 47
  • Were you able to find a solution to this pipeline staging question, as I am also building an image with Kaniko and would like to scan with Trivy before pushing the image to a registry, if scanning reports no high vulnerabilities? – anandg112 Aug 01 '20 at 21:13
  • Not yet, right now I let it push and use a separate stage to check security and another stage then for deployment (which should be the only place to trigger a pull of a new image) – kmindi Aug 03 '20 at 08:14

1 Answers1

48

You can do that using crane tool:

  • First step: Build with Kaniko and export to a tarball. Save your image as an artifact.
  • Second step: Push tarball to your registry using crane
docker:build:
  stage: build
  image:
    name: gcr.io/kaniko-project/executor:debug-v1.0.0
    entrypoint: [""]
  script:
  - /kaniko/executor
    --context $CI_PROJECT_DIR
    --dockerfile $CI_PROJECT_DIR/docker/Dockerfile
    --no-push
    --destination $CI_REGISTRY_IMAGE/path/to/your/image:version
    --tar-path image.tar
  artifacts:
    paths:
    - image.tar
    when: on_success

docker:push:
  stage: push
  image:
    name: gcr.io/go-containerregistry/crane:debug
    entrypoint: [""]
  script:
  - crane auth login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  - crane push image.tar $CI_REGISTRY_IMAGE/path/to/your/image:version
  needs:
  - docker:build
DrDol
  • 2,220
  • 2
  • 19
  • 23
Guillaume
  • 1,277
  • 8
  • 11
  • that looks like a good approach, I'll accept it when I have verified that it works as expected. – kmindi Aug 23 '20 at 14:23
  • were you able to verify? This is a really good question and answer. – Lebenitza Jun 15 '21 at 13:43
  • 1
    @Lebenitza I can confirm, using $CI_REGISTRY_IMAGE for the registry url – matttrach Oct 19 '21 at 04:42
  • 6
    This approach is good. It also allows to add one more step - scanning for vulnerabilities with trivy before pushing the image to registry. Very nice for Merge Request validation – Bogdans Dec 07 '21 at 14:51
  • Note that crane is not reading tags (nor image name) from tar file. You need to pass tags separately using crane tag. If single tag is sufficient for you, you can pass it using push like: `crane push image.tar registry:5000/path/To/Image:singleCustomTag`. – Lubo Aug 26 '22 at 08:50
  • Note that this pattern of saving docker images into the artifacts store only works for small images. GitLab has a default 100Mb and GitLab.com a 1Gb max size limit for artifacts and can only be change by GitLab administrators (see https://docs.gitlab.com/ee/user/admin_area/settings/continuous_integration.html#maximum-artifacts-size) – Zoltan Fedor Sep 20 '22 at 17:02
  • If you want to save a bit of time i think this will skip the git checkout too. Making the job run faster. " variables: GIT_STRATEGY: none" – RichE Oct 11 '22 at 16:08
  • Is "$CI_REGISTRY_IMAGE/path/to/your/image:version" usable as an image for steps before pushing? – Gino Pane Feb 03 '23 at 11:49