Tekton Pipelines Tutorial
https://github.com/tektoncd/pipeline/blob/master/docs/tutorial.md
Tekton Pipeline은 Kubernetes 환경에서 CI/CD를 제공한다. 튜토리얼을 통해서 이해하고 넘어가려고 한다. Tekton Pipeline은설치 시 아래 엔티티를 정의한다. (설명은 내 마음대로다)
엔티티 | 설명 |
Task | 하나의 단계 (단위는 컨테이너) |
TaskRun | 매개변수를 사용하여 Task를 실행 (파이프라인 런을 통해서도 생성된다) |
Pipeline | Task의 순서를 정해서 정의 |
PipelineRun | 파이프라인을 실행 |
PipelineResource | 태스크를 실행할 때 매개변수를 미리 지정해놓는 리소스 |
설치는 패스하고 튜토리얼부터 정리해본다.
- Creating and running a Task
- Creating and running a Pipeline
1. Task 생성 및 실행
태스크는 내가 지정한 작업을 실행한다. 아래 태스크는 Hello, Danika를 출력해준다.
apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
name: echo-task
namespace: default
spec:
steps:
- name: echo
image: ubuntu
command:
- echo
args:
- "Hello, Danika!"
생성 이후 조회해준다.
[root@compute ~]# kubectl get task -o yaml
apiVersion: v1
items:
- apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
creationTimestamp: "2020-08-24T08:12:16Z"
generation: 1
name: echo-task
namespace: default
resourceVersion: "4002206"
selfLink: /apis/tekton.dev/v1beta1/namespaces/default/tasks/echo-task
uid: be227432-e99d-4b2a-9e1d-216e65b47302
spec:
steps:
- args:
- Hello, Danika!
command:
- echo
image: ubuntu
name: echo
resources: {}
kind: List
metadata:
resourceVersion: ""
selfLink: ""
태스크를 실행하기 위해서는 TaskRun을 생성해야한다.
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
name: echo-taskrun
namespace: default
spec:
taskRef:
name: echo-task
TaskRun 생성 이후 파드를 조회하면 새로운 파드가 생성된 것을 볼 수 있다. 해당 파드의 로그를 살펴본다.
[root@compute ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
echo-taskrun-pod-bppjp 0/1 Completed 0 35s
[root@compute ~]# kubectl logs echo-taskrun-pod-bppjp
Hello, Danika!
내가 지정한 작업을 잘 마친 다음 Completed 상태에서 은은하게 머물러 있다. 이제 이거보다 조금 더 어려운 태스크를 만들어본다.
2. 입력 출력을 가진 Task 생성 및 실행
Task의 입력/출력에 사용할 PipelineResource를 만들어둔다.
- 빌드할 GIT 주소
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
name: skaffold-git
namespace: default
spec:
type: git
params:
- name: revision
value: master
- name: url
value: https://github.com/onenumbersol/skaffold
- 푸시 할 저장소 주소
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
name: skaffold-image-leeroy-web
namespace: default
spec:
type: image
params:
- name: url
value: [Registry_Address]/leeroy-web
git은 skaffold 저장소 포크해왔다.
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: build-docker-image-from-git-source
namespace: default
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)
Task를 생성해준다. YAML을 보면 이전에는 없었던 것들이 보인다.
위치 | 이름 | 내용 |
spec.params | pathToDockerFile | Build 할 dockerfile의 위치 |
spec.params | pathToContext | Kaniko를 통해 build할 context의 위치 |
spec.resources | docker-source | Git 주소 |
spec.resources | builtImage | Image 주소 |
Step을 보면 kaniko-project라는 애를 통해서 build 및 push를 해주는 것을 볼 수 있다. 튜토리얼에서는 credentials를 사용할 수 있는 SA를 생성해주는데 난 내부 저장소라서 필요없으니 패스한다.
이제 TASK를 실행해본다.
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
name: build-docker-image-from-git-source-task-run
namespace: default
spec:
serviceAccountName: default
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
위치 | 이름 | 내용 |
spec.params | pathToDockerFile | dockerfile 이름 |
spec.params | pathToContext | Kaniko를 통해 build할 context의 위치 |
spec.resources | docker-source | PipelineResource 이름과 매핑 (GIT) |
spec.resources | builtImage | PipelineResource 이름과 매핑 (IMAGE) |
실행하면 빌드 및 푸시를 수행하는 파드를 확인할 수 있다.
[root@compute ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
build-docker-image-from-git-source-task-run-pod-6ts69 0/4 PodInitializing 0 2m
Completed 상태로 변경되면 지정한 이미지 저장소에 이미지가 들어갔는지 확인해본다.
[root@compute ~]# curl -X GET REGISTRY_ADDRESS/v2/_catalog
{"repositories":["leeroy-web"]}
이상없이 진행되었음을 볼 수 있다.
3. 파이프라인 생성 및 실행
파이프라인은 생성한 태스크들의 순서를 정해주고 입력/출력의 결과를 매핑해주는 역할을 한다. 빌드 및 푸쉬를 진행했으면 해당 이미지를 통해 웹서비스를 띄우는 작업까지 한 번에 진행해주는 파이프라인을 생성한다.
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: tutorial-pipeline
namespace: default
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"
spec.tasks.taskRef를 보면 name으로 이전에 생성한 task를 지정해주는 것을 볼 수 있다. 이전에 build-docker-image-form-git-source는 생성해주었으나 deploy-using-kubectl은 존재하지 않으므로 만들어준다.
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: deploy-using-kubectl
namespace: default
spec:
params:
- name: path
type: string
description: Path to the manifest to apply
- name: yamlPathToImage
type: string
description: |
The path to the image to replace in the yaml manifest (arg to yq)
resources:
inputs:
- name: source
type: git
- name: image
type: image
steps:
- name: replace-image
image: mikefarah/yq
command: ["yq"]
args:
- "w"
- "-i"
- "$(params.path)"
- "$(params.yamlPathToImage)"
- "$(resources.inputs.image.url)"
- name: run-kubectl
image: lachlanevenson/k8s-kubectl
command: ["kubectl"]
args:
- "apply"
- "-f"
- "$(params.path)"
생성한 tutorial-pipeline에는 총 2개의 태스크가 존재한다. 첫번째는 build and push를 진행해주는 build-docker-image-form-git-source 태스크이고, 두번째는 kubectl을 이용하여 웹 파드를 생성해주는 deploy-using-kubectl 태스크이다. task는 정해진 순서가 있어야 한다. spec.tasks.name.resources.input 아래를 보면 from을 통해 이전 작업을 지정해주는 것을 볼 수 있다.
특정 namespace에 deploy를 하려면 service account에 해당 롤이 지정되어 있어야 한다. 난 미리 지정해두었는데 없으면 롤 생성 이후 바인딩을 해준다. 그리고 파이프라인 런을 실행해준다.
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: tutorial-pipeline-run-1
namespace: default
spec:
serviceAccountName: sa-test
pipelineRef:
name: tutorial-pipeline
resources:
- name: source-repo
resourceRef:
name: skaffold-git
- name: web-image
resourceRef:
name: skaffold-image-leeroy-web
실행 된 이후 파드들을 확인해본다.
[root@compute ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
leeroy-web-65b7986d78-j76dr 1/1 Running 0 2m7s
tutorial-pipeline-run-1-build-skaffold-web-qjdz5-pod-9xqq4 0/4 Completed 0 3m34s
tutorial-pipeline-run-1-deploy-web-c7wbs-pod-jfnxb 0/3 Completed 0 2m38s
leeroy-web 파드가 실행되어 Running 상태를 가지고 있다. 로그를 보자...
[root@compute ~]# k logs leeroy-web-65b7986d78-j76dr
2020/08/24 09:15:02 leeroy web server ready
제대로 배포되었음을 볼 수 있다. 이 정도면 해당 오브젝트들이 각각 어느 역할을 하는지에 대해서는 쪼끔이라도 이해한 것 같다.