전자책 출간 알림 [마이크로서비스패턴 쉽게 개발하기]

티스토리 뷰

Agile&DevOps/Tekton

3. Task & TaskRun

Happy@Cloud 2019. 12. 13. 15:21

Task와 Taskrun의 관계는 아래와 같습니다.

- Taskrun은 Resource를 참조할 수 있습니다.

- Taskrun은 Task를 실행하면서 parameter를 넘길 수 있습니다. 

- Task는 여러개의 Step을 가질 수 있습니다. 

 

그럼 간단한 예제를 이용하여 Task와 Taskrun을 이해해 보도록 합시다.

예제 Task는 2개를 만들어 보도록 하겠습니다.

1) build-image: gitlab의 hello1 project의 소스를 가져와 image를 생성한 후 docker.io에 push합니다.

- container image는 docker가 아닌 kaniko라는 툴을 사용합니다.

- image의 경로(예: happycloudpak/hello1:0.1.2)는 파라미터로 받아 동적으로 바꿉니다. 

2) deploy-image: gitlab의 hello1 project의 deploy.yaml을 이용하여 배포합니다.

- image의 경로(예: happycloudpak/hello1:0.1.2)는 파라미터로 받아 deploy.yaml의 image경로를 바꾼 후 배포합니다. YAML내의 image 경로를 바꾸는 툴은 yq를 이용합니다.

 


프로젝트 디렉토리를 작성합니다. 여기서는 아래와 같이 ~/tekton/start라는 디렉토리로 하겠습니다.

$ mkdir -p ~/tekton/start

$ cd ~/tekton/start

namespace를 tekton으로 만들고, 현재 namespace도 tekton으로 바꾸겠습니다. 

$ kubectl create namespace tekton

$ kubectl config set-context $(kubectl config current-context) --namespace tekton

kubectl명령에 alias를 부여하여 'k'로 실행하도록 설정도 하겠습니다. https://happycloud-lee.tistory.com/

$ sudo ln -s /usr/bin/kubectl /usr/local/bin/k

 

1. Pipeline Resource생성

git 유형의 resource와 image유형의 resource를 먼저 만듭니다. 

1) git-hello1

아래 내용으로 git-rs.yaml파일을 만듭니다.

apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: git-hello1
  namespace: tekton
spec:
  type: git
  params:
    - name: revision
      value: master
    - name: url
      value: https://gitlab.com/happycloudpak/hello1

https://gitlab.com/happycloudpak/hello1 을 브라우저에 쳐 보십시오.

noede.js로 개발된 간단한 프로그램입니다. 

deployment폴더를 클릭해 보면 하위에 Dockerfile과 deploy.yaml이 있는걸 확인할 수 있습니다.

 

git-hello1 resource를 생성합니다.

$ kubectl apply -f git-rs.yaml 

 

2) image-hello

container image 리소스를 만듭니다. 아래 내용으로 docker-image-rs.yaml파일을 만듭니다.

apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: image-hello1
  namespace: tekton
spec:
  type: image
  params:
    - name: url
      value: happycloudpak/hello1:0.0.2

image-hello1 리소스를 생성합니다.

$ kubectl apply -f docker-image-rs.yaml

 

 

2. TASK: build-image

1) Task yaml 생성

아래 내용으로 build-image-task.yaml 파일을 만듭니다.

apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
  name: build-image
  namespace: tekton
spec:
  inputs:
    resources:
      - name: hello1
        type: git
    params:
      - name: pathToDockerFile
        type: string
        description: The path to the dockerfile to build        
      - name: pathToContext
        type: string
        description:
          The build context used by Kaniko
          (https://github.com/GoogleContainerTools/kaniko#kaniko-build-contexts)
        
  outputs:
    resources:
      - name: builtImage
        type: image
  steps:
    - name: build-and-push
      image: gcr.io/kaniko-project/executor:v0.14.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=$(inputs.params.pathToDockerFile)
        - --destination=$(outputs.resources.builtImage.url)
        - --context=$(inputs.params.pathToContext)

이 Task는 kaniko라는 툴로 container image를 만들어 docker.io에 push하는 것입니다.

steps: > build-and-push에 보면 이를 수행하는 명령이 있습니다. 

- gcr.io/kaniko-project/executor:v0.14.0 이미지로 container를 생성합니다.

- container안에서 파라미터에 따라 아래 예제와 같은 명령이 수행될것입니다. 파라미터는 Taskrun리소스에 정의될것입니다. 이 명령은 /workspace/hello1/deployment/Dockerfile을 이용해서 image를 만든 후, happycloudpak/hello1:0.0.2로 docker registry 푸시합니다. happycloudpak앞에 registry 주소가 없으므로 index.docker.io에 푸시됩니다. 

$ /kaniko/executor \

--dockerfile=deployment/Dockerfile \

--destination=happycloudpak/hello1:0.0.2

--context=/workspace/hello1

파라미터 값은 Taskrun에서 정의한다고 하니 이해 되지만, 누가 git에서 소스를 갖고 와서 Dockerfile을 생성했을까요 ? 

일단 input으로 hello1이라는 git유형의 리소스를 정의했기 때문이라고 이해하고 넘어 갑시다.

 

2) Taskrun YAML생성

이번에는 이 Task를 실행할 Taskrun을 만들어 봅시다. 아래 소스로 build-image-taskrun.yaml이라는 파일을 만드십시오.

apiVersion: tekton.dev/v1alpha1
kind: TaskRun
metadata:
  name: build-image-taskrun
spec:
  serviceAccountName: tutorial-service
  taskRef:
    name: build-image
  inputs:
    resources:
      - name: hello1
        resourceRef:
          name: git-hello1
    params:
      - name: pathToDockerFile
        value: deployment/Dockerfile
      - name: pathToContext
        value: /workspace/hello1
  outputs:
    resources:
      - name: builtImage
        resourceRef:
          name: image-hello1

- 실행할 Task를 'taskRef'라는 key로 정의했습니다.

- input 리소스 hello1이 'git-hello1'이라는 resource임을 정의 했습니다.  그리고 파라미터로 Dockerfile의 위치와 Base 디렉토리를 정의했습니다. 

- output 리소스 buildImage는 'image-hello1'이라는 resource임을 정의 했습니다.

- serviceAccountName이 'tutorial-service'으로 정의했습니다. 이 Service Account로 Task를 실행하는것이므로 이 계정에 적절한 권한을 부여해 줘야 합니다.

 

3) Service Account에 권한 부여

docker.io에 로그인할 secret을 생성합니다. username, password, email은 본인껄로 바꾸셔야 합니다.

$ kubectl create secret docker-registry regcred \
                    --docker-server=index.docker.io \
                    --docker-username=happycloudpak \
                    --docker-password=happy@cloud \
                    --docker-email=happycloudpak@gmail.com

'tutorial-service'라는 service account를 만들면서, 사용할 secret을 위에서 만든 regcred로 지정합니다.

아래와 같은 내용으로 sa.yaml을 만드십시오.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: tutorial-service
  namespace: tekton  
secrets:
- name: regcred

Serviece Account를 생성하십시오.

$ kubectl apply -f sa.yaml

 

4) Task 실행

자 이제 실행해 봅시다.

$ kubectl apply -f build-image-task.yaml

$ kubectl apply -f build-image-taskrun.yaml

Tekton CLI인 'tkn'과 'kubectl'로 생성된 리소스를 확인 해 봅시다.

$ tkn task list 또는 tkn t list

$ tkn taskrun list 또는 tkn tr list

$ kubectl get task 

$ kubectl get taskrun 또는 kubectl get tr

 

아래 명령으로 Task가 모두 실행될때까지 기다려 봅시다.

$ watch tkn tr list

 

※ 재실행하기

yaml의 내용을 수정한 후 다시 적용하려면 taskrun 리소스를 삭제하고 kubectl apply -f <yaml path>을 수행해야 합니다. 

예를 들어 build-image-task.yaml 파일을 수정했다면 아래와 같이 해야 수정 사항이 적용 됩니다.

$ tkn tr delete build-image-taskrun

$ kubectl apply -f build-image-task.yaml

$ kubectl apply -f build-image-taskrun.yaml

 

5) 동작원리 이해하기

자 이제 이게 어떻게 돌아가는지 k8s web dashboard의 로그를 보면서 이해해 봅시다.

dashboard를 로그인합니다. web dashboard 생성과 로그인은 이 글을 참조하십시오.

https://happycloud-lee.tistory.com/36?category=832243

 

k8s Multi node 설치 후 web dashboard 설정

https://hiondal.blog.me/221624274450 k8s Multi node 설치 후 web dashboard 설정 web dashboard를 설치하면, CLI로 할 수 있는 대부분을 할 수 있을 뿐 아니라 디버깅을 하는데 매우 편... blog.naver.com

happycloud-lee.tistory.com

좌측에서 Namespace를 변경하고, Pods를 클릭하면 우측과 같이 build-image-taskrun-pod로 시작하는 Pod가 있을것입니다. 클릭하여 세부정보를 봅니다.

 

하단의 Containers와 Init containers항목을 보십시오. 

그 위에 Event를 쭉 읽어보면 알겠지만, 작업 순서는 Init containers 2개가 먼저 실행되고, Containers하위의 4개 container가 순서대로 실행됩니다. 

Containers의 4개 container에서 1번째와 4번째는 정확히 어떤 역할을 하는지 모르겠으나, 그리 중요한것 같지는 않습니다. 2번째가 git에서 소스를 갖고 오는 container이고, 3번째가 kaniko로 image를 만들고 registry에 push하는 container입니다. 

내부 log를 한번 봅시다.  상단 우측의 '로그'아이콘을 클릭합니다.

상단에서 2번째 container를 선택하면, 해당 container의 로그가 나옵니다. gitlab의 hello1 소스를 container내의  /workspace/hello1디렉토리로 갖고 옵니다. 왜 /workspace/hello1 디렉토리로 갖고 올까요 ?

Taksrun에서 아래와 같이 pathToContext의 값을 /workspace/hello1으로 했기 때문입니다. /workspace는 고정값이고, hello1은 resource의 이름과 반드시 같습니다. 즉, git에서 /workspace/<resource name>디렉토리로 가져 오는 것입니다.

 

3번째 container의 로그를 보면 아래와 유사하게 image가 build되는걸 볼 수 있습니다. registry에 push하는건 콘솔에 보이질 않습니다만, 내부적으로는 그것까지 실행됩니다.

이는 Task에서 정의한대로 kaniko/executor명령이 실행되었기 때문입니다.

 

6) image 업로드 확인

https://hub.docker.com/에 들어 가시면 아래와 같이 image가 잘 업로드된것을 확인할 수 있습니다.

 


2. TASK: deploy-image

 

두번째 Task인 deploy-image를 작성해 봅시다. 

1) Task YAML 작성

아래 소스로 deploy-image-task.yaml파일을 작성합니다.

apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
  name: deploy-image
  namespace: tekton
spec:
  inputs:
    resources:
      - name: hello1
        type: git
      - name: image
        type: image
    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)
  steps:
    - name: replace-image
      image: mikefarah/yq
      command: ["yq"]
      args:
        - "w"
        - "-i"
        - "$(inputs.params.path)"
        - "$(inputs.params.yamlPathToImage)"
        - "$(inputs.resources.image.url)"
    - name: run-kubectl
      image: lachlanevenson/k8s-kubectl
      command: ["kubectl"]
      args:
        - "apply"
        - "-f"
        - "$(inputs.params.path)"

Pipeline resource에 대해선 build-image TASK에서 설명했으니, 이해가 되실것이구요. 

첫번째 step인 'replace-image'가 하는일만 설명하겠습니다.  실제 들어오는 값으로 치환해 보면 아래와 같습니다.

yq w -i /workspace/hello1/deployment/deploy.yaml  spec.template.spec.containers[0].image happycloudpak/hello1:0.0.2   

즉, deploy.yaml내에서 spec.template.spec.containers[0].image 의 값을 'happycloudpak/hello1:0.0.2'으로

바꿔줍니다.

이렇게 해야 버전업을 할때 image-hello1리소스(docker-image-rs.yaml에 정의)에서 tag를 변경하면 변경된 image가 build & deploy되게 됩니다. 

 

2) Taskrun YAML 작성

아래 소스로 deploy-image-taskrun.yaml파일을 작성합니다.

apiVersion: tekton.dev/v1alpha1
kind: TaskRun
metadata:
  name: deploy-image-taskrun
spec:
  serviceAccount: tutorial-service
  taskRef:
    name: deploy-image
  inputs:
    resources:
      - name: hello1
        resourceRef:
          name: git-hello1
      - name: image
        resourceRef:
          name: image-hello1
    params:
      - name: path
        value: /workspace/hello1/deployment/deploy.yaml
      - name: yamlPathToImage
        value: "spec.template.spec.containers[0].image"

build-image-taskrun.yaml에서 설명했으므로 위 taskrun 소스는 잘 이해 되실겁니다. 

다만, build-image에서 설명 안한 resource name규칙만 추가 하겠습니다. 

Taskrun에서 정의한 resource name과 Task에 정의한 resource name은 반드시 동일해야 합니다. 

Taskrun Task



3) deploy-image TASK 실행

$ kubectl apply -f deploy-image-task.yaml

$ kubectl apply -f deploy-image-taskrun.yaml

아래 명령으로 진행 상황을 모니터링 합니다. 

$ watch tkn tr list

완료 되면, 아래 명령으로 log를 확인해 봅니다.

$ tkn tr logs deploy-image-taskrun 

Pod도 deploy.yaml에 정의한대로 2개가 잘 생성 되었을겁니다.

$ kubectl get pod

 

4) 결과 확인

ingress까지 생성되어 있으니, 웹 브라우저에서 ingress 주소로 접근해 봅니다.

$ kubectl get ing 

Host를 정하지 않았으니, 아무 node주소로 접근해도 되네요.

$ kubectl get nodes -o wide

위 예제에서는 3개 node 아무 ip로 접근해도 됩니다. 

웹브라우저에서 http://169.56.115.153 으로 접근하면 아래와 같이 제대로 표시가 될 겁니다.

 

수고하셨습니다.

 

 

'Agile&DevOps > Tekton' 카테고리의 다른 글

6. Conditions  (0) 2019.12.13
5. Pipeline Resource  (0) 2019.12.13
4. Pipeline & PipelineRun  (0) 2019.12.13
2. Tekton 설치하기  (0) 2019.12.13
1. Tekton 이란 ?  (0) 2019.12.12
댓글

전자책 출간 알림 [마이크로서비스패턴 쉽게 개발하기]