
6.0 들어가며
쿠버네티스 시대의 CI/CD는 더 이상 외부의 빌드 서버(Jenkins 등)에 작업을 던져놓고 결과물을 받아오는 방식만으로 끝나지 않는다.
빌드, 테스트, 이미지 생성, 보안 스캔, 매니페스트 렌더링, 실제 배포(쿠버네티스 apply/upgrade), 심지어 Git에 결과를 기록하고 PR을 만드는 것까지 전부 클러스터 내부에서 일어날 수 있다.
이 장은 그 전체 체인을 Tekton(텍톤), Kustomize, Helm, 그리고 GitHub Actions까지 연결해서 보여준다:
- 텍톤 설치 → Task → Pipeline → Trigger
- 빌드/패키징/이미지 푸시
- 쿠버네티스 배포
- 변경 내용을 Git에도 반영 (GitOps 스타일 업데이트)
- 마지막으로 GitHub Actions로 비교/연계
6.1 텍톤 설치
텍톤(Tekton)은 쿠버네티스에서 돌아가는 오픈소스 클라우드 네이티브 CI/CD 시스템이다.
Tekton은 다음과 같은 CRD(사용자 정의 리소스) 기반 컴포넌트를 제공한다:
- Task / TaskRun
- Pipeline / PipelineRun
- Trigger
- (추가적으로 Dashboard, CLI 등)

구조적으로 Tekton은 “쿠버네티스 리소스를 선언하면 그걸 파드로 실행해주는 CI/CD 엔진”이라고 볼 수 있다. 빌드/패키징/배포 흐름이 전부 쿠버네티스 내부에서 실행되기 때문에, 외부 빌드 서버 없이도 완전한 CI/CD를 구성할 수 있다.
설치 방식은 실제로 네임스페이스(tekton-pipelines 등)에 Tekton Pipelines, Triggers, Dashboard, CLI까지 배포하는 흐름으로 진행된다.
순서는 보통 다음과 같다:
- Tekton Pipelines CRD/컨트롤러 설치
- Tekton Triggers 설치
- Tekton Dashboard 설치 (웹 UI로 실행 상태/로그 확인)
- tkn CLI 설치 (로컬 개발자/운영자가 Tekton 리소스를 관리하고 로그 보는 데 사용)
설치 후에는 다음 리소스들이 떠 있는 것을 확인한다:
- tekton-pipelines-controller, tekton-pipelines-webhook, tekton-triggers-controller, tekton-dashboard 등
- CRD로 tasks.tekton.dev, pipelines.tekton.dev, pipelineruns.tekton.dev, triggerbindings.triggers.tekton.dev, … 가 등록되어 있어야 한다
의견: 이 단계에서 이미 “빌드 서버 = 쿠버네티스 클러스터 그 자체”라는 구조가 확보된다. 이후 파이프라인이 실패하더라도 kubectl / tkn 으로 바로 파드 로그를 볼 수 있다는 점이 운영에 큰 이점이다.
6.2 "Hello World" Task
Tekton의 가장 작은 실행 단위는 Task다.
- Task = 순차적으로 실행되는 여러 step들의 묶음
- 각 step = 컨테이너 하나
- Task 전체 = 하나의 파드로 실행되며, step들이 그 파드 안에서 순차 실행됨
- Task 실행 결과 인스턴스는 TaskRun으로 관리됨
예제 Task (hello):
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: hello
spec:
steps:
- name: hello-wrold
image: alpine
script: |
#!/bin/sh
echo "Hello Ben World"
이 Task를 실행하려면 CLI에서 tkn task start hello-world --showlog 같은 식으로 TaskRun을 생성할 수 있다.
실행이 시작되면 Tekton은 파드를 만들고, 그 파드 안에서 step 컨테이너가 순차적으로 수행된다.
로그는 tkn taskrun logs 또는 kubectl logs로 확인 가능하다.
의견: 이 예제는 작은 “echo”지만, 실제로는 step 안에 빌드 도구(maven, npm, go build 등), 보안 스캐너, 이미지 빌더 등을 넣는 식으로 실전 작업을 구성하게 된다.
확장 예제로 step 2개짜리 Task(two-step)를 만들면 단일 TaskRun에서 두 개의 컨테이너(step-echo1, step-echo2)가 순차로 실행된 뒤 종료된다는 걸 볼 수 있다. 이게 파이프라인의 최소 단위다.
6.3 Git 저장소에 보관된 코드를 컴파일하고 패키징하는 Task
여기부터는 Task를 단독으로 돌리는 수준을 넘어, 여러 Task를 순서대로 실행하는 Pipeline으로 올라간다.
중요 개념 몇 가지:
- Pipeline: 여러 Task를 묶어서 “이 순서대로 실행해라”라고 선언한 것
- PipelineRun: 그 Pipeline을 실제로 한 번 실행한 인스턴스
- Workspace: Task 간에 공유되는 파일 시스템(PVC 등). 예: 첫 Task가 소스 코드를 체크아웃해 놓으면 다음 Task가 그 디렉터리에서 빌드를 수행
- Params: 파라미터(예: Git URL, 이미지 이름 등)를 외부에서 전달 가능하게 해준다
실습 흐름은 보통 이렇게 간다:
- git-clone Task를 사용해 Git 저장소를 클론한다
- 클론된 소스를 다른 Task에서 읽어 빌드/패키징한다
예제 Pipeline(clone-read 등)은 대략 이런 형태:
- params.repo-url: 어떤 Git repo를 가져올지
- workspaces.shared-data: 체크아웃된 소스가 놓일 PVC
- tasks.fetch-source: git-clone Task를 실행해 repo 코드 다운로드
- (추가 Task에서) 소스 내용을 읽거나 빌드
이 파이프라인을 PipelineRun으로 실행할 때는 다음을 지정한다:
- pipelineRef.name: 어떤 Pipeline을 돌릴지
- workspaces: PVC를 동적으로 생성해 Pipeline 전체에서 공유
- params: repo-url 등 실제 값
여기서 한 번 중요한 현실 이슈가 드러난다.
git-clone 같은 Task는 Tekton Pipelines 자체에 포함되는 게 아니라 “Tekton Catalog”에서 제공되는 공용 Task이기 때문에, 클러스터에 먼저 설치해야 한다. 즉, 팀 표준 Task들을 카탈로그에서 가져와 설치하고 버전 고정하는 관리가 필요하다.
의견: 이것부터가 사실상 ‘내부 빌드 플랫폼’ 설계다. 우리 조직 표준 git-clone, go-build, docker-build, kubectl-apply 같은 Task들을 사내 카탈로그로 관리하게 되면, 개발자들은 그냥 Pipeline을 조합만 하면 된다.
6.4 비공개 Git 저장소의 앱을 컴파일하고 패키징하는 Task
현실에서는 대부분의 소스 코드가 private repo에 있다. 따라서 CI/CD는 인증 문제를 해결해야 한다.
Tekton은 ServiceAccount + Secret 조합으로 Git 인증을 처리한다:
- SSH 키나 Personal Access Token(PAT)을 Secret으로 저장
- 해당 Secret을 특정 ServiceAccount에 연결
- PipelineRun 수행 시 taskRunTemplate.serviceAccountName으로 그 ServiceAccount를 사용하도록 지정
- git-clone Task 같은 Git 관련 Task가 그 ServiceAccount로 실행되면서 비공개 저장소에 접근
추가적으로, Pipeline에 git-credentials용 workspace를 만들어 그 Secret을 마운트해주는 패턴을 쓴다.
이 구조를 통해 Tekton은 private repo를 안전하게 clone하고, 이후 단계(step)에서 그 코드를 바로 빌드/패키징할 수 있다.
의견: 이 방식은 회사별로 GitHub, GitLab, 사내 Gitea 등 어디든 유효하다. 중요한 건 “누가 어떤 자격증명(Secret)으로 어떤 리포를 읽었는가”를 RBAC + ServiceAccount 레벨에서 통제할 수 있다는 점이다. 나중에 감사/보안 측면에서 굉장히 중요하다.
여기까지로 “소스 코드 가져오기 → 앱 빌드/패키징”까지는 Tekton 안에서 자동화된다.
6.5 텍톤 Task와 빌더를 통한 애플리케이션 컨테이너 이미지 생성

이제 빌드된 아티팩트로 컨테이너 이미지를 만들고 레지스트리에 push해야 한다. 이 부분이 기존 Jenkins 파이프라인의 Docker build/push 단계에 해당한다.
Tekton에서는 보통 다음과 같은 Task를 사용한다:
- kaniko (또는 buildah 등): Docker 데몬 없이 컨테이너 이미지를 빌드하고 레지스트리에 push할 수 있는 빌더
파이프라인 흐름 예:
- git-clone Task: 소스 가져오기
- kaniko Task: 해당 소스로 Dockerfile을 빌드하고, 결과 이미지를 레지스트리에 push
이때도 두 가지 포인트가 중요하다.
① 이미지 레지스트리 인증
- Docker Hub나 프라이빗 레지스트리에 push하려면, Docker config(~/.docker/config.json) 내용을 base64로 넣은 Secret을 만든다.
- 그 Secret을 ServiceAccount(build-sa 등)에 연결한다.
- PipelineRun 실행 시 그 ServiceAccount를 사용하면 kaniko Task가 해당 자격 증명을 이용해 push할 수 있다.
② workspace 공유
- git-clone이 내려받은 소스 코드 디렉터리(공유 workspace)를 kaniko Task에도 마운트한다.
- kaniko Task는 그 디렉터리에 있는 Dockerfile을 기반으로 이미지를 빌드하고, 파라미터로 받은 이미지 태그(image-reference)로 push한다.
의견: 여기서부터 Tekton은 더 이상 “CI만”이 아니다. 이미지는 결국 배포 단위이고, 이 이미지를 push하는 순간부터는 ‘운영 가능한 아티팩트’가 생긴다. 즉, Tekton은 빌드와 배포의 경계를 사실상 허물고 있다.
6.6 텍톤 Task를 통한 쿠버네티스 애플리케이션 배포
이미지가 만들어졌으면 이제 쿠버네티스 클러스터에 실제 애플리케이션(Deployment, Service 등)을 배포하게 된다.
여기서 Tekton Task는 단순하게 kubectl apply 역할을 할 수도 있다.
예를 들어 다음과 같은 Task를 둘 수 있다:
- 컨테이너 이미지 태그를 Deployment 매니페스트에 주입
- kubectl apply -f로 클러스터에 반영
- 롤링 업데이트 완료까지 대기 (옵션)
이 Task는 빌드 단계 이후에 실행되며, Pipeline 차원에서는 “빌드 → 이미지 푸시 → 쿠버네티스 배포”가 한 번의 흐름으로 이어진다.
의견: 이 방식은 GitOps 이전 세대 스타일에 가깝다. CI/CD 파이프라인이 직접 클러스터에 apply한다. 단점은 ‘누가 언제 어떤 매니페스트를 apply했는가’를 Git 히스토리로 추적하기 어려울 수 있다는 점이다. 그래서 이후 단계(6.9, 6.10)에서 Git을 소스 오브 트루스로 끌어들이는 방향으로 확장한다.
6.7 텍톤 파이프라인을 통한 앱 빌드 및 쿠버네티스 배포

여기서는 6.3 ~ 6.6의 내용을 하나의 Pipeline으로 묶는다.
전형적인 형태:
- 소스 코드 클론 (git-clone)
- 애플리케이션 컴파일/패키징 (예: Maven, npm build 등)
- 컨테이너 이미지 빌드 및 레지스트리 푸시 (kaniko 등)
- 쿠버네티스에 배포 (kubectl apply 역할을 하는 Task)
PipelineRun 한 번으로 “새 코드 → 새 이미지 → 새 배포”까지 이어지는 CI/CD 전체 흐름이 실행된다.
의견: 이 상태만으로도 이미 Jenkins에서 흔히 하던 CI/CD 파이프라인을 Tekton으로 대체할 수 있다. 차이가 있다면 Tekton은 쿠버네티스 네이티브 모델이라 파이프라인의 Task 하나하나가 쿠버네티스 리소스로 남고, 파드 로그로 디버깅할 수 있다는 점이다. 이건 운영/관찰성 측면에서 큰 차이다.
6.8 텍톤 트리거를 사용한 Git 변경 사항 자동 컴파일 및 배포

지금까지는 수동으로 PipelineRun을 만들었다. 실제 운영에서는 Git에 변경이 push되었을 때 자동으로 Pipeline을 돌려야 한다.
Tekton Triggers의 역할이 바로 이 부분이다.
구성 요소 개념:
- EventListener: 외부 이벤트(보통 웹훅 HTTP 요청)를 받는 엔드포인트
- TriggerBinding / TriggerTemplate: 들어온 이벤트 payload에서 어떤 값을 추출할지, 그리고 그 값으로 어떤 PipelineRun을 생성할지 정의
흐름은 이렇게 된다:
- Git 저장소(예: GitHub)에서 push/pull request 등 이벤트가 발생
- Git 웹훅이 Tekton EventListener로 HTTP POST 전송
- Trigger가 payload에서 repo URL, 브랜치, 커밋 SHA 등을 뽑는다
- 이 값을 바탕으로 PipelineRun을 자동 생성 → 빌드 → 이미지 푸시 → (필요하면) 배포까지 자동으로 진행
즉 “코드가 바뀌면 자동으로 컨테이너 이미지가 새로 빌드되고, 쿠버네티스에 새 버전이 올라간다.”
의견: 이 시점에서 Tekton은 완전히 Git 기반 자동화로 전환된다. 사람이 tkn을 치지 않아도 된다. 결과적으로 개발자는 그냥 git push만 하면 되고, 클러스터는 변경된 코드로 새 이미지를 만들고 새 배포를 반영한다. 조직 입장에서는 Dev→Prod 승인을 어떻게 붙일지(특정 브랜치만 자동 배포? 태그만 배포?) 같은 거버넌스 설계가 필요하다.
6.9 커스터마이즈로 쿠버네티스 리소스를 갱신하고 Git에 저장
여기부터는 GitOps스럽게 간다.
지금까지는 파이프라인이 직접 kubectl apply를 실행했다.
이제는 이렇게 바꿀 수 있다:
- 현재 운영 중인 쿠버네티스 매니페스트(Deployment, Service 등)를 Git에 선언적으로 보관한다.
- Tekton 파이프라인은 새 이미지 태그(예: my-app:1.2.3)를 Kustomize overlay에 주입해 YAML을 갱신한다.
- 변경된 매니페스트를 Git 리포지토리에 커밋/푸시한다.
즉, 파이프라인의 결과는 “업데이트된 쿠버네티스 선언”이다.
이 선언을 기준으로 Argo CD나 Flux 같은 GitOps 컨트롤러가 실제 클러스터를 동기화한다는 구조로 확장할 수 있다.
의견: 이는 조직적인 거버넌스에 매우 적합한 모델이다. 실제 배포 상태를 Git이 단일 소스로 갖게 되므로, 누가 언제 어떤 이미지를 운영에 올렸는지 Git 히스토리로 감사 가능하다. CI/CD가 곧 변경 관리 시스템(Change Management System)이 된다.
6.10 헬름을 사용한 쿠버네티스 리소스 업데이트 및 PR 생성
Kustomize 대신 Helm 차트를 쓰는 조직도 많다.
여기서는 Tekton 파이프라인이 Helm 차트의 values 또는 Chart 버전 등을 업데이트한 뒤, 그 변경 사항을 새로운 브랜치에 커밋하고 Pull Request(PR)를 생성하는 방식까지 간다.
흐름은 예를 들면 다음과 같다:
- 이미지 빌드 후 새 태그가 나왔다 (my-service:1.3.0)
- Tekton이 Helm 차트의 values.yaml (예: .image.tag) 값을 1.3.0으로 갱신
- 이 변경 내용을 Git 브랜치로 push하고, PR을 자동 오픈
- PR 승인/머지가 끝나면 GitOps(Argo CD 등) 또는 후속 Tekton 파이프라인이 실제로 배포 반영
이 구조는 “운영 환경으로의 배포”를 Pull Request 승인을 통해 관리할 수 있게 만든다.
즉, 배포 승인 자체가 코드 리뷰 프로세스에 들어온다.
의견: 이 방식은 규제 산업(금융, 의료 등)에서 특히 선호된다. 운영 반영은 반드시 코드 리뷰/PR 머지 후에만 일어나고, 모든 변경은 Git에 기록이 남아 추적 가능하기 때문이다. Helm이 이미지를 포함한 배포 구성을 패키징해준다는 점도 관리 측면에서 유리하다.
6.11 GitHub 액션을 통한 CI 구현
마지막으로, Tekton이 전부라고 가정할 필요는 없다.
GitHub Actions 같은 SaaS형 CI도 Git 이벤트 기반으로 워크플로우를 실행하고, 컨테이너 이미지를 빌드하고, 쿠버네티스에 배포하거나 매니페스트를 업데이트하는 일을 할 수 있다.
두 가지 관점에서 비교할 수 있다:
- Tekton
- 쿠버네티스 네이티브.
- 모든 실행이 클러스터 내부 파드로 일어난다.
- RBAC, NetworkPolicy, Secret 관리 등 조직 인프라 정책을 그대로 적용할 수 있다.
- 멀티클라우드/온프렘/사내망 환경에서도 동일한 방식으로 동작한다.
- GitHub Actions
- GitHub에 밀접하게 통합되어 있어, PR 기반 워크플로우/코드 리뷰/권한 모델과 자연스럽게 맞물린다.
- Marketplace 액션을 쉽게 조합해서 빌드, 테스트, 린트, 이미지 푸시, 차트 업데이트, PR 생성 등을 구현할 수 있다.
- 쿠버네티스에 접근시키려면 kubeconfig나 OIDC 기반 접근 권한을 runner에 제공하는 방식으로 통합한다.
의견: 실제로는 두 시스템을 혼합하는 경우가 많다. 예를 들어 GitHub Actions에서 기본 테스트/린트/단위 빌드를 돌리고, 최종적으로 승인된 코드만 Tekton Trigger를 통해 클러스터 내부 빌드·배포 파이프라인으로 흘려보내는 식이다. 이렇게 하면 사내 클러스터 안에서만 접근 가능한 비공개 레지스트리나 내부 인프라 의존성도 안전하게 처리할 수 있다.
정리
이 장에서 한 흐름은 아래와 같이 한 줄로 요약된다.
- 클러스터 안에 Tekton을 설치해 CI/CD 엔진을 올린다.
- Task → Pipeline → PipelineRun으로 소스 클론, 빌드, 이미지 푸시, 배포까지 자동화한다.
- Triggers로 Git 이벤트에 반응해 이 파이프라인을 자동 실행한다.
- 배포 결과(쿠버네티스 매니페스트 변경)를 Git에 다시 기록하고, Kustomize나 Helm 차트를 업데이트하고, PR까지 자동으로 생성한다.
- 최종적으로 GitHub Actions 같은 외부 CI와도 연동할 수 있다.
의견: 한마디로 말하면 “쿠버네티스 자체가 CI/CD 플랫폼이 된다”는 시나리오다. 더 나아가 Git이 최종 상태를 정의하고, Tekton은 그 정의를 자동으로 갱신하는 엔진 역할을 하며, PR과 승인 과정을 통해 배포 거버넌스까지 코드 리뷰로 흡수하게 된다. 이것이 현대적인 GitOps형 클라우드 네이티브 배포 전략의 본질이다.
'스터디(Study) > CI·CD Study' 카테고리의 다른 글
| GitOps Cookbook 8장: 고급 주제 (0) | 2025.11.01 |
|---|---|
| GitOps Cookbook 7장: Argo CD (0) | 2025.11.01 |
| GitOps Cookbook 5장: 헬름 (0) | 2025.10.25 |
| GitOps Cookbook 4장: 커스터마이즈 (0) | 2025.10.18 |
| GitOps Cookbook 3장: 컨테이너 (0) | 2025.10.18 |
댓글