tekton notes

run my own ci...?

SEAN K.H. LIAO

tekton notes

run my own ci...?

tekton pipelines

Tekton sits somewhere on the spectrum between a building block and a product of a CI system. Or maybe not a CI system, a generalized graph of arbitrary code execution.

cloud build

There was a build task I wanted to move over from Google Cloud Build: a nightly build of Go (plus some extra tools). This was setup as a Dockerfile in a git repo subdirectory, a Cloud Build config file, and a Google Cloud Scheduler to trigger the build.

Dockerfile:

 1FROM golang:alpine AS build
 2ENV CGO_ENABLED=0 \
 3    GOFLAGS=-trimpath
 4RUN apk add --no-cache bash curl gcc git musl-dev && \
 5    go install golang.org/dl/gotip@latest && \
 6    gotip download && \
 7    rm -rf /root/sdk/gotip/pkg/linux_* && \
 8    curl -Lo /usr/local/bin/skaffold https://storage.googleapis.com/skaffold/builds/latest/skaffold-linux-amd64 && \
 9    chmod +x /usr/local/bin/skaffold
10
11FROM alpine
12RUN apk add --no-cache git
13ENV CGO_ENABLED=0 \
14    GOFLAGS=-trimpath
15ENV PATH=/root/sdk/gotip/bin:/root/go/bin:$PATH
16COPY --from=build /usr/local/bin/skaffold /usr/local/bin/skaffold
17COPY --from=build /root/sdk/gotip /root/sdk/gotip
18WORKDIR /workspace
19ENTRYPOINT [ "go" ]

cloudbuild.yaml:

 1steps:
 2  - id: build-push-gotip
 3    name: "gcr.io/kaniko-project/executor"
 4    args:
 5      - "--context=gotip"
 6      - "--destination=${_REGISTRY}/gotip:latest"
 7      - "--image-name-with-digest-file=.image.gotip.txt"
 8      - "--reproducible"
 9      - "--single-snapshot"
10      - "--snapshot-mode=redo"
11      - "--ignore-var-run"
12
13  - id: sign-gotip
14    name: "gcr.io/projectsigstore/cosign"
15    entrypoint: sh
16    env:
17      - "TUF_ROOT=/tmp" # cosign tries to create $HOME/.sigstore
18      - "COSIGN_EXPERIMENTAL=1"
19      - "GOOGLE_SERVICE_ACCOUNT_NAME=cosign-signer@com-seankhliao.iam.gserviceaccount.com"
20    args:
21      - "-c"
22      - "cosign sign --force $(head -n 1 .image.gotip.txt)"
23
24substitutions:
25  _REGISTRY: us-central1-docker.pkg.dev/com-seankhliao/build
26
27options:
28  env:
29    - GOGC=400
30
31timeout: "1800s" # 30m gotip build is slow

tekton build

Moving over to Tekton, I went with inlining the entire build config into a TriggerTemplate. No more cloning a repo first just for a file. I think I could have done this with Cloud Build too, but I haven't been consistent in managing my config as code consistently...

 1apiVersion: triggers.tekton.dev/v1beta1
 2kind: TriggerTemplate
 3metadata:
 4  name: gotip-trigger
 5spec:
 6  resourcetemplates:
 7    - apiVersion: tekton.dev/v1beta1
 8      kind: TaskRun
 9      metadata:
10        generateName: build-gotip-tr-
11      spec:
12        taskSpec:
13          params:
14            - name: image-ref
15              type: string
16              default: us-central1-docker.pkg.dev/com-seankhliao/build/gotip:latest
17          results:
18            - name: image-digest
19          steps:
20            - name: write-dockerfile
21              image: busybox
22              script: |
23                cat << EOF > /workspace/src/Dockerfile
24                FROM golang:alpine AS build
25                ENV CGO_ENABLED=0 \
26                    GOFLAGS=-trimpath
27                RUN apk add --no-cache bash curl gcc git musl-dev && \
28                    go install golang.org/dl/gotip@latest && \
29                    gotip download && \
30                    rm -rf /root/sdk/gotip/pkg/linux_* && \
31                    curl -Lo /usr/local/bin/skaffold https://storage.googleapis.com/skaffold/builds/latest/skaffold-linux-amd64 && \
32                    chmod +x /usr/local/bin/skaffold
33
34                FROM alpine
35                RUN apk add --no-cache git
36                ENV CGO_ENABLED=0 \
37                    GOFLAGS=-trimpath
38                ENV PATH=/root/sdk/gotip/bin:/root/go/bin:$PATH
39                COPY --from=build /usr/local/bin/skaffold /usr/local/bin/skaffold
40                COPY --from=build /root/sdk/gotip /root/sdk/gotip
41                WORKDIR /workspace
42                ENTRYPOINT [ "go" ]
43                EOF                
44              volumeMounts:
45                - name: src
46                  mountPath: /workspace/src
47            - name: build-gotip
48              image: "gcr.io/kaniko-project/executor"
49              args:
50                - "--context=/workspace/src"
51                - "--destination=$(params.image-ref)"
52                - "--image-name-with-digest-file=$(results.image-digest.path)"
53                - "--reproducible"
54                - "--single-snapshot"
55                - "--snapshot-mode=redo"
56                - "--ignore-var-run"
57                - "--ignore-path=/product_uuid" # kind specific? https://github.com/GoogleContainerTools/kaniko/issues/2164
58              volumeMounts:
59                - name: src
60                  mountPath: /workspace/src
61                - name: docker-auth
62                  mountPath: /kaniko/.docker/config.json
63                  subPath: .dockerconfigjson
64          volumes:
65            - name: src
66              emptyDir: {}
67            - name: docker-auth
68              secret:
69                secretName: gcp-ar-docker

Next up, an EventListener to turn HTTP requests into TaskRuns:

 1apiVersion: triggers.tekton.dev/v1beta1
 2kind: EventListener
 3metadata:
 4  name: gotip-event
 5spec:
 6  serviceAccountName: tekton-triggers
 7  triggers:
 8    - name: default
 9      template:
10        ref: gotip-trigger

And a CronJob to make the HTTP requests:

 1apiVersion: batch/v1
 2kind: CronJob
 3metadata:
 4  name: trigger-gotip
 5spec:
 6  schedule: "*/30 * * * *"
 7  jobTemplate:
 8    spec:
 9      template:
10        spec:
11          containers:
12            - name: trigger
13              image: curlimages/curl:latest
14              args:
15                - --data
16                - "{}"
17                - http://el-gotip-event.default.svc.cluster.local:8080
18          restartPolicy: OnFailure