This tutorial uses a simple Hello World
example to show you how to:
- Create a
Task
- Create a
Pipeline
containing yourTasks
- Use a
TaskRun
to instantiate and execute aTask
outside of aPipeline
- Use a
PipelineRun
to instantiate and run aPipeline
containing yourTasks
This tutorial consists of the following sections:
Note: Items requiring configuration are marked with the #configure
annotation.
This includes Docker registries, log output locations, and other configuration items
specific to a given cloud computing service.
Before you begin this tutorial, make sure you have installed and configured the latest release of Tekton on your Kubernetes cluster, including the Tekton CLI.
If you would like to complete this tutorial on your local workstation, see Running this tutorial locally. To learn more about the Tekton entities involved in this tutorial, see Further reading.
A Task
defines a series of steps
that run in a desired order and complete a set amount of build work. Every Task
runs as a Pod on your Kubernetes cluster with each step
as its own container. For example, the following Task
outputs "Hello World":
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: echo-hello-world
spec:
steps:
- name: echo
image: ubuntu
command:
- echo
args:
- "Hello World"
Apply your Task
YAML file as follows:
kubectl apply -f <name-of-task-file.yaml>
To see details about your created Task
, use the following command:
tkn task describe echo-hello-world
The output will look similar to the following:
Name: echo-hello-world
Namespace: default
π¨ Input Resources
No input resources
π‘ Output Resources
No output resources
β Params
No params
π¦Ά Steps
β echo
π Taskruns
No taskruns
To run this Task
, instantiate it using a TaskRun
:
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
name: echo-hello-world-task-run
spec:
taskRef:
name: echo-hello-world
Apply your TaskRun
YAML file as follows:
kubectl apply -f <name-of-taskrun-file.yaml>
To check whether running your TaskRun
succeeded, use the following command:
tkn taskrun describe echo-hello-world-task-run
The output will look similar to the following:
Name: echo-hello-world-task-run
Namespace: default
Task Ref: echo-hello-world
Status
STARTED DURATION STATUS
4 minutes ago 9 seconds Succeeded
Input Resources
No resources
Output Resources
No resources
Params
No params
Steps
NAME
echo
The Succeeded
status confirms that the TaskRun
completed with no errors.
To see more detail about the execution of your TaskRun
, view its logs as follows:
tkn taskrun logs echo-hello-world-task-run
The output will look similar to the following:
[echo] hello world
In more complex scenarios, a Task
requires you to define inputs and outputs. For example, a
Task
could fetch source code from a GitHub repository and build a Docker image from it.
Use one or more PipelineResources
to define the artifacts you want to pass in
and out of your Task
. The following are examples of the most commonly needed resources.
The git
resource specifies a git repository with
a specific revision from which the Task
will pull the source code:
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
name: skaffold-git
spec:
type: git
params:
- name: revision
value: master
- name: url
value: https://github.com/GoogleContainerTools/skaffold #configure: change if you want to build something else, perhaps from your own local git repository.
The image
resource specifies the repository to which the image built by the Task
will be pushed:
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
name: skaffold-image-leeroy-web
spec:
type: image
params:
- name: url
value: gcr.io/<use your project>/leeroy-web #configure: replace with where the image should go: perhaps your local registry or Dockerhub with a secret and configured service account
In the following example, you can see a Task
definition with the git
input and image
output
introduced earlier. The arguments of the Task
command support variable substitution so that
the Task
definition is constant and the value of parameters can change during runtime.
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: build-docker-image-from-git-source
spec:
params:
- name: pathToDockerFile
type: string
description: The path to the dockerfile to build
default: $(resources.inputs.docker-source.path)/Dockerfile
- name: pathToContext
type: string
description: |
The build context used by Kaniko
(https://github.com/GoogleContainerTools/kaniko#kaniko-build-contexts)
default: $(resources.inputs.docker-source.path)
resources:
inputs:
- name: docker-source
type: git
outputs:
- name: builtImage
type: image
steps:
- name: build-and-push
image: gcr.io/kaniko-project/executor:v0.17.1
# specifying DOCKER_CONFIG is required to allow kaniko to detect docker credential
env:
- name: "DOCKER_CONFIG"
value: "/tekton/home/.docker/"
command:
- /kaniko/executor
args:
- --dockerfile=$(params.pathToDockerFile)
- --destination=$(resources.outputs.builtImage.url)
- --context=$(params.pathToContext)
Before you can execute your TaskRun
, you must create a secret
to push your image
to your desired image registry:
kubectl create secret docker-registry regcred \
--docker-server=<your-registry-server> \
--docker-username=<your-name> \
--docker-password=<your-pword> \
--docker-email=<your-email>
You must also specify a ServiceAccount
that uses this secret
to execute your TaskRun
:
apiVersion: v1
kind: ServiceAccount
metadata:
name: tutorial-service
secrets:
- name: regcred
Save the ServiceAccount
definition above to a file and apply the YAML file to make the ServiceAccount
available for your TaskRun
:
kubectl apply -f <name-of-file.yaml>
You are now ready for your first TaskRun
!
A TaskRun
binds the inputs and outputs to already defined PipelineResources
, sets values
for variable substitution parameters, and executes the Steps
in the Task
.
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
name: build-docker-image-from-git-source-task-run
spec:
serviceAccountName: tutorial-service
taskRef:
name: build-docker-image-from-git-source
params:
- name: pathToDockerFile
value: Dockerfile
- name: pathToContext
value: $(resources.inputs.docker-source.path)/examples/microservices/leeroy-web #configure: may change according to your source
resources:
inputs:
- name: docker-source
resourceRef:
name: skaffold-git
outputs:
- name: builtImage
resourceRef:
name: skaffold-image-leeroy-web
Save the YAML files that contain your Task
, TaskRun
, and PipelineResource
definitions and apply them using the following command:
kubectl apply -f <name-of-file.yaml>
To examine the resources you've created so far, use the following command:
kubectl get tekton-pipelines
The output will look similar to the following:
NAME AGE
taskruns/build-docker-image-from-git-source-task-run 30s
NAME AGE
pipelineresources/skaffold-git 6m
pipelineresources/skaffold-image-leeroy-web 7m
NAME AGE
tasks/build-docker-image-from-git-source 7m
To see the result of executing your TaskRun
, use the following command:
tkn taskrun describe build-docker-image-from-git-source-task-run
The output will look similar to the following:
Name: build-docker-image-from-git-source-task-run
Namespace: default
Task Ref: build-docker-image-from-git-source
Status
STARTED DURATION STATUS
2 hours ago 56 seconds Succeeded
Input Resources
NAME RESOURCE REF
docker-source skaffold-git
Output Resources
NAME RESOURCE REF
builtImage skaffold-image-leeroy-web
Params
NAME VALUE
pathToDockerFile Dockerfile
pathToContext /workspace/docker-source/examples/microservices/leeroy-web
Steps
NAME
build-and-push
create-dir-builtimage-wtjh9
git-source-skaffold-git-tck6k
image-digest-exporter-hlbsq
The Succeeded
status indicates the Task
has completed with no errors. You
can also confirm that the output Docker image has been created in the location specified in the resource definition.
To view detailed information about the execution of your TaskRun
, view the logs:
tkn taskrun logs build-docker-image-from-git-source-task-run
A Pipeline
defines an ordered series of Tasks
that you want to execute
along with the corresponding inputs and outputs for each Task
. You can specify whether the output of one
Task
is used as an input for the next Task
using the from
property.
Pipelines
offer the same variable substitution as Tasks
.
Below is an example definition of a Pipeline
:
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: tutorial-pipeline
spec:
resources:
- name: source-repo
type: git
- name: web-image
type: image
tasks:
- name: build-skaffold-web
taskRef:
name: build-docker-image-from-git-source
params:
- name: pathToDockerFile
value: Dockerfile
- name: pathToContext
value: /workspace/docker-source/examples/microservices/leeroy-web #configure: may change according to your source
resources:
inputs:
- name: docker-source
resource: source-repo
outputs:
- name: builtImage
resource: web-image
- name: deploy-web
taskRef:
name: deploy-using-kubectl
resources:
inputs:
- name: source
resource: source-repo
- name: image
resource: web-image
from:
- build-skaffold-web
params:
- name: path
value: /workspace/source/examples/microservices/leeroy-web/kubernetes/deployment.yaml #configure: may change according to your source
- name: yamlPathToImage
value: "spec.template.spec.containers[0].image"
The above Pipeline
is referencing a Task
called deploy-using-kubectl
defined as follows:
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: deploy-using-kubectl
spec:
params:
- name: path
type: string
description: Path to the manifest to apply
- name: yamlPathToImage
type: string
description: |
The path to the image to replace in the yaml manifest (arg to yq)
resources:
inputs:
- name: source
type: git
- name: image
type: image
steps:
- name: replace-image
image: mikefarah/yq
command: ["yq"]
args:
- "w"
- "-i"
- "$(params.path)"
- "$(params.yamlPathToImage)"
- "$(resources.inputs.image.url)"
- name: run-kubectl
image: lachlanevenson/k8s-kubectl
command: ["kubectl"]
args:
- "apply"
- "-f"
- "$(params.path)"
The run-kubectl
step in the above example requires additional permissions. You must grant those
permissions to your ServiceAccount
.
First, create a new role called tutorial-role
:
kubectl create clusterrole tutorial-role \
--verb=* \
--resource=deployments,deployments.apps
Next, assign this new role to your ServiceAccount
:
kubectl create clusterrolebinding tutorial-binding \
--clusterrole=tutorial-role \
--serviceaccount=default:tutorial-service
To run your Pipeline
, instantiate it with a PipelineRun
as follows:
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: tutorial-pipeline-run-1
spec:
serviceAccountName: tutorial-service
pipelineRef:
name: tutorial-pipeline
resources:
- name: source-repo
resourceRef:
name: skaffold-git
- name: web-image
resourceRef:
name: skaffold-image-leeroy-web
The PipelineRun
automatically defines a corresponding TaskRun
for each Task
you have defined
in your Pipeline
collects the results of executing each TaskRun
. In our example, the
TaskRun
order is as follows:
tutorial-pipeline-run-1-build-skaffold-web
runsbuild-skaffold-web
, since it has nofrom
orrunAfter
clauses.tutorial-pipeline-run-1-deploy-web
runsdeploy-web
because its inputweb-image
comesfrom
build-skaffold-web
. Thus,build-skaffold-web
must run beforedeploy-web
.
Save the Task
, Pipeline
, and PipelineRun
definitions above to as YAML files and apply them using the following command:
kubectl apply -f <name-of-file.yaml>
Note: Also apply the deploy-task
or the PipelineRun
will not execute.
You can monitor the execution of your PipelineRun
in realtime as follows:
tkn pipelinerun logs tutorial-pipeline-run-1 -f
To view detailed information about your PipelineRun
, use the following command:
tkn pipelinerun describe tutorial-pipeline-run-1
The output will look similar to the following:
Name: tutorial-pipeline-run-1
Namespace: default
Pipeline Ref: tutorial-pipeline
Status
STARTED DURATION STATUS
4 hours ago 1 minute Succeeded
Resources
NAME RESOURCE REF
source-repo skaffold-git
web-image skaffold-image-leeroy-web
Params
No params
Taskruns
NAME TASK NAME STARTED DURATION STATUS
tutorial-pipeline-run-1-deploy-web-jjf2l deploy-web 4 hours ago 14 seconds Succeeded
tutorial-pipeline-run-1-build-skaffold-web-7jgjh build-skaffold-web 4 hours ago 1 minute Succeeded
The Succeeded
status indicates that your PipelineRun
completed without errors.
You can also see the statuses of the individual TaskRuns
.
This section provides guidelines for completing this tutorial on your local workstation.
Complete these prerequisites to run this tutorial locally:
-
Install the required tools.
-
Install Docker for Desktop and configure it to use six CPUs, 10 GB of RAM and 2GB of swap space.
-
Set
host.docker.local:5000
as an insecure registry with Docker for Desktop. See the Docker insecure registry documentation. for details. -
Pass
--insecure
as an argument to your Kaniko tasks so that you can push to an insecure registry. -
Run a local (insecure) Docker registry as follows:
docker run -d -p 5000:5000 --name registry-srv -e REGISTRY_STORAGE_DELETE_ENABLED=true registry:2
-
(Optional) Install a Docker registry viewer to verify the images have been pushed:
docker run -it -p 8080:8080 --name registry-web --link registry-srv -e REGISTRY_URL=http://registry-srv:5000/v2 -e REGISTRY_NAME=localhost:5000 hyper/docker-registry-web
- Verify that you can push to
host.docker.internal:5000/myregistry/<image_name>
.
You must reconfigure any image
resource definitions in your PipelineResources
as follows:
- Set the URL to
host.docker.internal:5000/myregistry/<image_name>
- Set the
KO_DOCKER_REPO
variable tolocalhost:5000/myregistry
before usingko
- Set your applications (such as deployment definitions) to push to
localhost:5000/myregistry/<image name>
.
- You can keep your logs in memory only without sending them to a logging service such as Stackdriver.
- You can deploy Elasticsearch, Beats, or Kibana locally to view logs. You can find an example configuration at https://github.com/mgreau/tekton-pipelines-elastic-tutorials.
- To learn more about obtaining logs, see Logs.
To learn more about the Tekton Pipelines entities involved in this tutorial, see the following topics:
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License.