Gitlab – Using Kaniko to Build/Push Image to Google Cloud Registry (GCR)

We were faced with difficulties getting a build image constructed, and then pushed to Google Cloud Repository (GCR) from GitLab. In setting this help, with a great deal of help from a coworker, I learned a lot about Docker, and how Docker should be used.

What was key was using an official gcloud image to set up a stage in the gitlab pipeline to perform the impersonation needed to get us logged into gcloud so we can push our image. We ended up with a simple .gitlab-ci.yml file that looks like:

stages:
- gcloud
- build
- publish

variables:
  DOCKER_NAME: <name of your image>
  
gcloud:
  stage: gcloud
  image:
    name: gcr.io/google.com/cloudsdktool/google-cloud-cli:latest
  environment:
    name: dev
  variables:
    CLOUDSDK_CONFIG: $CI_PROJECT_DIR/gcloud
  script:
    - gcloud config set auth/impersonate_service_account ${sa_account}
    - token=$(gcloud auth print-access-token)
    - docker_token=$(echo -n "gclouddockertoken:$token" | base64 | tr -d "\n")
    - echo "{\"auths\":{\"<server of gcr>\":{\"auth\":\"$docker_token\",\"email\":\"not@val.id\"}}}" > gcloud/config.json
  artifacts:
    paths:
      - gcloud/config.json

build:
  stage: build
  image: 
    name: <name of our java11 build image>
  tags:
    - <tag of a runner to use>
  script:
    - ./gradlew clean build
  artifacts:
    paths:
      - build/libs/*SNAPSHOT.jar
      - Dockerfile

publish:
  stage: publish
  dependencies:
    - build
    - gcloud
  image: 
    name: gcr.io/kaniko-project/executor:debug
    entrypoint: [""]
  before_script:
    - mkdir -p /kaniko/.docker
    - cp gcloud/config.json /kaniko/.docker/config.json
  script:
    - >
      /kaniko/executor
      --context "${CI_PROJECT_DIR}"
      --dockerfile "${CI_PROJECT_DIR}/Dockerfile"
      --destination "<server of gcr>/<path to image>/${DOCKER_NAME}:dev"

And … there you have it. The “gcloud” stage will run, and output the access token, which we store in the token variable. We produce a docker token out of it, base64 encoded, and produce a config.json with that value. We push that config.json out as an artifact of the stage. The publish stage then uses the config.json as it’s .docker/config.json, and we are automatically authenticated to the destination (GCR).

We were helped in no small way by stumbling across this post by Christopher Grotz, so …. thanks!

About John Woodward

Principal Consultant at Improving Enterprises, Inc. Tesla referral code: https://ts.la/john91435
This entry was posted in Software and tagged , , , . Bookmark the permalink.

Leave a comment