본문 바로가기
cicd/tekton

Tekton pipeline으로 CI환경 구축하기

by _Nate 2023. 3. 25.
반응형

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사용법과 대시보드를 정리해 보겠다.

반응형