Skip to content
Sunghyun Kim edited this page Feb 24, 2021 · 2 revisions

CI/CD Operator 소개

컨셉

  • Tekton Pipeline + Trigger 를 하나의 YAML 파일로 설정!
  • Github, Gitlab 과 연동해 파이프라인 진행 상태를 Git 페이지에서 확인 가능
  • 특정 태스크의 완료/실패 시 알림 기능도 있고
  • PullRequest에 /test /retest 댓글로 Pipeline 전체 재실행, 특정 태스크만 선택적 실행 가능

CRD

  • IntegrationConfig
    • Pipeline을 정의하고 언제 그 파이프라인이 실행돼야 할 지 결정함
    • GitHub workflows의 설정 yaml과 같은 역할
  • IntegrationJob
    • PullRequest, Push, Tag 이벤트 발생 시 자동으로 생성되는 오브젝트.
    • 하나의 IntegrationJob은 하나의 PipelineRun을 생성.
    • CI/CD Operator에는 동시 실행 가능한 최대 PipelineRun 수를 제한하기 때문에 Git 이벤트 큐 역할을 함.
    • 기본적으로 Pending 상태로 생성되며 (PipelineRun 생성 X), Scheduler에 의해 PipelineRun이 만들어지면 Running. 끝나면 Succeeded/Failed 상태가 됨.
  • Approval
    • 특정 사용자에게 승인을 요청하는 CRD

흐름

  1. 사용자가 IntegrationConfig 설정 (GitHub/GitLab 주소 및 access token도 작성)
  2. IntegrationConfig Controller (/controllers/integrationconfig_controller.go)가 GitHub/GitLab에 웹훅 주소 자동 등록.
    • 이 주소는 /webhook/<네임스페이스>/<IntegrationConfig이름> 형태
  3. 사용자가 GitHub/GitLab에서 Pull Request 작성
  4. 웹훅 서버로 (/pkg/server) Pull Request 이벤트 전달됨
  5. Git 패키지 (/pkg/git/[gitlab|github])에서 해당 이벤트 json을 공통 Webhook struct (/pkg/git)로 변환
  6. 웹훅 서버에 Handler로 등록된 Dispatcher (/pkg/dispatcher)가 웹훅 이벤트를 가져가서 처리함.
    1. 해당 웹훅 이벤트에 해당하는 IntegrationConfig를 Get해와 PullRequest 때 실행돼야 하는 .spec.jobs.presubmit 태스크들을 가져옴
      (Push/Tag 이벤트일 경우 .spec.jobs.postsubmit)
    2. 그 jobs 중 when 필드에 해당되는 애들만 필터링함 (e.g., when.branch[0] = master인데 Pull Request는 test 브랜치 타겟이라면 그 job은 제외함)
    3. 필터링에서 통과한 jobs들을 넣어 IntegrationJob 생성 (초기상태: Pending)
  7. IntegrationJob이 생성됐으니 Controller (/controllers/integrationjob_controller.go)가 감지해 Scheduler (/pkg/scheduler)로 signal 보냄
  8. Scheduler는 IntegrationJob 생성/상태 변경/삭제 등이 일어날 때마다 controller로부터 signal을 받아서 Pending중인 IntegrationJob 중 우선순위가 높은걸 골라 실행 (PipelineRun 생성)
    • 현재는 FIFO만 지원
    • 동시 실행 가능한 PipelineRun 수를 제한 (cicd-config ConfigMap에 설정)하는 역할을 함
  9. IntegrationJob에 해당하는 PipelineRun의 spec은 Pipeline Manager (/pkg/pipelinemanager)에서 생성함. Create 자체는 Scheduler에서.
    • Pipeline 없이 PipelineRun의 .spec.pipelineSpec에 모든 파이프라인/태스크 내용 때려박음
    • 모든 Job에 해당하는 TaskRun은 git-checkout 스텝이 포함되며 실제 job은 그 이후에 실행됨. (해당 job에 skipCheckout: true 설정된 경우 제외)
    • (Pull Request이벤트일 경우) git-checkout 스텝의 경우 Source 브랜치를 Target 브랜치 최신 커밋에 머지함.
      (Merge Conflict 있을 경우 이 단계에서 실패 - PullRequest인데 머지 안되는 코드면 테스트할 가치 없으니 리즈너블한 실패인듯)
  10. PipelineRun의 상태가 변경되는 경우 IntegrationJob Controller가 감지하고 Pipeline Manager의 ReflectStatus()를 콜함
    • PipelineRun의 상태를 IntegrationJob 상태에 반영함.
    • GitHub/GitLab에 Commit Status를 반영함 (각 Job 별로 진행중/성공/실패 등으로 표시)
    • 특정 Job 성공/실패에 대한 Notification 설정이 돼있을 경우 Notification 전송
    • IntegratinoJob에 대해 이벤트 생성
  11. 사용자가 Git Pull Request 페이지에서 파이프라인 진행 상황 확인.
  12. 사용자가 Git Pull Request 페이지에서 특정 Job 진행사항 디테일을 확인하기 위해 Details 클릭
  13. 레포트 서버 (/pkg/server)가 해당 리퀘스트를 handle함
    • ConfigMap에서 Report Template 가져와 IntegrationJob 상태 박아서 보여줌
    • 각 TaskRun Pod에 대한 로그도 수집해 보여줌
  14. 태스크가 일부 실해할 경우 사용자가 코드 수정해 해당 PullRequest에 커밋 추가
  15. 커밋 추가 시 자동으로 Pull Request에 대한 jobs 재실행
  16. 타겟 브랜치가 업데이트됐거나 어떤 이유로 테스트를 다시 해야 할 경우 사용자가 해당 Pull Request에 /test 댓글 등록
    • /test <Job 이름> 하면 그 Job, 그리고 그 잡이 dependant한 job들 같이 돌림
      e.g., B라는 Job의 .after[0] = A인데 /test B를 등록한 경우 A -> B 순서로 실행됨
    • /retest 또는 /test 시 전체 태스크 재실행
  17. 태스크 전체 성공 시 사용자가 Merge 클릭함
  18. 이 경우 Pull Request가 등록됐을 때와 동일한 프로세스 진행됨. 차이점은 IntegrationConfig의 .spec.jobs.postsubmit의 jobs가 실행된다는 점 뿐
  19. IntegrationJob 성공/실패 후 특정 시간이 지난 경우 Collector에 의해 삭제됨

내부 구성 요소

  • Git (/pkg/git)
    • GitHub/GitLab 과 통신하는 데 필요한 Structs 정의
    • Webhook으로 이벤트가 들어오면 GitLab/GitHub-specific한 struct로 unmarshal한 뒤 공통 structs로 변환.
    • 공통 Structs로 변환된 이후에는 해당 이벤트가 GitHub에서 왔는지 GitLab에서 왔는지 신경쓰지 않고 처리하기 가능.
    • 웹훅 이벤트 뿐 아니라 GitHub/GitLab에 요청을 보낼 때도 공통 struct로 구성해 interface로 요청.
    • 실제 HTTP 리퀘스트는 GitHub/GitLab-specific한 structs로 변환, marshal돼 날아감
  • Controllers (/controllers)
    • IntegrationConfig Controller
      • IntegrationConfig 생성 시 깃 레포지토리에 웹훅 자동으로 등록. 삭제할 땐 웹훅도 삭제. 끝!
    • IntegrationJob Controller
      • IntegrationJob 상태가 바뀔 때 (생성/PipelineRun 상태 변경 등등) Scheduler로 알려서 Scheduler 내부의 JobPool 싱크 맞춤
      • PipelineManager 불러서 PipelineRun의 상태를 IntegrationJob의 상태에 반영함
    • Approval Controller
      • 생성 시 메일 전송, 사용자가 승인/거절했을 경우에도 메일 전송 (ConfigMap의 Template대로 보내줌)
      • 요청받은 유저에게 해당 Approval에 대한 approve/reject 권한 부여
    • CustomRun Controller
      : Tekton Custom Task로 만들어지는 Run 오브젝트 Controller들
      : Pipeline 구성할 때 taskRef에 apiVersion: cicd.tmax.io/v1, kind: [ApprovalTask|EmailTask|SlackTask]로 명시하면 해당 Task는 TaskRun&Pod로 생성되지 않고 Run 오브젝트가 생성돼 각 커스텀 런 컨트롤러의 제어를 받음
      • ApprovalRun Controller
        • Approval CR 만들어줌
        • Approval의 상태를 Run 상태에 반영 (Approval이 approved 상태면 Run은 Succeeded. Approval이 rejected 상태면 Run은 Failed)
      • EmailRun Controller
        • 이메일을 보내줌
        • 보내는거 성공하면 Succeeded, 실패하면 Failed
      • SlackRun Controller
        • Slack 메세지를 보내줌
        • 보내는거 성공하면 Succeeded, 실패하면 Failed
    • ConfigMap Controller
      • cicd-config 컨피그맵과 email-template 컨피그맵에 변동 발생 시 내부 (/internal/configs) 전역 변수에 반영
      • cicd-config 변동 발생 시 Collector로 signal 보내 GC 주기 수정 (cronjob (k8s cronjob 아니고 go의 cronjob) 삭제/재등록)
    • Ingress Controller
      • Webhook/Report 서버를 위한 Ingress를 자동으로 수정해줌
      • ingress class 자동으로 달아주고
      • IP 할당 되면 호스트 이름 자동으로 수정해줌
  • Dispatcher (/pkg/dispatcher)
    • 웹훅 이벤트 (pull_request / push) -> IntegrationJob 생성 역할
  • Chat-ops (/pkg/chatops)
    • 웹훅 이벤트 (comment) -> IntegrationJob 생성 역할
  • Scheduler (/pkg/scheduler)
    • IntegrationJob -> PipelineRun 생성 역할
  • Pipeline Manager (/pkg/pipelinemanager)
    • PipelineRun Spec 작성
    • PipelineRun Status -> IntegrationJob Status 반영 역할
  • Collector (/pkg/collector)
    • Garbage Collector
    • 설정 파라미터가 gcPeriod, TTL이 있음. gcPeriod마다 collector 돌고 TTL 넘는 IntegrationJob 삭제
  • Api Server (/pkg/apiserver)
    • Approval approve/reject 요청에 대한 요청 처리
  • Server (/pkg/server)
    • Webhook/Report 서버 핸들러 존재
  • Events (/pkg/events)
    • IntegrationJob 상태 변화 시 발생되는 이벤트 발생기
  • Notification (/pkg/notification)
    • Email/Slack 전송 클라이언트
  • Structs (/pkg/structs)
    • Scheduler에서 쓰이는 Queue 정의
    • ChatOps 시 dependant job 구하는 Graph 정의

Clone this wiki locally