Skip to content

2. Create a Task to Build and Upload Container Image using Kaniko

The next task that the pipeline needs is a task that builds a docker image and pushes it to a container registry. The catalog provides a kaniko task which does this using Google's kaniko tool. The task is described here.

The task is reproduced below.

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: kaniko
  labels:
    app.kubernetes.io/version: "0.2"
  annotations:
    tekton.dev/pipelines.minVersion: "0.12.1"
    tekton.dev/categories: Image Build
    tekton.dev/tags: image-build
spec:
  description: >-
    This Task builds source into a container image using Google's kaniko tool.

    Kaniko doesn't depend on a Docker daemon and executes each
    command within a Dockerfile completely in userspace. This enables
    building container images in environments that can't easily or
    securely run a Docker daemon, such as a standard Kubernetes cluster.

  params:
  - name: IMAGE
    description: Name (reference) of the image to build.
  - name: DOCKERFILE
    description: Path to the Dockerfile to build.
    default: ./Dockerfile
  - name: CONTEXT
    description: The build context used by Kaniko.
    default: ./
  - name: EXTRA_ARGS
    default: ""
  - name: BUILDER_IMAGE
    description: The image on which builds will run (default is v1.5.1)
    default: gcr.io/kaniko-project/executor:v1.5.1@sha256:c6166717f7fe0b7da44908c986137ecfeab21f31ec3992f6e128fff8a94be8a5
  workspaces:
  - name: source
  results:
  - name: IMAGE-DIGEST
    description: Digest of the image just built.
  steps:
  - name: build-and-push
    workingDir: $(workspaces.source.path)
    image: $(params.BUILDER_IMAGE)
    # specifying DOCKER_CONFIG is required to allow kaniko to detect docker credential
    # https://github.com/tektoncd/pipeline/pull/706
    env:
    - name: DOCKER_CONFIG
      value: /tekton/home/.docker
    args:
    - $(params.EXTRA_ARGS)
    - --dockerfile=$(params.DOCKERFILE)
    - --context=$(workspaces.source.path)/$(params.CONTEXT)  # The user does not need to care the workspace and the source.
    - --destination=$(params.IMAGE)
    - --oci-layout-path=$(workspaces.source.path)/$(params.CONTEXT)/image-digest
    # kaniko assumes it is running as root, which means this example fails on platforms
    # that default to run containers as random uid (like OpenShift). Adding this securityContext
    # makes it explicit that it needs to run as root.
    securityContext:
      runAsUser: 0
  - name: write-digest
    workingDir: $(workspaces.source.path)
    image: gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/imagedigestexporter:v0.16.2
    # output of imagedigestexport [{"key":"digest","value":"sha256:eed29..660","resourceRef":{"name":"myrepo/myimage"}}]
    command: ["/ko-app/imagedigestexporter"]
    args:
    - -images=[{"name":"$(params.IMAGE)","type":"image","url":"$(params.IMAGE)","digest":"","OutputImageDir":"$(workspaces.source.path)/$(params.CONTEXT)/image-digest"}]
    - -terminationMessagePath=$(params.CONTEXT)/image-digested
    securityContext:
      runAsUser: 0
  - name: digest-to-results
    workingDir: $(workspaces.source.path)
    image: docker.io/stedolan/jq@sha256:a61ed0bca213081b64be94c5e1b402ea58bc549f457c2682a86704dd55231e09
    script: |
      cat $(params.CONTEXT)/image-digested | jq '.[0].value' -rj | tee /tekton/results/IMAGE-DIGEST

You can see that this task needs a workspace as well.

workspaces:
  - name: source

This workspace has the source to be build. The pipeline will provide the same workspace that it used for the git-clone task.

The kaniko task also uses a feature called results. A result is a value produced by a task which can then be used as a parameter value to other tasks. This task declares a result named IMAGE-DIGEST which it sets to the digest of the built image. A task sets a result by writing it to a file named /tekton/results/name where name refers to the name of the result, in this case IMAGE-DIGEST. We will see later how the pipeline uses this result.

results:
  - name: IMAGE-DIGEST

We will cover how the task authenticates to the image repository for permission to push the image later.

First, apply the file to your cluster and create the kaniko task in your namespace.

$ oc apply -f https://raw.githubusercontent.com/tektoncd/catalog/main/task/kaniko/0.2/kaniko.yaml
task.tekton.dev/kaniko created

$ oc get tasks
NAME        AGE
git-clone   48m
kaniko      3m9s

Next

Next, go to Create a Task to Deploy an Image to OpenShift.