During the section we'll install build
task, which compiles the code and pushes the image to local registry.
The build task uses buildah to build and push the image to the registry.
Before starting make sure you have the following:
- Kubernetes: kubernetes cluster up and running.
- Tekton: tekton installed.
- Go (optional): Go installed if you want to build the app locally.
- Docker (optional): Docker installed if you want to build the app locally in a container image.
- tkn: A CLI for interacting with Tekton.
Apply the following tekton task and resources:
# build task
❯ kubectl apply -f tekton/2.tasks/build-task.yaml
task.tekton.dev/build created
# tekton-tutorial git & image pipeline-resources
❯ kubectl apply -f tekton/1.resources/
pipelineresource.tekton.dev/tekton-tutorial-git created
pipelineresource.tekton.dev/tekton-tutorial-image created
List the installed tekton tasks and resources:
❯ tkn task list
NAME DESCRIPTION AGE
build build & push app 3 seconds ago
❯ tkn resource list
NAME TYPE DETAILS
tekton-tutorial-git git url: https://github.com/harbur/tekton-tutorial
tekton-tutorial-image image url: example.com/harbur/tekton-tutorial
PipelineResources in a pipeline are the set of objects that are going to be used as inputs to a Task and can be output by a Task.
There is a lot to unpack here. We'll go step-by-step and explain first how to run the code locally using go
in your machine, then compile it inside an docker image and run it as a container, and lastly we'll create some pipeline resources to represent this git repository as a registry image and trigger the build task to compile the image and push it to the local registry.
Each of the steps below are independent between each other, so if you're confortable you can skip (a) or (b) of the following steps. Step (c) is necessary to be run at least once so that a built image is ready to be deployed on next stage.
- (a) Run Go app
- (b) Run Docker image
- (c) Run Build task
(a) Run Go app
Before running the build
task, let's try to build and run the code locally first.
To run the code execute and leave it running:
go run main.go
The app is now listening to port :8080
so let's test it using curl on a separate console:
❯ curl localhost:8080/there
Hello
(b) Run Docker image
To build the docker image run:
❯ docker build -t tekton-tutorial .
Sending build context to Docker daemon 364.5kB
Step 1/7 : FROM golang:1.14.2-alpine AS build
1.14.2-alpine: Pulling from library/golang
cbdbe7a5bc2a: Pull complete
408f87550127: Pull complete
fe522b08c979: Pull complete
618fff1cf170: Pull complete
0d8b518583db: Pull complete
Digest: sha256:9b3ad7928626126b72b916609ad081cfb6c0149f6e60cef7fc1e9e15a0d1e973
Status: Downloaded newer image for golang:1.14.2-alpine
---> dda4232b2bd5
Step 2/7 : COPY main.go .
---> 80e4093a0f0d
Step 3/7 : RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
---> Running in 35f01c2a39c3
Removing intermediate container 35f01c2a39c3
---> f31a08a3c7e4
Step 4/7 : FROM scratch
--->
Step 5/7 : COPY --from=build /go/app /bin/
---> f2001138dd15
Step 6/7 : EXPOSE 8080
---> Running in 0db12d023d6d
Removing intermediate container 0db12d023d6d
---> 94128d6b2222
Step 7/7 : CMD ["app"]
---> Running in fdb272576f2c
Removing intermediate container fdb272576f2c
---> ff7bfe39b3d9
Successfully built ff7bfe39b3d9
Successfully tagged tekton-tutorial:latest
Run the container and test it with curl
on port 8080
:
# Run tekton-tutorial
❯ docker run --name tekton-tutorial -dp 8080:8080 tekton-tutorial
8abc5b4fb9a5c86c4e0e225317977cac424699cdb3133c098e3cc32936a550bc
# test it
❯ curl localhost:8080/there
Hello
# tear-down
❯ docker rm -f tekton-tutorial
Note that the Dockerfile is using multistage build so that the final image doesn't include the source code and build tools (more specifically it uses empty scratch base image since go can be statically built).
(c) Run Build task
Let's start the build task:
❯ tkn task start build
? Choose the git resource to use for source: tekton-tutorial-git (https://github.com/harbur/tekton-tutorial#main)
? Choose the image resource to use for builtImage: tekton-tutorial-image (example.com/harbur/tekton-tutorial)
? Value for param `contextDir` of type `string`? (Default is `.`) .
? Value for param `destinationImage` of type `string`? (Default is `$(outputs.resources.builtImage.url)`) $(outputs.resources.builtImage.url)
? Value for param `dockerFile` of type `string`? (Default is `Dockerfile`) Dockerfile
? Value for param `tlsVerify` of type `string`? (Default is `false`) false
TaskRun started: build-run-55rvb
In order to track the TaskRun progress run:
tkn taskrun logs build-run-55rvb -f -n default
It prompts you to choose parameter values, continue with the defaults and wait for the pod to start (First run may take a minute or so to download the image):
❯ kubectl get pod -w
NAME READY STATUS RESTARTS AGE
build-run-55rvb-pod-hptkw 0/5 PodInitializing 0 51s
Check the logs of the TaskRun to see the progress of the compilation:
❯ tkn taskrun logs -L -f
[git-source-source-nbm56] {"level":"info","ts":1611575486.87084,"caller":"git/git.go:165","msg":"Successfully cloned https://github.com/harbur/tekton-tutorial @ 7000f44dee568bfff166360e1a9bdf5b9f6d2790 (grafted, HEAD, origin/main) in path /workspace/source"}
[git-source-source-nbm56] {"level":"info","ts":1611575486.9887836,"caller":"git/git.go:203","msg":"Successfully initialized and updated submodules in path /workspace/source"}
[build-image] STEP 1: FROM golang:1.14.2-alpine AS build
[build-image] Completed short name "golang" with unqualified-search registries (origin: /etc/containers/registries.conf)
[build-image] Getting image source signatures
[build-image] Copying blob sha256:cbdbe7a5bc2a134ca8ec91be58565ec07d037386d1f1d8385412d224deafca08
[build-image] Copying blob sha256:0d8b518583db0dc830a3a43c739d6cc91b7610c09d9eba918ae54b20a1dcd18c
[build-image] Copying blob sha256:fe522b08c9798748151fec9b7a908aca712cd102cfcbb8ed79d57d05b71e6cc4
[build-image] Copying blob sha256:618fff1cf170e1785ab64028237182717bc1e1287d03cf0888e424b7563ae5df
[build-image] Copying blob sha256:408f875501273f3af2a9cbff2a23e736585641e73da80dd81712518b28e7843c
[build-image] Copying config sha256:dda4232b2bd580bbf633be12d62e8d0e00f6b7bd60ea6faee157bad1809c53c4
[build-image] Writing manifest to image destination
[build-image] Storing signatures
[build-image] STEP 2: COPY main.go .
[build-image] --> 6e1697caffd
[build-image] STEP 3: RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
[build-image] --> 55e22e2278c
[build-image] STEP 4: FROM scratch
[build-image] STEP 5: COPY --from=build /go/app /bin/
[build-image] --> f59a8f6fe9b
[build-image] STEP 6: EXPOSE 8080
[build-image] --> 5b57d9eaa58
[build-image] STEP 7: CMD ["app"]
[build-image] STEP 8: COMMIT example.com/harbur/tekton-tutorial
[build-image] --> bac5a87e870
[build-image] bac5a87e870b9ae2ab1684c55a032b084f8b5eac90754339aceaa08b1e53b6a0
[push-image] Getting image source signatures
[push-image] Copying blob sha256:f8ae64caa97c1fe2b8e29d76b9f89caf17f81112b65ff4ab891f2a2b9a891113
[push-image] Copying config sha256:bac5a87e870b9ae2ab1684c55a032b084f8b5eac90754339aceaa08b1e53b6a0
[push-image] Writing manifest to image destination
[push-image] Storing signatures
[image-digest-exporter-9lpxd] {"severity":"INFO","timestamp":"2021-01-25T11:52:56.258420557Z","caller":"logging/config.go:115","message":"Successfully created the logger.","logging.googleapis.com/labels":{},"logging.googleapis.com/sourceLocation":{"file":"github.com/tektoncd/pipeline/vendor/knative.dev/pkg/logging/config.go","line":"115","function":"github.com/tektoncd/pipeline/vendor/knative.dev/pkg/logging.newLoggerFromConfig"}}
[image-digest-exporter-9lpxd] {"severity":"INFO","timestamp":"2021-01-25T11:52:56.258726744Z","caller":"logging/config.go:116","message":"Logging level set to: info","logging.googleapis.com/labels":{},"logging.googleapis.com/sourceLocation":{"file":"github.com/tektoncd/pipeline/vendor/knative.dev/pkg/logging/config.go","line":"116","function":"github.com/tektoncd/pipeline/vendor/knative.dev/pkg/logging.newLoggerFromConfig"}}
[image-digest-exporter-9lpxd] {"severity":"INFO","timestamp":"2021-01-25T11:52:56.264141916Z","caller":"imagedigestexporter/main.go:59","message":"No index.json found for: builtImage","commit":"95144d9","logging.googleapis.com/labels":{},"logging.googleapis.com/sourceLocation":{"file":"github.com/tektoncd/pipeline/cmd/imagedigestexporter/main.go","line":"59","function":"main.main"}}
Check the status of the TaskRuns:
❯ tkn taskrun list
NAME STARTED DURATION STATUS
build-run-55rvb 7 minutes ago 2 minutes Succeeded
Check more details of build
Task:
❯ tkn task describe build
Name: build
Namespace: default
Description: build & push app
📨 Input Resources
NAME TYPE
∙ source git
📡 Output Resources
NAME TYPE
∙ builtImage image
⚓ Params
NAME TYPE DESCRIPTION DEFAULT VALUE
∙ contextDir string the context dir wit... .
∙ destinationImage string the fully qualified... $(outputs.resources.builtImage.url)
∙ dockerFile string the docker file to ... Dockerfile
∙ tlsVerify string tls verify false
📝 Results
No results
📂 Workspaces
No workspaces
🦶 Steps
∙ build-image
∙ push-image
🗂 Taskruns
NAME STARTED DURATION STATUS
build-run-dhxx4 3 minutes ago 1 minute Succeeded
If you want to learn more about the steps involved in this section, here are some interesting references:
- Tour of Go: A Tour of Go
- Docker Tutorial: Docker 101 Tutorial
- Docker Multi-Stage Build: Use multi-stage builds
Once build task is installed, see the Install Deploy Task tutorial.
If you want to tear down the build task:
# Delete tekton pipelineresources
kubectl delete -f tekton/1.resources/
# Delete tekton build task
kubectl delete -f tekton/2.tasks/build-task.yaml