Tekton Lab
Pre-requisites¶
Make sure your environment is properly setup.
Check the Environment Setup page for your setup.
Create Target Namespace¶
- Set the environment variable
NAMESPACE
totekton-demo-{initials}
, if you open a new terminal remember to set this environment againexport NAMESPACE=tekton-demo-{initials}
- Create the namespace using the variable
NAMESPACE
oc create namespace $NAMESPACE
Pipeline Resources¶
Pipeline Resource Creation¶
Create a PipelineResource of type git
¶
- Create the file git.yaml Verify the file content
apiVersion: tekton.dev/v1alpha1 kind: PipelineResource metadata: name: source spec: type: git params: - name: revision value: master - name: url value: https://github.com/ibm-cloud-architecture/cloudnative_sample_app
cat git.yaml
Create a PipelineResource of type image
¶
- Set the environment variable
DOCKER_USERNAME
to your dockerhub account, replace<REPLACEME>
with your docker username, keep the quotesexport DOCKER_USERNAME='<REPLACEME>'
- Create the file image.yaml Verify the file content, and make sure the
apiVersion: tekton.dev/v1alpha1 kind: PipelineResource metadata: name: image spec: type: image params: - name: url value: index.docker.io/$DOCKER_USERNAME/cloudnative_sample_app
url
value is valid with your dockerhub username replacedcat image.yaml
Pipeline Resources deployment¶
- Each pipeline resource has:
- name: the name using which it will be referred in other places
- type: the type of the pipeline resource, in this example we have two types
- git - this type of resource refers to a GitHub repository
- image - this type of resource is linux container image
-
params: each type can have one or more parameters that will be used to configure the underlying type. In the above example for the git-source pipeline resource, the parameters url and revision are used to identify the GitHub repository url and revision of the sources respectively.
-
More details on other types of pipeline resource types is available here.
-
Create the pipeline resources using the command:
oc apply -f git.yaml -n $NAMESPACE oc apply -f image.yaml -n $NAMESPACE
Verify the deployed resource¶
-
Use the Tekton cli to list the created resources
tkn res ls -n $NAMESPACE
-
The above command should list two resources as shown below:
Use the command help viaNAME TYPE DETAILS source git url: https://github.com/ibm-cloud-architecture/cloudnative_sample_app image image url: index.docker.io/yourdockerhubusername/cloudnative_sample_app
tkn res --help
- Use the Tekton cli to describe the git resource The output should look like this:
tkn res describe source -n $NAMESPACE
Name: source Namespace: tekton-demo PipelineResource Type: git Params NAME VALUE revision master url https://github.com/ibm-cloud-architecture/cloudnative_sample_app Secret Params No secret params
- Use the Tekton cli to describe the git resource The output should look like this:
tkn res describe image -n $NAMESPACE
Name: image Namespace: tekton-demo PipelineResource Type: image Params NAME VALUE url index.docker.io/myusername/cloudnative_sample_app Secret Params No secret params
Tasks¶
Task Creation¶
- Create the below yaml files.
- The following snippet shows what a Tekton Task YAML looks like:
-
Create the file test_task.yaml
apiVersion: tekton.dev/v1alpha1 kind: Task metadata: name: java-test spec: inputs: resources: - name: source type: git params: - name: maven-image type: string default: maven:3.3-jdk-8 steps: - name: test image: $(inputs.params.maven-image) workingdir: $(inputs.resources.source.path) command: ["/bin/bash"] args: - -c - | set -e mvn test echo "tests passed with rc=$?" volumeMounts: - name: m2-repository mountPath: /.m2 volumes: - name: m2-repository emptyDir: {}
-
Each Task has the following:
-
name - the unique name using which the task can be referred
- inputs - the inputs to the task
- resources - the pipeline resources that will be used in the task e.g. git-source
- name - the name of the input resource using which it can be referenced and bound via TaskRun
- type - the type of the input resource, typically the pipeline resource type
- params - the parameters that will be used in the task steps. Each parameter has
- name - the name of the parameter
- description - the description of the parameter
-
default - the default value of parameter
-
Note: The
TaskRun
orPipelineRun
could override the parameter values, if no parameter value is passed then the default value will be used. -
outputs the pipeline resource that will end artifact of the task. In the above example the build will produce a container image artifact.
- resources - the pipeline resources that will be used in the task e.g. builtImage
- name - the name of the input resource using which it can be referenced and bound via TaskRun
- type - the type of the input resource, typically the pipeline resource type
- steps - One or more sub-tasks that will be executed in the defined order. The step has all the attributes like a Pod spec
- stepTemplate - when there is a need to have similar container configuration across all steps of a the task, we can have them defined in the stepTemplate, the task steps will inherit them implicitly in all steps. In the example above we define the resources and securityContext for all the steps
-
volumes - the task can also mount external volumes using the volumes attribute.
-
The parameters that were part of the spec inputs params can be used in the steps using the notation
$(<variable-name>)
.
Task Deploy¶
-
The application test task could be created using the command:
oc apply -f test_task.yaml -n $NAMESPACE
-
We will use the Tekton cli to inspect the created resources
tkn task ls -n $NAMESPACE
-
The above command should list one Task as shown below:
NAME AGE java-test 22 seconds ago
TaskRun¶
- The TaskRun is used to run a specific task independently. In the following section we will run the build-app task created in the previous step
TaskRun Creation¶
- The following snippet shows what a Tekton TaskRun YAML looks like:
- Create the file test_taskrun.yaml
apiVersion: tekton.dev/v1alpha1 kind: TaskRun metadata: generateName: test-task-run- spec: taskRef: name: java-test inputs: resources: - name: source resourceRef: name: source
- generateName - since the TaskRun can be run many times, in order to have unique name across the TaskRun ( helpful when checking the TaskRun history) we use this generateName instead of name. When Kubernetes sees generateName it will generate unique set of characters and suffix the same to build-app-, similar to how pod names are generated
- taskRef - this is used to refer to the Task by its name that will be run as part of this TaskRun. In this example we use build-app Task.
- As described in the earlier section that the Task inputs and outputs could be overridden via TaskRun.
- In this example we make the Task Run
spec > inputs > resources > source
to refer to pipeline resourcesource
via theresourceRef
. - The application test task(java-maven-test) could be run using the command:
oc create -n $NAMESPACE -f test_taskrun.yaml
- Note - As tasks will use generated name, never use
oc apply -f test_taskrun.yaml
-
We will use the Tekton cli to inspect the created resources:
The above command should list one TaskRun as shown below:tkn tr ls -n $NAMESPACE
Note - It will take few seconds for the TaskRun to show status as Running as it needs to download the container images.NAME STARTED DURATION STATUS test-task-run-q6s8c 1 minute ago --- Running(Pending)
-
To check the logs of the Task Run using the
tkn
:Note - Each task step will be run within a container of its own. The -f or -a allows to tail the logs from all the containers of the task. For more options runtkn tr logs -f -a -n $NAMESPACE
tkn tr logs --help
- If you see the TaskRun status as Failed or Error use the following command to check the reason for error:
tkn tr describe <taskrun-name> -n $NAMESPACE
- If it is successful, you will see something like below. The above command should list one TaskRun as shown below:
tkn tr ls -n $NAMESPACE
NAME STARTED DURATION STATUS test-task-run-q6s8c 47 seconds ago 34 seconds Succeeded
Creating additional tasks and deploying them¶
- Create a Task to build a container image and push to the registry
- This task will be later used by the pipeline.
- Download the task file task-buildah.yaml to build the image, push the image to the registry:
- Create the
buildah
Task using the file and the command:oc apply -f task-buildah.yaml -n $NAMESPACE
- Use the Tekton cli to inspect the created resources
tkn task ls -n $NAMESPACE
-
The above command should list one Task as shown below:
NAME AGE buildah 4 seconds ago java-test 46 minutes ago
-
To access the docker registry, create the required secret as follows.
- Create the environment variables to be use, replace with real values and include the single quotes:
export DOCKER_USERNAME='<DOCKER_USERNAME>'
export DOCKER_PASSWORD='<DOCKER_PASSWORD>'
export DOCKER_EMAIL='<DOCKER_EMAIL>'
-
Run the following command to create a secret
regcred
in the namespaceNAMESPACE
Before creating, replace the values as mentioned above. Note: If your docker password contains special characters in it, please enclose the password in double quotes or place an escape character before each special character.oc create secret docker-registry regcred \ --docker-server=https://index.docker.io/v1/ \ --docker-username=${DOCKER_USERNAME} \ --docker-password=${DOCKER_PASSWORD} \ --docker-email=${DOCKER_EMAIL} \ -n ${NAMESPACE}
-
(Optional) Only if you have problems with the credentials you can recreate it, but you have to deleted first
oc delete secret regcred -n $NAMESPACE
- Before we run the Task using TaskRun let us create the Kubernetes service account and attach the needed permissions to the service account, the following Kubernetes resource defines a service account called
pipeline
in namespace$NAMESPACE
who will have administrative role within the$NAMESPACE
namespace. - Create the file sa.yaml
apiVersion: v1 kind: ServiceAccount metadata: name: pipeline secrets: - name: regcred
-
Create sa role as follows:
oc apply -n $NAMESPACE -f sa.yaml
-
Lets create a Task Run for
buildah
Task using thetkn
CLI passing the inputs, outputs and service accountThe task will start and logs will start printing automaticallytkn task start buildah \ -i source=source \ -i image=image \ -s pipeline \ -n $NAMESPACE
Taskrun started: buildah-run-vvrg2 Waiting for logs to be available...
-
Verify the status of the Task Run
Output should look like thistkn tr ls -n $NAMESPACE
NAME STARTED DURATION STATUS buildah-run-zbsrv 2 minutes ago 1 minute Succeeded
- To clean up all Pods associated with all Task Runs, delete all the task runs resources
oc delete taskrun --all -n $NAMESPACE
- (Optional) Instead of starting the Task via
tkn task start
you could also use yaml TaskRunThen create the TaskRun withapiVersion: tekton.dev/v1alpha1 kind: TaskRun metadata: generateName: buildah-task-run- spec: serviceAccountName: pipeline taskRef: name: buildah inputs: resources: - name: source resourceRef: name: source - name: image resourceRef: name: image
generateName
Follow the logs with:oc create -f taskrun.yaml -n $NAMESPACE
tkn tr logs -f -n $NAMESPACE
Pipelines¶
Pipeline Creation¶
-
Pipelines allows to start multiple Tasks, in parallel or in a certain order
-
Create the file pipeline.yaml, the Pipeline contains two Tasks
apiVersion: tekton.dev/v1alpha1 kind: Pipeline metadata: name: test-build-push spec: resources: - name: source type: git - name: image type: image tasks: - name: test taskRef: name: java-test resources: inputs: - name: source resource: source - name: build-push taskRef: name: buildah runAfter: [test] resources: inputs: - name: source resource: source - name: image resource: image
-
Pipeline defines a list of Tasks to execute in order, while also indicating if any outputs should be used as inputs of a following Task by using the from field and also indicating the order of executing (using the runAfter and from fields). The same variable substitution you used in Tasks is also available in a Pipeline.
- Create the Pipeline using the command:
oc apply -f pipeline.yaml -n $NAMESPACE
- Use the Tekton cli to inspect the created resources The above command should list one Pipeline as shown below:
tkn pipeline ls -n $NAMESPACE
NAME AGE LAST RUN STARTED DURATION STATUS test-build-push 31 seconds ago --- --- --- ---
PipelineRun¶
PipelineRun Creation¶
- To execute the Tasks in the Pipeline, you must create a PipelineRun. Creation of a PipelineRun will trigger the creation of TaskRuns for each Task in your pipeline.
- Create the file pipelinerun.yaml serviceAccount - it is always recommended to have a service account associated with PipelineRun, which can then be used to define fine grained roles.
apiVersion: tekton.dev/v1alpha1 kind: PipelineRun metadata: generateName: test-build-push-run- spec: serviceAccountName: pipeline pipelineRef: name: test-build-push serviceAccountName: pipeline resources: - name: source resourceRef: name: source - name: image resourceRef: name: image
- Create the PipelineRun using the command:
oc create -f pipelinerun.yaml -n $NAMESPACE
-
We will use the Tekton cli to inspect the created resources
tkn pipelinerun ls -n $NAMESPACE
-
The above command should list one PipelineRun as shown below:
NAME STARTED DURATION STATUS test-build-push-run-c7zgv 8 seconds ago --- Running
-
Wait for few minutes for your pipeline to complete all the tasks. If it is successful, you will see something like below.
tkn pipeline ls -n $NAMESPACE
NAME AGE LAST RUN STARTED DURATION STATUS test-build-push 33 minutes ago test-build-push-run-c7zgv 2 minutes ago 2 minutes Succeeded
-
Run again the pipeline ls command
tkn pipelinerun ls -n $NAMESPACE
If it is successful, go to your container registry account and verify if you have theNAME STARTED DURATION STATUS test-build-push-run-c7zgv 2 minutes ago 2 minutes Succeeded
cloudnative_sample_app
image pushed. -
(Optional) Run the pipeline again using the
tkn
CLItkn pipeline start test-build-push \ -r source=source \ -r image=image \ -s pipeline \ -n $NAMESPACE
- (Optional) Re-run the pipeline using last pipelinerun values
tkn pipeline start test-build-push --last -n $NAMESPACE
Deploy Application¶
- Deploy the app as follows:
export APP_YAML_URL='https://raw.githubusercontent.com/ibm-cloud-architecture/cloudnative_sample_app_deploy/master/yamls/' oc apply -n $NAMESPACE -f $APP_YAML_URL/deployment.yaml oc apply -n $NAMESPACE -f $APP_YAML_URL/service.yaml
- Replace the default image with the new image you deployed using Tekton
- Replace
<DOCKER_USERNAME>
with your usernameexport DOCKER_USERNAME='<DOCKER_USERNAME>'
- Replace
<SHORT_GIT_HASH>
with the tag of the image you push to the registry, you can go the registry Web UI and verify the tag value.export SHORT_GIT_HASH='<SHORT_GIT_HASH>'
- Set the environment variable
IMAGE_URL
to the new image url value sing the two previous environment variablesDOCKER_USERNAME
andSHORT_GIT_HASH
export IMAGE_URL=docker.io/${DOCKER_USERNAME}/cloudnative_sample_app:${SHORT_GIT_HASH} echo $IMAGE_URL
- Replace the image on the deployment
oc set image \ deployment/cloudnativesampleapp-deployment \ \*=${IMAGE_URL} \ -n $NAMESPACE --record
- Verify the image is set
oc get deploy \ cloudnativesampleapp-deployment \ -o jsonpath='{.spec.template.spec.containers[0].image}' \ -n $NAMESPACE
- Verify if the pods are running:
oc get pods -n $NAMESPACE -l app=cloudnativesampleapp-selector
NAME READY STATUS RESTARTS AGE cloudnativesampleapp... 1/1 Running 0 82s
- Retrieve the service NodePort:
oc describe svc cloudnativesampleapp-service -n $NAMESPACE | grep NodePort
In this instance the NodePort assigned isType: NodePort NodePort: http 30632/TCP
30632
- Get the External Public IP as follows:
crc ip
192.168.64.30
- Now access the compose the URL of the App using IP and NodePort
export APP_EXTERNAL_IP=$(crc ip) export APP_NODEPORT=$(oc get svc cloudnativesampleapp-service -n $NAMESPACE -o jsonpath='{.spec.ports[0].nodePort}') export APP_URL="http://${APP_EXTERNAL_IP}:${APP_NODEPORT}/greeting?name=Carlos" echo $APP_URL
http://192.168.64.30:30632//greeting?name=Carlos
- Now access the app from terminal or browser
curl $APP_URL
open $APP_URL