반응형
Tekton은 CI/CD pipeline을 구축하기 위한 Kubernetes기반의 오픈소스 프로젝트이다.
Kubernetes의 CRD로 정의해 사용된다.
이번 포스팅에서는 Tekton의 특징과 공식 sample예제를 진행해 보겠다.
1. Tekton의 구조
- Tekton은 크게 Steps, Tasks, Pipelines로 이루어져 있다.
- Pipeline은 Task들의 모임이며 Task는 Step들의 모임이다.
- Step : Tekton의 기본 작업 단위이다.
- Task : Kubernetes의 pod으로 실행되며 step들은 이 pod내부에 container로 기동된다.
- Pipeline : 순서를 갖는 Task들의 모음이다.
- TaskRun : Task를 실행시키는 역할을 한다.
- PipelineRun : Pipeline을 실행시키는 역할을 한다.
2. Tekton pipelines 설치
- Kubernetes cluster에 Tekton pipeline을 설치한다.
kubectl apply --filename \
https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
test@DESKTOP-F55SF6V:~ (⎈|test-cluster:default)# k get all -n tekton-pipelines
NAME READY STATUS RESTARTS AGE
pod/tekton-pipelines-controller-94965db6f-kshxb 1/1 Running 0 69s
pod/tekton-pipelines-webhook-5bfc758fd7-9zbrd 1/1 Running 0 50s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/tekton-pipelines-controller ClusterIP 10.100.115.12 <none> 9090/TCP,8008/TCP,8080/TCP 70s
service/tekton-pipelines-webhook ClusterIP 10.100.3.221 <none> 9090/TCP,8008/TCP,443/TCP,8080/TCP 50s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/tekton-pipelines-controller 1/1 1 1 72s
deployment.apps/tekton-pipelines-webhook 1/1 1 1 52s
NAME DESIRED CURRENT READY AGE
replicaset.apps/tekton-pipelines-controller-94965db6f 1 1 1 72s
replicaset.apps/tekton-pipelines-webhook-5bfc758fd7 1 1 1 53s
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
horizontalpodautoscaler.autoscaling/tekton-pipelines-webhook Deployment/tekton-pipelines-webhook <unknown>/100% 1 5 1 55s
- 구성 resource들이 생성되었다.
3. Tekton CLI(tkn) 설치
- ubuntu 기준이며 아래와 같이 설치한다.
curl -LO https://github.com/tektoncd/cli/releases/download/v0.27.0/tektoncd-cli-0.27.0_Linux-64bit.deb
sudo dpkg -i tektoncd-cli-0.27.0_Linux-64bit.deb
cp /usr/bin/tkn /usr/local/bin/tkn
4. Task생성 및 TaskRun 실행
- hello-world.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: hello
namespace: test
spec:
steps:
- name: echo
image: alpine
script: |
#!/bin/sh
echo "Hello World"
- echo "Hello World"를 수행할 Task yaml파일을 작성한다.
- hello-world.yaml파일로 task를 생성한다.
test@DESKTOP-F55SF6V:~/tekton (⎈|test-cluster:default)# kubectl apply -f hello-world.yaml
task.tekton.dev/hello created
test@DESKTOP-F55SF6V:~/tekton (⎈|test-cluster:default)# k get task -n test
NAME AGE
hello 6s
- hello Task를 실행시키기 위한 hello-task-run TaskRun을 생성한다.
- hello-world-run.yaml
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
name: hello-task-run
namespace: test
spec:
taskRef:
name: hello
- taskRef로 앞에 만들어둔 hello Task를 지정한다.
- hello-task-run.yaml파일로 TaskRun을 실행한다.
test@DESKTOP-F55SF6V:~/tekton (⎈|test-cluster:default)# kubectl apply -f hello-world-run.yaml
taskrun.tekton.dev/hello-task-run created
test@DESKTOP-F55SF6V:~/tekton (⎈|test-cluster:default)# k get taskrun -n test
NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME
hello-task-run True Succeeded 47s 31s
test@DESKTOP-F55SF6V:~/tekton (⎈|test-cluster:default)# k get po -n test
NAME READY STATUS RESTARTS AGE
hello-task-run-pod 0/1 Completed 0 69s
test@DESKTOP-F55SF6V:~/tekton (⎈|test-cluster:default)# kubectl logs --selector=tekton.dev/taskRun=hello-task-run -n test
Defaulted container "step-echo" out of: step-echo, prepare (init), place-scripts (init)
Hello World
- hello-task-run-pod가 앞에 만들어둔 hello Task의 tasks들을 container로 기동시킨다.
hello-task-run-pod의 container를 보면 step-echo container가 기동된 것을 확인할 수 있다.
반응형
5. Pipeline 생성 및 PipelineRun 실행
- Pipeline으로 묶을 task들을 생성한다.
앞의 예제에서 생성한 hello Task와 추가로 goodbye Task를 생성한다.
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: goodbye
namespace: test
spec:
params:
- name: username
type: string
steps:
- name: goodbye
image: ubuntu
script: |
#!/bin/bash
echo "Goodbye $(params.username)!"
- username을 전달받아 echo "Goodbye $username!" 을 수행하는 Task를 만든다.
test@DESKTOP-F55SF6V:~/tekton (⎈|test-cluster:default)# kubectl apply -f goodbye-world.yaml
task.tekton.dev/goodbye created
test@DESKTOP-F55SF6V:~/tekton (⎈|test-cluster:default)# k get task -n test
NAME AGE
goodbye 13s
hello 6m32s
- hello-goodbye-pipeline.yaml파일로 Pipeline을 만든다.
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: hello-goodbye
namespace: test
spec:
params:
- name: username
type: string
tasks:
- name: hello
taskRef:
name: hello
- name: goodbye
runAfter:
- hello
taskRef:
name: goodbye
params:
- name: username
value: $(params.username)
- 앞에서 만든 hello와 goodbye Task를 하나의 Pipeline으로 묶었다. goodbye Task는 hello Task 이 후 수행된다.
test@DESKTOP-F55SF6V:~/tekton (⎈|test-cluster:default)# kubectl apply -f hello-goodbye-pipeline.yaml
pipeline.tekton.dev/hello-goodbye created
test@DESKTOP-F55SF6V:~/tekton (⎈|test-cluster:default)# k get pipeline -n test
NAME AGE
hello-goodbye 43s
- hello-goodbye-pipeline-run.yaml파일로 PipelineRun을 실행한다.
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: hello-goodbye-run
namespace: test
spec:
pipelineRef:
name: hello-goodbye
params:
- name: username
value: "Tekton"
- hello-goodbye Pipeline을 실행시킬 hello-goodbye-run PipelineRun이 생성되며
$(params.username)값인 Tekton 을 파라미터로 전달한다.
test@DESKTOP-F55SF6V:~/tekton (⎈|test-cluster:default)# kubectl apply -f hello-goodbye-pipeline-run.yaml
pipelinerun.tekton.dev/hello-goodbye-run created
test@DESKTOP-F55SF6V:~ (⎈|test-cluster:default)# tkn pipelinerun logs hello-goodbye-run -f -n test
[hello : echo] Hello World
[goodbye : goodbye] Goodbye Tekton!
- hello-goodbye-pipeline-run이 수행되며 Task별로 hello-goodbye-run-hello-pod 와 hello-goodbye-run-goodbye-pod가
각각 생성되었다. - Tekton CLI인 tkn을 통해 pipelinerun의 로그를 확인해보면 "[Task명 : Step명] 로그" 형태로 보인다.
6. Trigger 생성 및 EventListener를 통한 Trigger 발생
- Trigger를 사용할 경우 별도의 deploy, crd등 resource추가 설치가 필요하다.
kubectl apply -f \
https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml
kubectl apply -f \
https://storage.googleapis.com/tekton-releases/triggers/latest/interceptors.yaml
- Trigger에 의해 수행될 내용을 정의한다.
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
name: hello-template
namespace: test
spec:
params:
- name: username
default: "Kubernetes"
resourcetemplates:
- apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: hello-goodbye-run-
spec:
pipelineRef:
name: hello-goodbye
params:
- name: username
value: $(tt.params.username)
- Trigger에 의해 수행될 PipelineRun을 정의한다. 앞의 예제에서 생성한 Pipeline의 정보가 들어가 있다.
- Event에서 받은 데이터를 TriggerTemplate의 파라미터에 맵핑해줄 TriggerBinding을 작성한다.
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerBinding
metadata:
name: hello-binding
namespace: test
spec:
params:
- name: username
value: $(body.username)
- HTTP기반의 Event를 받아 Trigger로 전달해줄 EventListener를 작성한다.
apiVersion: triggers.tekton.dev/v1beta1
kind: EventListener
metadata:
name: hello-listener
namespace: test
spec:
serviceAccountName: tekton-robot
triggers:
- name: hello-trigger
bindings:
- ref: hello-binding
template:
ref: hello-template
- 데이터를 전달할 binding과 telmplate의 정보가 정의되어 있다.
- EventListener에 사용할 ServiceAccount 및 RBAC생성을 한다.
apiVersion: v1
kind: ServiceAccount
metadata:
name: tekton-robot
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: triggers-example-eventlistener-binding
subjects:
- kind: ServiceAccount
name: tekton-robot
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: tekton-triggers-eventlistener-roles
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: triggers-example-eventlistener-clusterbinding
subjects:
- kind: ServiceAccount
name: tekton-robot
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: tekton-triggers-eventlistener-clusterroles
- 포스팅을 기준으로 테스트하는 경우 tekton-triggers-eventlistener-roles Role이 생성된 Namespace와 별도의 Namespace(test)에 Resource를 생성하고 있어 권한이 없을 거다.
테스트용도이기 때문에 tekton-triggers-eventlistener-clusterroles Clusterrole에 필요한 권한을 부여했으니 필요시
참고한다.
rules:
- apiGroups:
- triggers.tekton.dev
resources:
- clustertriggerbindings
- clusterinterceptors
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- triggers.tekton.dev
resources:
- eventlisteners
- triggerbindings
- interceptors
- triggertemplates
- triggers
verbs:
- get
- list
- watch
- apiGroups:
- tekton.dev
resources:
- pipelineruns
- pipelineresources
- taskruns
verbs:
- create
- EventListener pod와 service가 생성되며 HTTP요청을 보내 Trigger가 작동하는지 확인한다.
curl -v \
-H 'content-Type: application/json' \
-d '{"username": "Tekton"}' \
http://localhost:8080
- curl로 EventLister service의 port로 username data와 함께 HTTP요청을 넣었다.
< HTTP/1.1 202 Accepted
< Content-Type: application/json
< Date: Sat, 25 Mar 2023 11:54:31 GMT
< Content-Length: 161
<
{"eventListener":"hello-listener","namespace":"test","eventListenerUID":"c74122e8-a7e0-4933-aca0-41b714db46c5","eventID":"9cb1db79-e71d-4b9e-a865-e43dbef5775a"}
- EventListener의 이름, namespace등의 정보가 나온다.
- Trigger가 정상적으로 동작되었는지 확인한다.
test@DESKTOP-F55SF6V:~/tekton (⎈|test-cluster:default)# k get pipelinerun -n test
NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME
hello-goodbye-run True Succeeded 5h16m 5h16m
hello-goodbye-run-rpmkt True Succeeded 54m 53m
test@DESKTOP-F55SF6V:~/tekton (⎈|test-cluster:default)# tkn pipelinerun logs hello-goodbye-run-rpmkt -f -n test
[hello : echo] Hello World
[goodbye : goodbye] Goodbye Tekton!
- 앞에 생성해둔 hello-goodbye-run PipelineRun이 수행된 것을 확인할 수 있다.
다음 포스팅에는 tkn사용법과 대시보드를 정리해 보겠다.
반응형