diff --git a/task/kaniko/0.3/README.md b/task/kaniko/0.3/README.md new file mode 100644 index 0000000000..721a53f72a --- /dev/null +++ b/task/kaniko/0.3/README.md @@ -0,0 +1,65 @@ +# Kaniko + +This Task builds source into a container image using Google's +[`kaniko`](https://github.com/GoogleCloudPlatform/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. +> - [Kaniko website](https://github.com/GoogleCloudPlatform/kaniko) + +kaniko is meant to be run as an image, `gcr.io/kaniko-project/executor:v1.5.1`. This +makes it a perfect tool to be part of Tekton. + +## Install the Task + +``` +kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/master/task/kaniko/0.3/kaniko.yaml +``` + +## Parameters + +* **IMAGE**: The name (reference) of the image to build. +* **DOCKERFILE**: The path to the `Dockerfile` to execute (_default:_ `./Dockerfile`) +* **CONTEXT**: The build context used by Kaniko (_default:_ `./`) +* **EXTRA_ARGS**: Additional args to pass to the Kaniko executor. +* **BUILDER_IMAGE**: The Kaniko executor image to use (_default:_ `gcr.io/kaniko-project/executor:v1.5.1`) + +## Workspaces + +* **source**: A [Workspace](https://github.com/tektoncd/pipeline/blob/master/docs/workspaces.md) containing the source to build. + +## Results + +* **IMAGE-DIGEST**: The digest of the image just built. + +## ServiceAccount + +kaniko builds an image and pushes it to the destination defined as a parameter. +In order to properly authenticate to the remote container registry, it needs to +have the proper credentials. This is achieved using a `ServiceAccount`. + +For an example on how to create such a `ServiceAccount` to push an image to +DockerHub, see the +[Authentication](https://github.com/tektoncd/pipeline/blob/master/docs/auth.md#basic-authentication-docker) +documentation page. + +## Usage + +This TaskRun runs the Task to fetch a Git repo, and build and push a container +image using Kaniko + +``` +apiVersion: tekton.dev/v1beta1 +kind: TaskRun +metadata: + name: example-run +spec: + taskRef: + name: kaniko + workspaces: + - name: source + persistentVolumeClaim: + claimName: my-source +``` diff --git a/task/kaniko/0.3/kaniko.yaml b/task/kaniko/0.3/kaniko.yaml new file mode 100644 index 0000000000..e2c23ed724 --- /dev/null +++ b/task/kaniko/0.3/kaniko.yaml @@ -0,0 +1,84 @@ +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: kaniko + labels: + app.kubernetes.io/version: "0.3" + annotations: + tekton.dev/pipelines.minVersion: "0.12.1" + 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 + capabilities: + add: + - CHOWN + - DAC_OVERRIDE + - FOWNER + - SETGID + - SETUID + - SETFCAP + - KILL + - 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) + # imega/jq:latest as of March 10, 2021 + # https://hub.docker.com/r/imega/jq/ + image: docker.io/imega/jq@sha256:39d079b17c958870d03cac5b7b70300dc2e86fc97f9c31ae9a505fcd97418fae + script: | + cat $(params.CONTEXT)/image-digested | jq '.[0].value' -rj | tee /tekton/results/IMAGE-DIGEST diff --git a/task/kaniko/0.3/tests/pre-apply-task-hook.sh b/task/kaniko/0.3/tests/pre-apply-task-hook.sh new file mode 100755 index 0000000000..892417d70d --- /dev/null +++ b/task/kaniko/0.3/tests/pre-apply-task-hook.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# Add an internal registry as sidecar to the task so we can upload it directly +# from our tests withouth having to go to an external registry. +add_sidecar_registry ${TMPF} + +# Add git-clone +add_task git-clone latest diff --git a/task/kaniko/0.3/tests/resources.yaml b/task/kaniko/0.3/tests/resources.yaml new file mode 100644 index 0000000000..195051e964 --- /dev/null +++ b/task/kaniko/0.3/tests/resources.yaml @@ -0,0 +1,11 @@ +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: kaniko-source-pvc +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 500Mi diff --git a/task/kaniko/0.3/tests/run.yaml b/task/kaniko/0.3/tests/run.yaml new file mode 100644 index 0000000000..521f255b23 --- /dev/null +++ b/task/kaniko/0.3/tests/run.yaml @@ -0,0 +1,71 @@ +--- +apiVersion: tekton.dev/v1beta1 +kind: Pipeline +metadata: + name: kaniko-test-pipeline +spec: + workspaces: + - name: shared-workspace + params: + - name: image + description: reference of the image to build + tasks: + - name: fetch-repository + taskRef: + name: git-clone + workspaces: + - name: output + workspace: shared-workspace + params: + - name: url + value: https://github.com/kelseyhightower/nocode + - name: subdirectory + value: "" + - name: deleteExisting + value: "true" + - name: kaniko + taskRef: + name: kaniko + runAfter: + - fetch-repository + workspaces: + - name: source + workspace: shared-workspace + params: + - name: IMAGE + value: $(params.image) + - name: EXTRA_ARGS + value: "--skip-tls-verify" + - name: verify-digest + runAfter: + - kaniko + params: + - name: digest + value: $(tasks.kaniko.results.IMAGE-DIGEST) + taskSpec: + params: + - name: digest + steps: + - name: bash + image: ubuntu + script: | + echo $(params.digest) + case .$(params.digest) in + ".sha"*) exit 0 ;; + *) echo "Digest value is not correct" && exit 1 ;; + esac +--- +apiVersion: tekton.dev/v1beta1 +kind: PipelineRun +metadata: + name: kaniko-test-pipeline-run +spec: + pipelineRef: + name: kaniko-test-pipeline + params: + - name: image + value: localhost:5000/kaniko-nocode + workspaces: + - name: shared-workspace + persistentvolumeclaim: + claimName: kaniko-source-pvc