What is Tekton
Tekton is an open-source project from the Continuous Delivery Foundation for creating CI/CD systems from
You might wonder what is the difference with Jenkins, in shorts Jenkins is more like "stateful" (Jenkins can be stateless with Kubernetes plugins) and Tekton is "stateless"
Comparison tables above are taken from OpenShift
Installation
Assume you have a Kubernetes cluster and kubectl installed
Install tekton, dashboard and optionally cli
Preview dashboard with the following command
kubectl --namespace tekton-pipelines port-forward svc/tekton-dashboard 9097:9097
Run sample task
With Tekton, each operation in your CI/CD workflow becomes a Step, which is executed with a container image you specify. Steps are then organized in Tasks, which run as a Kubernetes pod in your cluster. You can further organize Tasks into Pipelines, which can control the order of execution of several Tasks.
Create a file named task-hello.yaml
, it specifies a Task with one simple Step, which prints a Hello World! message using the official Ubuntu image
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: hello
spec:
steps:
- name: hello
image: ubuntu
command:
- echo
args:
- "Hello World!"
To run this task with Tekton, you need to create a TaskRun, which is another Kubernetes object used to specify run-time information for a Task.
Create a file named task-hello-run.yaml
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
generateName: hello-run-
spec:
taskRef:
name: hello
Run the task, and view it on the dashboard
kubectl apply -f task-hello.yaml
kubectl create -f task-hello-run.yaml
Tekton Hub
Tasks and Pipelines can be reused, a handful of command Tasks and Pipelines like git clone, docker build and etc can be found on Tekton Hub
Build your own pipeline
A Pipeline is a collection of Tasks that you define and arrange in a specific order of execution as part of your continuous integration flow. Each Task in a Pipeline executes as a Pod on your Kubernetes cluster. You can configure various execution conditions to fit your business needs
We will build a Pipeline that builds the Go program into a Docker image, and push it to the registry
Complete source code can be found on cncf-demo/hello-word
hello-world sample without auth
Install the following Tasks from the Tekton hub
tkn hub install task git-clone
tkn hub install task kaniko
Examine pipeline.yaml
, which contains two steps
- Clone the project with
git-clone
task that we installed above - Build an image with Kaniko, without pushing to registry (
--no-push
)
Tekton Tasks are executed in parallel, use runAfter to execute in a specific order within the Pipeline
...
workspaces:
- name: git-source # attach a volume to store source code
params:
- name: git_revision # from PipelineRun
tasks:
- name: fetch-from-git # first task, clone project
taskRef:
name: git-clone # using git-clone task that we installed from the Tekton hub
params:
- name: url
value: https://github.com/WLun001/cncf-demo
- name: revision
value: $(params.git_revision) # refers from PipelineRun
workspaces:
- name: output
workspace: git-source
- name: build-image # second task, build an image
runAfter: [ fetch-from-git ] # to run after first task
taskRef:
name: kaniko # using kaniko task that we installed from Tekton hub
params:
- name: IMAGE
value: ghcr.io/wlun001/hello-world # replace with your own registry
- name: CONTEXT
value: examples/hello-world
- name: DOCKERFILE
value: $(workspaces.source.path)/examples/hello-world/Dockerfile
- name: EXTRA_ARGS
value: ['--no-push'] # only build the image, without pushing to a registry.
workspaces:
- name: source
workspace: git-source
And pipeline-run.yaml
to run the pipeline
...
pipelineRef:
name: kaniko-pipeline # refer to the pipeline above
params:
- name: git_revision
value: HEAD
workspaces:
- name: git-source
volumeClaimTemplate: # create volume claim
spec:
accessModes:
- ReadWriteOnce # access mode may affect how you can use this volume in parallel tasks
resources:
requests:
storage: 100m
Create Pipeline and PipelineRun
kubectl apply -f pipeline.yaml
kubectl create -f pipeline-run.yaml
The output should be visible on the dashboard. We have created a Pipeline that clone and build an image
hello-world sample with auth
Most of the time we will need to access the private git repository and registry, we will continue to enhance the Pipeline with authentication
Add registry credentials
Get your docker registry user and password encoded in base64
echo -n USER:ACCESS_TOKEN | base64
Create a config.json
file with your Docker registry URL and the generated base64 string
{
"auths": {
"ghcr.io": {
"auth": "XXXXXX"
}
}
}
Create registry secret
kubectl create secret generic kaniko-secret --from-file=config.json
Add git ssh credentials
git-clone
supports multiple ways of authentication, we only show ssh credentials, more refer to git-clone
Replace the values by running the command in the comment
kind: Secret
apiVersion: v1
metadata:
name: ssh-credentials
type: Opaque
stringData:
# ssh-keygen -t ed25519 -C "example.com"
# cat id_ed25519
id_ed25519: |
XXXXXX
# ssh-keyscan github.com >> githubKey
# cat githubkey
known_hosts: |
XXXXX
config: |
IdentityFile ~/.ssh/id_ed25519
And add the SSH key to Git service, for example Github
Use secrets in Pipeline
Add credentials to related Tasks by attaching Workspace
...
workspaces:
- name: git-source
- name: ssh-creds # git credentials
- name: dockerconfig # registry credentials
tasks:
- name: fetch-from-git
...
workspaces:
- name: output
workspace: git-source
- name: ssh-directory # need git credentials to clone
workspace: ssh-creds
- name: build-image
...
workspaces:
- name: source
workspace: git-source
- name: dockerconfig # registry credentials to push
workspace: dockerconfig
And PipelineRun will get the secret, and attached as Workspace
...
spec:
pipelineRef:
name: kaniko-pipeline
workspaces:
...
- name: ssh-creds
secret:
secretName: ssh-credentials # refer to the secret
- name: dockerconfig
secret:
secretName: kaniko-secret # refer to the secret
Create the Pipeline and execute it
kubectl apply -f pipeline.yaml
kubectl create -f pipeline-run.yaml
View the build logs on the dashboard, it should push to the registry after building the image
Conclusion
We have built Pipelines that can build images and push them to the registry. Next, we will look at Triggers, which will automatically run the Pipelines when events occur, for example, the git push event.