Zum Hauptinhalt springen

CI/CD 파이프라인

Lumie의 CI/CD는 Tekton Pipelines로 구성됩니다. Gitea(github.lumie-infra.com)에 코드가 푸시되면 웹훅이 Tekton EventListener를 호출하고, Kaniko로 컨테이너 이미지를 빌드하여 Zot 레지스트리에 푸시한 뒤, lumie-infra 레포의 common-values.yaml을 업데이트하면 ArgoCD가 자동으로 클러스터를 동기화합니다.

중요: Tekton의 git-update-values 태스크는 내부 Gitea 서비스 URL(http://gitea-http.gitea.svc.cluster.local:3000/Lumie-Edu/lumie-infra.git)을 사용합니다. github.lumie-infra.com(Teleport 경유)이 아닙니다. 커밋 author는 Tekton CI입니다.

전체 흐름


파이프라인 목록

파이프라인 이름대상빌드 도구
lumie-springboot-build-deploylumie-backend (Spring Boot 모노리스)Kaniko
fastapi-build-deployWorker 서비스 (grading, report, analysis, chatbot 등)Kaniko
nextjs-build-deploylumie-frontend, lumie-documentKaniko

lumie-springboot-build-deploy

백엔드 모노리스 전용 파이프라인입니다. lumie-backend 레포에 푸시되면 단일 PipelineRun이 생성됩니다. springboot-ci 태스크가 Gradle 테스트 → Kaniko 빌드를 순서대로 수행합니다.

# 파이프라인 파라미터 (TriggerTemplate에서 주입)
params:
- git-url: https://github.com/Lumie-Edu/lumie-backend.git
- git-revision: main # 브랜치명 (이미지 태그로도 사용)
- service-name: lumie-backend
- context-dir: . # 레포 루트에서 빌드
- dockerfile-path: Dockerfile
- image-prefix: applications/
- update-values: "true"
- values-file-path: applications/lumie/backend/common-values.yaml
- informational: "false" # false = 테스트 실패 시 빌드 중단

빌드 타임아웃: 45분 (tasks.ci.timeout: "40m")

informational 파라미터가 "true"이면 Gradle 테스트 실패가 경고로 기록되고 Kaniko 빌드는 계속됩니다. "false"(기본값)이면 테스트 실패 시 파이프라인이 중단됩니다.

fastapi-build-deploy

lumie-worker 레포 내 서비스별 디렉토리 변경을 CEL 필터로 감지하여 개별 PipelineRun을 실행합니다.

서비스감지 경로values 파일
grading-svcservices/grading/applications/lumie/worker/grading-svc/common-values.yaml
report-svcservices/report/applications/lumie/worker/report-svc/common-values.yaml
analysis-svcservices/analysis/applications/lumie/worker/analysis-svc/common-values.yaml
chatbot-svcservices/chatbot/applications/lumie/worker/chatbot-svc/common-values.yaml
temp-omr-gradingservices/temp-omr-grading/(values 업데이트)

빌드 타임아웃: 30분

nextjs-build-deploy

lumie-frontend, lumie-document 레포를 처리합니다.


Tekton 트리거 구성

EventListener

모든 Gitea 레포에서 오는 웹훅은 단일 github-listener EventListener로 수신됩니다.

# 트리거 목록 (주요)
triggers:
- github-push-lumie-backend # lumie-backend 레포 → lumie-backend-build-template
- github-push-lumie-frontend # lumie-frontend 레포 → lumie-frontend-build-template
- github-push-lumie-document # lumie-document 레포 → lumie-document-build-template
- github-push-fastapi # joossam(AI) 레포 → fastapi-build-template
- github-push-lumie-grading-svc
- github-push-lumie-report-svc
- github-push-lumie-chatbot-svc
- github-push-lumie-analysis-svc

필터링 (CEL)

모든 트리거는 두 개의 CEL 인터셉터를 통과합니다:

  1. 이벤트 + 브랜치 필터: header.match('X-Gitea-Event', 'push') && body.ref.startsWith('refs/heads/main') — Gitea push 이벤트 + main 브랜치만 처리
  2. 레포/경로 필터: 레포 이름 또는 변경 파일 경로를 기준으로 라우팅
# Worker 서비스 경로 기반 필터 예시 (grading)
- name: "filter"
value: >
body.repository.name in ['lumie-worker'] &&
body.commits.exists(c,
c.added.exists(f, f.startsWith('services/grading/')) ||
c.modified.exists(f, f.startsWith('services/grading/'))
)

HMAC 검증

Gitea 웹훅 시크릿은 github-webhook-secret Kubernetes Secret에 저장됩니다. 모든 요청은 서명 검증 후 처리됩니다.


Tekton Task 상세

kaniko-clone-build-github

소스 코드를 Gitea에서 clone하고 Kaniko로 이미지를 빌드하여 Zot에 푸시합니다.

# 주요 파라미터
params:
- GIT_URL: 소스 레포 URL
- GIT_REVISION: 브랜치명 (이미지 태그로 사용됨)
- IMAGE: zot.lumie-infra.com/applications/<app-name>
- TAG: git-revision 값 (브랜치명)
- CONTEXT: 빌드 컨텍스트 디렉토리
- DOCKERFILE: Dockerfile 경로

# 결과
results:
- IMAGE_TAG: 푸시된 이미지 태그 (다음 태스크로 전달)

Docker 데몬 없이 컨테이너 내부에서 이미지를 빌드합니다.

git-update-values

Kaniko 빌드 성공 후 lumie-infra 레포의 values 파일에서 image.tag 값을 업데이트하고 커밋/푸시합니다.

params:
- VALUES_FILE_PATH: 업데이트할 values 파일 경로 (콤마 구분 다중 지원)
- IMAGE_DIGEST: 새 이미지 태그 (kaniko-clone-build-github 결과)
- APP_NAME: 앱 이름 (커밋 메시지에 사용)
- YQ_PATH: 업데이트할 YAML 경로 (기본: .image.tag)

커밋 메시지 형식: CHORE(app): update <app-name> image to <tag> (author: Tekton CI, email: tekton@lumie.local)

동시 푸시 충돌 시 최대 5회 재시도 + git pull --rebase로 자동 복구합니다.


이미지 태그 전략

이미지 태그는 Git 브랜치명을 사용합니다. main 브랜치에서 빌드하면 태그는 main입니다.

zot.lumie-infra.com/applications/lumie-backend:main

values 파일에 기록되는 실제 태그는 커밋 SHA입니다 (kaniko 빌드 결과 IMAGE_TAG):

# common-values.yaml 업데이트 후
common:
image:
tag: "3ba13d48" # 커밋 SHA 앞 8자리

네임스페이스 및 리소스 쿼터

모든 파이프라인은 tekton-pipelines 네임스페이스에서 실행됩니다. 리소스 쿼터가 설정되어 동시 빌드 수를 제한합니다.

# 실행 중인 PipelineRun 확인
kubectl get pipelinerun -n tekton-pipelines

# 완료된 PipelineRun (자동 삭제: onSuccessfulCompletion: delete)
# 실패한 PipelineRun은 보존됩니다

# 실패한 PipelineRun 로그 확인
kubectl logs -n tekton-pipelines -l tekton.dev/pipelineRun=<run-name>

# Tekton Dashboard 접근 (Teleport App Access)
# https://tekton.lumie-infra.com

새 서비스 CI/CD 추가 방법

  1. eventlistener.yaml에 새 트리거 추가:
- name: github-push-my-service
interceptors:
- ref:
name: "github"
params:
- name: "secretRef"
value:
secretName: github-webhook-secret
secretKey: webhook-secret
- name: "eventTypes"
value: ["push"]
- ref:
name: "cel"
params:
- name: "filter"
value: "body.ref.startsWith('refs/heads/main')"
- ref:
name: "cel"
params:
- name: "filter"
value: "body.repository.name in ['my-service-repo']"
bindings:
- ref: github-push-binding
template:
ref: my-service-build-template
  1. triggertemplate.yaml에 TriggerTemplate 추가 (파이프라인 파라미터 정의)

  2. Gitea 레포의 Webhook 설정에 EventListener URL 등록

  3. lumie-infra에 해당 서비스 ArgoCD Application 추가


관련 문서