파이프라인 아키텍처
파이프라인 아키텍처 (Pipeline architecture)
파이프라인은 GitLab에서 CI/CD의 기본 구성 요소예요. 이와 관련된 몇 가지 중요한 개념을 살펴볼게요.
파이프라인은 각각 고유한 장점이 있는 여러 방법으로 구조화할 수 있어요. 필요하다면 이 방법들을 혼합해서 사용할 수도 있어요.
- 기본(Basic) 파이프라인: 모든 구성이 한 곳에 있는 간단한 프로젝트에 좋아요.
needs키워드가 있는 파이프라인: 효율적인 실행이 필요한 크고 복잡한 프로젝트에 좋아요.- 부모-자식 파이프라인: 모노레포와 독립적으로 정의된 컴포넌트가 많은 프로젝트에 좋아요. 개요는 부모-자식 파이프라인 기능 데모를 참고해요.
- 멀티 프로젝트 파이프라인: 마이크로서비스 아키텍처처럼 크로스 프로젝트 상호 의존성이 필요한 대형 제품에 좋아요.
예를 들어 웹 애플리케이션을 세 개의 다른 GitLab 프로젝트에서 배포한다고 가정해 볼게요. 멀티 프로젝트 파이프라인으로 각 프로젝트에서 파이프라인을 트리거할 수 있고, 각각 자체 빌드, 테스트, 배포 프로세스를 가져요. 모든 크로스 프로젝트 상호 의존성을 포함해 연결된 파이프라인을 한 곳에서 시각화할 수 있어요.
개요는 멀티 프로젝트 파이프라인 데모를 참고해요.
출처: 문서
본문
기본 파이프라인
기본 파이프라인은 GitLab에서 가장 단순한 파이프라인이에요. 빌드 스테이지의 모든 것을 동시에 실행하고, 그 모두가 끝나면 테스트 및 이후 스테이지의 모든 것을 같은 방식으로 실행해요. 가장 효율적이지는 않고, 스텝이 많으면 복잡해질 수 있지만 유지보수하기는 쉬워요.
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph LR
accTitle: Basic pipelines
accDescr: Shows a pipeline that runs sequentially through the build, test, and deploy stages.
subgraph deploy stage
deploy --> deploy_a
deploy --> deploy_b
end
subgraph test stage
test --> test_a
test --> test_b
end
subgraph build stage
build --> build_a
build --> build_b
end
build_a -.-> test
build_b -.-> test
test_a -.-> deploy
test_b -.-> deploy
다이어그램과 일치하는 기본 /.gitlab-ci.yml 파이프라인 구성 예시:
stages:
- build
- test
- deploy
default:
image: alpine
build_a:
stage: build
script:
- echo "This job builds something."
build_b:
stage: build
script:
- echo "This job builds something else."
test_a:
stage: test
script:
- echo "This job tests something. It will only run when all jobs in the"
- echo "build stage are complete."
test_b:
stage: test
script:
- echo "This job tests something else. It will only run when all jobs in the"
- echo "build stage are complete too. It will start at about the same time as test_a."
deploy_a:
stage: deploy
script:
- echo "This job deploys something. It will only run when all jobs in the"
- echo "test stage complete."
environment: production
deploy_b:
stage: deploy
script:
- echo "This job deploys something else. It will only run when all jobs in the"
- echo "test stage complete. It will start at about the same time as deploy_a."
environment: production
needs 키워드가 있는 파이프라인
효율이 중요하고 모든 것을 최대한 빨리 실행하고 싶다면 [needs 키워드](/ci/yaml/needs/)로 잡 사이의 의존성을 정의할 수 있어요. GitLab이 잡 사이의 의존성을 알면, 같은 스테이지의 다른 잡보다 일찍 시작할 수도 있을 만큼 잡을 최대한 빨리 실행할 수 있어요.
다음 예시에서 build_a와 test_a가 build_b와 test_b보다 훨씬 빠르다면, build_b가 아직 실행 중이어도 GitLab이 deploy_a를 시작해요.
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph LR
accTitle: Pipeline using needs
accDescr: Shows how two jobs can start without waiting for earlier stages to complete
subgraph Pipeline using needs
build_a --> test_a --> deploy_a
build_b --> test_b --> deploy_b
end
다이어그램과 일치하는 /.gitlab-ci.yml 구성 예시:
stages:
- build
- test
- deploy
default:
image: alpine
build_a:
stage: build
script:
- echo "This job builds something quickly."
build_b:
stage: build
script:
- echo "This job builds something else slowly."
test_a:
stage: test
needs: [build_a]
script:
- echo "This test job will start as soon as build_a finishes."
- echo "It will not wait for build_b, or other jobs in the build stage, to finish."
test_b:
stage: test
needs: [build_b]
script:
- echo "This test job will start as soon as build_b finishes."
- echo "It will not wait for other jobs in the build stage to finish."
deploy_a:
stage: deploy
needs: [test_a]
script:
- echo "Since build_a and test_a run quickly, this deploy job can run much earlier."
- echo "It does not need to wait for build_b or test_b."
environment: production
deploy_b:
stage: deploy
needs: [test_b]
script:
- echo "Since build_b and test_b run slowly, this deploy job will run much later."
environment: production
부모-자식 파이프라인
파이프라인이 더 복잡해지면 몇 가지 관련 문제가 생기기 시작해요.
- 스테이지의 모든 스텝이 끝나야 다음 스테이지의 첫 잡이 시작되는 단계 구조 때문에, 느려지는 대기가 발생해요.
- 단일 전역 파이프라인의 구성 관리가 어려워져요.
[include](/ci/yaml/#include)로 가져오는 구성이 구성의 복잡성을 높이고, 잡이 의도치 않게 중복되는 네임스페이스 충돌을 일으킬 수 있어요.- 파이프라인 UX에 다루기 힘들 정도로 많은 잡과 스테이지가 있어요.
또한 때로는 파이프라인의 동작이 더 역동적이어야 할 필요가 있어요. 하위 파이프라인을 시작할지 선택할 수 있는데, 특히 YAML이 동적으로 생성되는 경우에 유용해요.
앞의 기본 파이프라인과 needs 파이프라인 예시에는 독립적으로 빌드할 수 있는 두 개의 패키지가 있어요. 이런 경우는 부모-자식 파이프라인을 사용하기에 이상적이에요. 구성이 여러 파일로 나뉘어 더 단순해져요. 부모-자식 파이프라인은 다음과 결합할 수 있어요.
[rules 키워드](/ci/yaml/#rules): 예를 들어 해당 영역에 변경이 있을 때만 자식 파이프라인을 트리거.[include 키워드](/ci/yaml/#include): 공통 동작을 가져와서 중복을 피함.- 자식 파이프라인 안의
[needs 키워드](/ci/pipelines/pipeline_architectures/#pipelines-with-the-needs-keyword): 두 가지의 이점을 모두 얻기.
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph LR
accTitle: Parent and child pipelines
accDescr: Shows that a parent pipeline can trigger independent child pipelines
subgraph Parent pipeline
trigger_a -.-> build_a
trigger_b -.-> build_b
subgraph child pipeline B
build_b --> test_b --> deploy_b
end
subgraph child pipeline A
build_a --> test_a --> deploy_a
end
end
다이어그램과 일치하는 부모 파이프라인의 /.gitlab-ci.yml 구성 예시:
stages:
- triggers
trigger_a:
stage: triggers
trigger:
include: a/.gitlab-ci.yml
rules:
- changes:
- a/*
trigger_b:
stage: triggers
trigger:
include: b/.gitlab-ci.yml
rules:
- changes:
- b/*
/a/.gitlab-ci.yml에 있는 자식 a 파이프라인 구성 예시. needs 키워드를 사용해요.
stages:
- build
- test
- deploy
default:
image: alpine
build_a:
stage: build
script:
- echo "This job builds something."
test_a:
stage: test
needs: [build_a]
script:
- echo "This job tests something."
deploy_a:
stage: deploy
needs: [test_a]
script:
- echo "This job deploys something."
environment: production
/b/.gitlab-ci.yml에 있는 자식 b 파이프라인 구성 예시. needs 키워드를 사용해요.
stages:
- build
- test
- deploy
default:
image: alpine
build_b:
stage: build
script:
- echo "This job builds something else."
test_b:
stage: test
needs: [build_b]
script:
- echo "This job tests something else."
deploy_b:
stage: deploy
needs: [test_b]
script:
- echo "This job deploys something else."
environment: production
잡은 GitLab에서 자식 파이프라인을 트리거하기 전이나 후에 실행되도록 설정할 수 있어서, 공통 설정 단계나 통합 배포를 가능하게 해요.
더 알아보기
파이프라인 구성 방법을 직접 비교하고 싶다면 하위 파이프라인 문서에서 멀티 프로젝트·부모-자식 파이프라인을 더 자세히 볼 수 있어요. 파이프라인 자체의 기본 개념은 CI/CD 파이프라인 문서에서, 성능 최적화는 파이프라인 효율성 문서를 함께 읽어보는 걸 추천해요.