티스토리 뷰

728x90
반응형

Overview

Tekton은 CI/CD를 위한 클라우드 네이티브 솔루션으로 CSP 3사는 물론, On-premise 환경의 Kubernetes를 모두 지원하며, build, test, deploy를 기능을 제공한다.

Tekton은 언어 및 배포 환경 전반에서 CI / CD 도구 및 프로세스를 표준화한다. 특히 복잡한 MSA 환경에서 배포 환경을 통합하여 구성하기 용이한 구조로 되어 있다. Jenkins, Jenkins X, Spinnker, Skaffold, Knative 등 다양한 CI/CD 도구와 통합할 수 있다.

Tekton은 Step, Task, Pipeline, Pipeline Resource로 구성되어 있으며, Task와 Pipeline을 기동하는 TaskRun, PipelineRun 오브젝트가 있다.

- Step : Step은 컴파일, 이미지 생성, 이미지 저장 등 일련의 작업을 실행하는 하위 명령어이다.

- Task : Task는 Step의 모음이다. Step은 Kubernetes 환경에서 Pod로 기동되며, Task는 이 Step 들의 그룹이라 볼 수 있다. 예를 들어 Step에 git clone, git push 등의 명령어를 실행한다면, 이들을 묶어 git-clone이라는 Task로 정의한다.

- TaskRun : Task를 실행하는 오브젝트이다. Task에 변수를 할당하거나, input/output을 정의하는 역할을 한다.

[task sample]

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: build-docker-image-from-git-source
spec:
  params:
    - name: pathToDockerFile
      type: string
      description: The path to the dockerfile to build
      default: $(resources.inputs.docker-source.path)/Dockerfile
    - name: pathToContext
      type: string
      description: |
        The build context used by Kaniko
        (https://github.com/GoogleContainerTools/kaniko#kaniko-build-contexts)
      default: $(resources.inputs.docker-source.path)
  resources:
    inputs:
      - name: docker-source
        type: git
    outputs:
      - name: builtImage
        type: image
  steps:
    - name: build-and-push
      image: gcr.io/kaniko-project/executor:v0.16.0
      # specifying DOCKER_CONFIG is required to allow kaniko to detect docker credential
      env:
        - name: "DOCKER_CONFIG"
          value: "/tekton/home/.docker/"
      command:
        - /kaniko/executor
      args:
        - --dockerfile=$(params.pathToDockerFile)
        - --destination=$(resources.outputs.builtImage.url)
        - --context=$(params.pathToContext)
        
[taskRun sample]
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
  name: build-docker-image-from-git-source-task-run
spec:
  serviceAccountName: tutorial-service
  taskRef:
    name: build-docker-image-from-git-source
  params:
    - name: pathToDockerFile
      value: Dockerfile
    - name: pathToContext
      value: $(resources.inputs.docker-source.path)/examples/microservices/leeroy-web #configure: may change according to your source
  resources:
    inputs:
      - name: docker-source
        resourceRef:
          name: skaffold-git
    outputs:
      - name: builtImage
        resourceRef:
          name: skaffold-image-leeroy-web

- Pipeline : Pipeline은 Task의 모음이다. Task의 순서를 정의하고, 실행 시점에 파라미터를 정의할 수 있다. 이로 인해 Task는 Template으로써 재사용이 가능한 형태가 된다.

[pipeline sample]

apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: tutorial-pipeline
spec:
  resources:
    - name: source-repo
      type: git
    - name: web-image
      type: image
  tasks:
    - name: build-skaffold-web
      taskRef:
        name: build-docker-image-from-git-source
      params:
        - name: pathToDockerFile
          value: Dockerfile
        - name: pathToContext
          value: /workspace/docker-source/examples/microservices/leeroy-web #configure: may change according to your source
      resources:
        inputs:
          - name: docker-source
            resource: source-repo
        outputs:
          - name: builtImage
            resource: web-image
    - name: deploy-web
      taskRef:
        name: deploy-using-kubectl
      resources:
        inputs:
          - name: source
            resource: source-repo
          - name: image
            resource: web-image
            from:
              - build-skaffold-web
      params:
        - name: path
          value: /workspace/source/examples/microservices/leeroy-web/kubernetes/deployment.yaml #configure: may change according to your source
        - name: yamlPathToImage
          value: "spec.template.spec.containers[0].image"

- PipelineRun : Pipeline을 실행하는 오브젝트이다. Pipeline도 재활용성을 높이기 위해 PipelineRun에 변수할당 및 input/output을 정의할 수 있다.

PipelineResource : Pipeline에서 사용하는 리소스로 Git Repository, Image Repository 등이 있다.

실제 논리적인 연관도를 보자면, Step > Task > Pipeline > PipelineRun으로 이어진다고 볼 수 있다. TaskRun의 경우 Task > TaskRun으로 동작한다.

Tekton에서는 RWO모드의 볼륨을 사용하는 경우를 대비하여 Affinity Assistants라는 기능을 제공하고 있다. Affinity Assistants는 Pipeline 내 모든 Task를 같은 Node에 배치하게 하는 역할을 한다.
또한, PodTemplate을 따로 만들어 NodeSelector나 Tolerations를 설정했다고 해도 Affinity Assistant가 그 설정들을 오버라이드한다. 이를 활용하면, task들이 동일한 노드에서 기동되어 볼륨 이슈를 방지할 수 있다.


Tekton 설치

Tekton을 설치하기 위해서는 먼저 Kubernetes 1.16 이상의 환경이 준비되어 있어야 한다. 이번 포스팅은 Amazon EKS를 통해 테스트를 실행해 보도록 하자. 

1) Tekton Pipeline 설치

kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml

2) Tekton Dashboard & Trigger 설치

kubectl apply --filename https://github.com/tektoncd/dashboard/releases/download/v0.6.0/tekton-dashboard-release.yaml
kubectl apply --filename https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml

3) Tekton Ingress Dashboard 설치

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: tekton-dashboard
  namespace: tekton-pipelines
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/subnets: subnet-xxxxxxxx,subnet-xxxxxxxx
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: tekton-dashboard
          servicePort: 9097

> 9097 서비스 포트를 사용하는 tekton-dashboard에 접근하기 위한 ingress를 구성한다.

4) 설치 확인

[root@ip-192-168-71-110 eks]# kubectl get all -n tekton-pipelines
NAME                                               READY   STATUS    RESTARTS   AGE
pod/tekton-dashboard-748fb458c7-9lhpr              1/1     Running   0          8h
pod/tekton-pipelines-controller-558cc574b7-dxqvx   1/1     Running   0          8h
pod/tekton-pipelines-webhook-575b9bcd9f-5srdv      1/1     Running   0          8h

NAME                                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                              AGE
service/tekton-dashboard              ClusterIP   10.100.199.143   <none>        9097/TCP                             8h
service/tekton-pipelines-controller   ClusterIP   10.100.105.128   <none>        9090/TCP,8080/TCP                    8h
service/tekton-pipelines-webhook      ClusterIP   10.100.138.201   <none>        9090/TCP,8008/TCP,443/TCP,8080/TCP   8h

NAME                                          READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/tekton-dashboard              1/1     1            1           8h
deployment.apps/tekton-pipelines-controller   1/1     1            1           8h
deployment.apps/tekton-pipelines-webhook      1/1     1            1           8h

NAME                                                     DESIRED   CURRENT   READY   AGE
replicaset.apps/tekton-dashboard-748fb458c7              1         1         1       8h
replicaset.apps/tekton-pipelines-controller-558cc574b7   1         1         1       8h
replicaset.apps/tekton-pipelines-webhook-575b9bcd9f      1         1         1       8h

NAME                                                           REFERENCE                             TARGETS          MINPODS   MAXPODS   REPLICAS   AGE
horizontalpodautoscaler.autoscaling/tekton-pipelines-webhook   Deployment/tekton-pipelines-webhook   <unknown>/100%   1         5         1          8h
[root@ip-192-168-71-110 eks]# 

5) tkn 설치

[root@ip-192-168-71-110 eks]# curl -LO https://github.com/tektoncd/cli/releases/download/v0.8.0/tkn_0.8.0_Linux_x86_64.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   637  100   637    0     0   2242      0 --:--:-- --:--:-- --:--:--  2242
100  9.7M  100  9.7M    0     0  4613k      0  0:00:02  0:00:02 --:--:-- 5965k
[root@ip-192-168-71-110 eks]# sudo tar xvzf tkn_0.8.0_Linux_x86_64.tar.gz -C /usr/local/bin/ tkn
tkn
[root@ip-192-168-71-110 eks]# tkn version
Client version: 0.8.0
Pipeline version: unknown
[root@ip-192-168-71-110 eks]#

6) Dashboard 접속 (http://alb_ip:alb_port)


Tekton CLI 구성

먼저 tekton pipeline을 구성하기 전 tkn cli를 활용한 배포구성을 진행해 보자.

1) Task

> 다음은 Ubuntu 이미지를 기반으로 echo "Hello World!"를 출력하는 Task이다.

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: hello
spec:
  steps:
    - name: hello
      image: ubuntu
      command:
        - echo
      args:
        - "Hello World!"

> task가 작성되면, 다음과 같이 반영하고 확인한다.

[root@ip-192-168-71-110 tekton]# kubectl apply -f hello.yaml 
task.tekton.dev/hello created
[root@ip-192-168-71-110 tekton]# kubectl get task --all-namespaces
NAMESPACE   NAME    AGE
default     hello   58m
[root@ip-192-168-71-110 tekton]# 

2) TaskRun

> 앞서 생성한 Task를 실행하기 위해서는 TaskRun을 생성해야 한다.

[root@ip-192-168-71-110 tekton]# tkn task start hello --dry-run
apiVersion: tekton.dev/v1alpha1
kind: TaskRun
metadata:
  creationTimestamp: null
  generateName: hello-run-
  namespace: default
spec:
  inputs: {}
  outputs: {}
  serviceAccountName: ""
  taskRef:
    name: hello
  timeout: 1h0m0s
status:
  podName: ""
[root@ip-192-168-71-110 tekton]# tkn task start hello
Taskrun started: hello-run-xkmwc

In order to track the taskrun progress run:
tkn taskrun logs hello-run-xkmwc -f -n default
[root@ip-192-168-71-110 tekton]#

> tkn task start [task_name]은 TaskRun을 자동으로 정의하며, task를 실행한다.

3) Task log

[root@ip-192-168-71-110 tekton]# tkn taskrun logs --last -f 
[hello] Hello World!

[root@ip-192-168-71-110 tekton]# tkn task list
NAME      AGE
goodbye   5 hours ago
hello     7 hours ago
[root@ip-192-168-71-110 tekton]# tkn taskrun list
NAME                                            STARTED       DURATION     STATUS               
hello-goodbye-run-rmrvm-r-2nr7d-goodbye-ljrnn   1 hour ago    10 seconds   Succeeded   
hello-goodbye-run-rmrvm-r-2nr7d-hello-dmz86     1 hour ago    9 seconds    Succeeded   
hello-goodbye-run-rmrvm-goodbye-wq5v4           5 hours ago   8 seconds    Succeeded   
hello-goodbye-run-rmrvm-hello-4lkl2             5 hours ago   8 seconds    Succeeded   
goodbye-run-fz724                               5 hours ago   12 seconds   Succeeded   
hello-run-xkmwc                                 7 hours ago   14 seconds   Succeeded   
[root@ip-192-168-71-110 tekton]#

> echo로 출력한 Hello World!가 출력되는 것을 확인할 수 있다.

4) 대시보드 확인

> 대시보드에 작성한 Task와 TaskRun이 등록되어 있는것을 확인할 수 있다.


Tekton Pipeline 구성

이번에는 Pipeline을 구성해 보자. Pipeline은 이미지를 생성하고 배포하고 또는 일련의 여러 과정을 파이프라인으로 묶어 하나의 프로세스가 동작하듯 제어하고 관리할 수 있다.

앞서 생성한 Hello Task와 함께 GoodBye Task를 생성하여 Pipeline으로 묶어 동작하는 것을 확인해 보자.

1) Task

> 다음은 Ubuntu 이미지를 기반으로 echo "Goodbye World!"를 출력하는 Task이다.

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: goodbye
spec:
  steps:
    - name: goodbye
      image: ubuntu
      script: |
        #!/bin/bash
        echo "Goodbye World!"

> task가 작성되면, 다음과 같이 반영하고 확인한다.

[root@ip-192-168-71-110 tekton]# kubectl apply -f goodbye.yaml 
task.tekton.dev/goodbye created
[root@ip-192-168-71-110 tekton]# kubectl get task --all-namespaces
NAMESPACE   NAME      AGE
default     goodbye   37s
default     hello     83m
[root@ip-192-168-71-110 tekton]#

2) TaskRun

> 앞서 생성한 Task를 실행하기 위해서는 TaskRun을 생성해야 한다.

[root@ip-192-168-71-110 tekton]# tkn task start goodbye
Taskrun started: goodbye-run-fz724

In order to track the taskrun progress run:
tkn taskrun logs goodbye-run-fz724 -f -n default
[root@ip-192-168-71-110 tekton]# 

> tkn task start [task_name]은 TaskRun을 자동으로 정의하며, task를 실행한다.

3) Task log

[root@ip-192-168-71-110 tekton]# tkn taskrun logs --last -f 
[goodbye] Goodbye World!

[root@ip-192-168-71-110 tekton]# tkn task list
NAME      AGE
goodbye   5 hours ago
hello     7 hours ago
[root@ip-192-168-71-110 tekton]# tkn taskrun list
NAME                                            STARTED       DURATION     STATUS               
hello-goodbye-run-rmrvm-r-2nr7d-goodbye-ljrnn   1 hour ago    10 seconds   Succeeded   
hello-goodbye-run-rmrvm-r-2nr7d-hello-dmz86     1 hour ago    9 seconds    Succeeded   
hello-goodbye-run-rmrvm-goodbye-wq5v4           5 hours ago   8 seconds    Succeeded   
hello-goodbye-run-rmrvm-hello-4lkl2             5 hours ago   8 seconds    Succeeded   
goodbye-run-fz724                               5 hours ago   12 seconds   Succeeded   
hello-run-xkmwc                                 7 hours ago   14 seconds   Succeeded   
[root@ip-192-168-71-110 tekton]#

4) 대시보드 확인

> 대시보드에 작성한 Task와 TaskRun이 등록되어 있는것을 확인할 수 있다.

5) Pipeline

apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: hello-goodbye
spec:
  tasks:
  - name: hello
    taskRef:
      name: hello
  - name: goodbye
    runAfter:
     - hello
    taskRef:
      name: goodbye

> 위와 같이 taskRef/runAfter를 활용하여 task 실행 순서를 정의한다.

[root@ip-192-168-71-110 tekton]# kubectl apply -f hello-goodbye.yaml 
pipeline.tekton.dev/hello-goodbye created
[root@ip-192-168-71-110 tekton]# kubectl get pipeline 
NAME            AGE
hello-goodbye   53s
[root@ip-192-168-71-110 tekton]# 

> 위와 같이 Pipeline 오브젝트가 생성된것을 확인할 수 있다.

6) PipelineRun

> Pipeline을 실행하기 위해서는 PipelineRun을 생성해야 한다.

[root@ip-192-168-71-110 tekton]# tkn pipeline start hello-goodbye --dry-run
apiVersion: tekton.dev/v1alpha1
kind: PipelineRun
metadata:
  creationTimestamp: null
  generateName: hello-goodbye-run-
  namespace: default
spec:
  pipelineRef:
    name: hello-goodbye
  timeout: 1h0m0s
status: {}
[root@ip-192-168-71-110 tekton]# tkn pipeline start hello-goodbye
Pipelinerun started: hello-goodbye-run-rmrvm

In order to track the pipelinerun progress run:
tkn pipelinerun logs hello-goodbye-run-rmrvm -f -n default
[root@ip-192-168-71-110 tekton]#

> tkn pipeline start [pipeline_name]은 PipelineRun을 자동으로 정의하며, Pipeline을 실행한다.

7) Pipeline log

[root@ip-192-168-71-110 tekton]# tkn pipelinerun logs --last -f 
[hello : hello] Hello World!

[goodbye : goodbye] Goodbye World!

[root@ip-192-168-71-110 tekton]# tkn pipeline list
NAME            AGE           LAST RUN                          STARTED      DURATION     STATUS
hello-goodbye   5 hours ago   hello-goodbye-run-rmrvm-r-2nr7d   1 hour ago   19 seconds   Succeeded
[root@ip-192-168-71-110 tekton]# tkn pipelinerun list
NAME                              STARTED       DURATION     STATUS               
hello-goodbye-run-rmrvm-r-2nr7d   1 hour ago    19 seconds   Succeeded   
hello-goodbye-run-rmrvm           5 hours ago   16 seconds   Succeeded   
[root@ip-192-168-71-110 tekton]# 

> 위와 같이 순차적으로 Hello World!와 Goodbye World!가 출력되는 것을 볼 수 있다.

8) 대시보드 확인

9) Pipeline과 Task 간 파라미터 공유하기

hello.yaml과 hello-goodbye.yaml을 수정하여 다음과 같이 파라미터를 세팅할 수 있다.

[hello-goodbye.yaml]

apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: hello-goodbye
spec:
  tasks:
  - name: hello
    taskRef:
      name: hello
    params:
      - name: hello-greeting
        value: "hello nara!"
  - name: goodbye
    runAfter:
     - hello
    taskRef:
      name: goodbye

> 적용하고자 하는 task 하위에 params를 추가한다.

[hello.yaml]

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: hello
spec:
  params:
    - name: hello-greeting
      type: string
      description: hello 
      default: hello my friend
  steps:
    - name: hello
      image: ubuntu
      command:
        - echo
      args:
        - "$(params.hello-greeting)"

> task에 params를 정의(name, type, description, default)하고, steps.args에 "$(params.[PARAM_NAME])" 형태로 정의하여 pipeline의 변수를 받아 올 수 있다.

[root@ip-192-168-71-110 tekton]# kubectl apply -f hello.yaml 
task.tekton.dev/hello configured
[root@ip-192-168-71-110 tekton]# kubectl apply -f hello-goodbye.yaml 
pipeline.tekton.dev/hello-goodbye configured
[root@ip-192-168-71-110 tekton]# tkn pipelinerun logs --last -f 
[hello : hello] hello nara!

[goodbye : goodbye] Goodbye World!

[root@ip-192-168-71-110 tekton]#

Tekton Hub 활용

Tekton Hub는 DockerHub와 같이 Tekton에서 사용하는 Task를 정의해 둔 라이브러리 저장소라고 볼 수 있다.

Tekton Hub : https://hub.tekton.dev/

> 초기에 Task를 커스터마이징하기 위한 Template 자료로 활용할 수 있다. 예를 들어 Git Clone에 대한 Task를 알아보고 싶다면,

> 위와 같이 Git을 검색하고, git clone을 선택한다.

> 커스터마이징 가능한 YAML 파일과 주요 설정 정보에 대한 Description 그리고 Task 반영을 위한 Install 방법이 제공된다.

> kubectl과 tkn을 사용하여 적용하는 방법이 각각 제시된다.

[root@ip-192-168-71-110 tekton]# kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/main/task/git-clone/0.4/git-clone.yaml
task.tekton.dev/git-clone created
[root@ip-192-168-71-110 tekton]# 

> 아래와 같이 task가 적용된 것을 볼 수 있다.

> Task를 기반으로 Pipeline, PipelineRun 또는 TaskRun을 구현하여 배포하면 된다.


결론

지금까지 간단하게 Tekton을 활용하여 Pipeline을 구성하는 방법에 대해 알아보았다.

1) tkn task start [TASK_NAME]

2) tkn taskrun logs --last -f 

3) tkn task list

4) tkn taskrun list

5) tkn pipeline start [PIPELINE_NAME]

6) tkn pipelinerun logs --last -f 

7) tkn pipeline list

8) tkn pipelinerun list

Tekton은 task, pipeline으로 구성된 단순하면서도 확장성과 재활용성이 높은 클라우드 네이티브 오픈소스 플랫폼이라고 할 수 있다.

대표적인 CI/CD Tool들과 견주어 최근 많은 플랫폼에서 선택되고 있으며, 특히 기존 사용하던 플랫폼과의 호환성이 뛰어나 초기 적용에 많은 강점을 갖고 있다.

이번 포스팅에서는 Tekton을 활용한 배포 프로세스를 이해해 보았으며, 다음 포스팅에서는 보다 상세하게 Task와 Pipeline에 대해 알아보고, 활용 방법에 대해 살펴보도록 하자.

728x90
반응형