Tekton
Tekton CI/CD 스터디를 위해서 환경 구축을 해보았다.
결론은 사용측면에서는 jenkins나 gitAction이 쉽다.
https://tekton.dev/docs/installation

Tekton 배포
kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
Tekton-Dashboard
kubectl apply --filename https://storage.googleapis.com/tekton-releases/dashboard/latest/release.yaml
Dashbaord는 초기에 read-only로 배포되어있다. 설치전에 변경하던가 설치하고 수정한다.
spec:
containers:
- args:
- --default-namespace=
- --external-logs=
- --log-format=json
- --log-level=info
- --logout-url=
- --namespaces=
- --pipelines-namespace=tekton-pipelines
- --port=9097
# - --read-only=true
- --read-only=false
- --stream-logs=true
- --triggers-namespace=tekton-pipelines
Dashboard ingress
kubectl create secret tls ssl-common --cert ./chain.pem --key ./tk8s.test.key -n tekton-pipelines
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
name: tekton-pipelines-ing
namespace: tekton-pipelines
spec:
ingressClassName: nginx
rules:
- host: tek.tk8s.test
http:
paths:
- backend:
service:
name: tekton-dashboard
port:
number: 9097
path: /
pathType: Prefix
tls:
- hosts:
- tek.tk8s.test
secretName: ssl-common
Tekton-triggers 배포
kubectl apply --filename \
https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml
kubectl apply --filename \
https://storage.googleapis.com/tekton-releases/triggers/latest/interceptors.yaml
kubectl create clusterrolebinding tekton-dashboard-clustertask \
--clusterrole=cluster-admin \
--serviceaccount=tekton-pipelines:tekton-dashboard
kubectl rollout restart deployment tekton-dashboard -n tekton-pipelines
chrome 사설인증서 신뢰할수있는 인증서 등록
Ubuntu Desktop chrome에 추가.
chrome://certificate-manager/localcerts/usercerts
Tekton Simple Test
demo 테스트를 해보자
kubectl create ns tekton-demo
Task 배포
# hello-task.yaml
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: hello-task
namespace: tekton-demo
spec:
steps:
- name: echo-hello
image: ubuntu
script: |
#!/bin/bash
echo "✅ Hello from Tekton Task!"

Sample Pipeline
# hello-pipeline.yaml
apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
name: hello-pipeline
namespace: tekton-demo
spec:
tasks:
- name: run-hello
taskRef:
name: hello-task
Pipeline Run
# hello-pipelinerun.yaml
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: hello-pipelinerun
namespace: tekton-demo
spec:
pipelineRef:
name: hello-pipeline


에러처리
ClusterTasks 에러
https://tekton.dev/docs/pipelines/deprecations
ClusterTask는 deprecated된 항목으로 무시할까하다 좀더 찾아보기로함.


crd를 추가함으로서 해결되었다.
# crd-clustertasks.yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
labels:
app.kubernetes.io/part-of: tekton-pipelines
pipeline.tekton.dev/release: v0.68.0
version: v0.68.0
name: clustertasks.tekton.dev
spec:
conversion:
strategy: None
group: tekton.dev
names:
categories:
- tekton
- tekton-pipelines
kind: ClusterTask
listKind: ClusterTaskList
plural: clustertasks
singular: clustertask
scope: Cluster
versions:
- name: v1beta1
schema:
openAPIV3Schema:
type: object
x-kubernetes-preserve-unknown-fields: true
served: true
storage: true
subresources:
status: {}
Tekton build Test
- Git으로 Push하면
- git은 web-hook으로 보낸다.
- hook은 event-lisner로 쏜다.
- event
Gitea Webhook연동
도메인 허용 설정
~/gitea-icurfer/gitea-data/gitea/conf/app.ini
[webhook]
ALLOWED_HOST_LIST = *
SKIP_TLS_VERIFY = true # 테스트 편의를 위해서 설정. 실사용에는 권장하지않음
gitea에 ALLOWE_HOST_LIST 설정이 안되서 발생하는 에러

사설인증서가 신뢰할수없어서 발생하는 에러

event lisner 설정이 안되서 발생하는 에러

Webhook을 받을 수있는 ingress 설정
dashboard의 url을 이용할 것이므로 ExternalName service를 추가하고 ingress를 수정한다.
tekton-demo에있는 service 오브젝트를 불러오는 역할을 하도록 구성한다.
# 09.ing-proxy.yaml
apiVersion: v1
kind: Service
metadata:
name: el-tekton-demo-proxy
namespace: tekton-pipelines
spec:
type: ExternalName
externalName: el-gitea-event-listener.tekton-demo.svc.cluster.local
ports:
- port: 8080
targetPort: 8080
protocol: TCP
Dashboard의 ingress 수정
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tekton-pipelines-ing
namespace: tekton-pipelines
spec:
ingressClassName: nginx
rules:
- host: tek.tk8s.test
http:
paths:
- backend:
service:
name: tekton-dashboard
port:
number: 9097
path: /
pathType: Prefix
- backend:
service:
name: el-tekton-demo-proxy
port:
number: 8080
path: /webhook-demo
pathType: Prefix
tls:
- hosts:
- tek.tk8s.test
secretName: ssl-common
URL을 변경하고 갱신테스트를 해본다.
잘 적용되었다.

ServiceAccount
# serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: tekton-triggers-sa
namespace: tekton-demo
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: tekton-build-role
namespace: tekton-demo
rules:
- apiGroups: ["", "apps", "tekton.dev", "triggers.tekton.dev"]
resources: ["pods", "pipelineruns", "tasks", "events"]
verbs: ["get", "list", "watch", "create", "update", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: tekton-build-sa-binding
namespace: tekton-demo
subjects:
- kind: ServiceAccount
name: tekton-build-sa
roleRef:
kind: Role
name: tekton-build-role
apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: tekton-build-sa
namespace: tekton-demo
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: tekton-triggers-role
rules:
- apiGroups: [""] # core API
resources: ["pods", "services", "endpoints", "configmaps", "secrets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["triggers.tekton.dev"]
resources: ["eventlisteners", "triggerbindings", "triggertemplates", "triggers"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: tekton-build-sa-binding
subjects:
- kind: ServiceAccount
name: tekton-build-sa
namespace: tekton-demo
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
Secret for image pull
# secret-dockerconfig.yaml
apiVersion: v1
kind: Secret
metadata:
name: harbor-dockerconfig
namespace: tekton-demo
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: ewoJImF1dGhzI......
task와 pipeline은 실제 동작을 위해 구성하는 오브젝트 입니다.
task.yaml
# task-build.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: build-image
namespace: tekton-demo
spec:
params:
- name: IMAGE
type: string
description: Image name to build
steps:
- name: build-and-push
image: gcr.io/kaniko-project/executor:latest
args:
- "--dockerfile=/workspace/source/Dockerfile"
- "--context=/workspace/source/"
- "--destination=$(params.IMAGE)"
volumeMounts:
- name: docker-config
mountPath: /kaniko/.docker
workspaces:
- name: source
volumes:
- name: docker-config
secret:
secretName: harbor-dockerconfig
Pipeline
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: pipeline-build
namespace: tekton-demo
spec:
params:
- name: IMAGE
type: string
- name: GIT_URL
type: string
- name: GIT_REVISION
type: string
default: main
workspaces:
- name: shared-data
tasks:
- name: build
taskRef:
name: build-image
params:
- name: IMAGE
value: $(params.IMAGE)
- name: GIT_URL
value: $(params.GIT_URL)
- name: GIT_REVISION
value: $(params.GIT_REVISION)
workspaces:
- name: source
workspace: shared-data
EventListener
텍톤이 webhook으로 받은 것을 수신할 리스너가 필요합니다.
apiVersion: triggers.tekton.dev/v1beta1
kind: EventListener
metadata:
name: gitea-event-listener
namespace: tekton-demo
spec:
serviceAccountName: tekton-build-sa
triggers:
- name: gitea-trigger
bindings:
- ref: gitea-trigger-binding
template:
ref: gitea-trigger-template
Trigger Template
PipelineRun은 pipelineRef.name을 통해 어떤 Pipeline을 실행할지 지정하고, 실행에 필요한 파라미터를 전달합니다.
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
name: gitea-trigger-template
namespace: tekton-demo
spec:
params:
- name: git-url
- name: git-revision
resourcetemplates:
- apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: build-run-
spec:
serviceAccountName: tekton-build-sa
pipelineRef:
name: pipeline-build # 이부분이 사전에 정의한 pipeline을 가져다 쓰는 부분
params:
- name: IMAGE
value: harbor.icurfer.com/open/tekton-demo:latest
- name: GIT_URL
value: $(params.git-url)
- name: GIT_REVISION
value: $(params.git-revision)
workspaces:
- name: shared-data
volumeClaimTemplate:
metadata:
name: source-pvc
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
Trigger Binding
이건 trigger template에 변수 전달할때 사용됨.
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerBinding
metadata:
name: gitea-trigger-binding
namespace: tekton-demo
spec:
params:
- name: git-url
value: $(body.repository.clone_url)
- name: git-revision
value: $(body.ref)
git Push 결과

결론 gitAction이 쉽다. gitea-runner사용해야지…
gitAction(or gitea-runner)와 비교하면,
tekton은 event lisener를 만들어야하지만 gitAction은 아니다.
tekton은 대규모 환경에서 코드 재사용성을 높일수 있다. 반면에 틀에 갇힌다.